diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 25c9ef8daa6594..c4f48058b70416 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -402,6 +402,7 @@ DevKitM devtype df dfe +DFILE dfu DgDxsfHx dhclient @@ -649,6 +650,7 @@ href HSM hsm HTTPS +Humidistat HW hwadr HydrogenConcentrationMeasurement @@ -1354,6 +1356,7 @@ SVR SWD SWU symlinks +sysbuild sysconfdir SysConfig sysctl diff --git a/.github/workflows/darwin-tests.yaml b/.github/workflows/darwin-tests.yaml index a916250572bb6e..815293204b09de 100644 --- a/.github/workflows/darwin-tests.yaml +++ b/.github/workflows/darwin-tests.yaml @@ -95,6 +95,7 @@ jobs: --target darwin-x64-lit-icd-${BUILD_VARIANT} \ --target darwin-x64-microwave-oven-${BUILD_VARIANT} \ --target darwin-x64-rvc-${BUILD_VARIANT} \ + --target darwin-x64-network-manager-${BUILD_VARIANT} \ build \ --copy-artifacts-to objdir-clone \ " @@ -116,6 +117,7 @@ jobs: --bridge-app ./out/darwin-x64-bridge-${BUILD_VARIANT}/chip-bridge-app \ --microwave-oven-app ./out/darwin-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ --rvc-app ./out/darwin-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ + --network-manager-app ./out/darwin-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \ " - name: Run OTA Test run: | diff --git a/.github/workflows/examples-linux-tv-casting-app.yaml b/.github/workflows/examples-linux-tv-casting-app.yaml index 08005687062a49..4ab6bbbb1cf233 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -71,13 +71,16 @@ jobs: "python3 ./scripts/tests/run_tv_casting_test.py" timeout-minutes: 2 # Comment this out to debug if GitHub Action times out. - - name: - Test casting from Linux tv-casting-app to Linux tv-app - - Commissioner Generated Passcode - run: | - ./scripts/run_in_build_env.sh \ - "python3 ./scripts/tests/run_tv_casting_test.py --commissioner-generated-passcode=True" - timeout-minutes: 2 # Comment this out to debug if GitHub Action times out. + # TODO: this test is flaky and was disabled + # https://github.com/project-chip/connectedhomeip/issues/34598 + # + # - name: + # Test casting from Linux tv-casting-app to Linux tv-app - + # Commissioner Generated Passcode + # run: | + # ./scripts/run_in_build_env.sh \ + # "python3 ./scripts/tests/run_tv_casting_test.py --commissioner-generated-passcode=True" + # timeout-minutes: 2 # Comment this out to debug if GitHub Action times out. - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d6ff5d341cd070..8284b5a9abd284 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -186,6 +186,7 @@ jobs: src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/timer-cluster.xml \ @@ -223,6 +224,7 @@ jobs: --target linux-x64-lit-icd-${BUILD_VARIANT} \ --target linux-x64-microwave-oven-${BUILD_VARIANT} \ --target linux-x64-rvc-${BUILD_VARIANT} \ + --target linux-x64-network-manager-${BUILD_VARIANT} \ build \ --copy-artifacts-to objdir-clone \ " @@ -245,6 +247,7 @@ jobs: --lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \ --microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ --rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ + --network-manager-app ./out/linux-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \ " - name: Run purposeful failure tests using the python parser sending commands to chip-tool @@ -286,6 +289,7 @@ jobs: --lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \ --microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ --rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ + --network-manager-app ./out/linux-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \ " - name: Run Tests using chip-repl (including slow) if: github.event_name == 'push' @@ -305,6 +309,7 @@ jobs: --lit-icd-app ./out/linux-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \ --microwave-oven-app ./out/linux-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ --rvc-app ./out/linux-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ + --network-manager-app ./out/linux-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \ " - name: Uploading core files uses: actions/upload-artifact@v4 @@ -373,6 +378,7 @@ jobs: --target darwin-x64-lit-icd-${BUILD_VARIANT} \ --target darwin-x64-microwave-oven-${BUILD_VARIANT} \ --target darwin-x64-rvc-${BUILD_VARIANT} \ + --target darwin-x64-network-manager-${BUILD_VARIANT} \ build \ --copy-artifacts-to objdir-clone \ " @@ -396,6 +402,7 @@ jobs: --lit-icd-app ./out/darwin-x64-lit-icd-${BUILD_VARIANT}/lit-icd-app \ --microwave-oven-app ./out/darwin-x64-microwave-oven-${BUILD_VARIANT}/chip-microwave-oven-app \ --rvc-app ./out/darwin-x64-rvc-${BUILD_VARIANT}/chip-rvc-app \ + --network-manager-app ./out/darwin-x64-network-manager-${BUILD_VARIANT}/matter-network-manager-app \ " - name: Run purposeful failure tests using the python parser sending commands to chip-tool @@ -502,6 +509,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_ACE_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_ACE_1_5.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_AccessChecker.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_CC_2_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_CC_10_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_CGEN_2_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_CNET_1_4.py' @@ -591,6 +599,10 @@ 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_RVCOPSTATE_2_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_SC_7_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_SWTCH.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_WHM_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_WHM_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_LVL_2_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/TCP_Tests.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --script "src/python_testing/TestConformanceSupport.py" --script-args "--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 --script "src/python_testing/TestMatterTestingSupport.py" --script-args "--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 --script "src/python_testing/TestSpecParsingSupport.py" --script-args "--trace-to json:out/trace_data/test-{SCRIPT_BASE_NAME}.json --trace-to perfetto:out/trace_data/test-{SCRIPT_BASE_NAME}.perfetto"' diff --git a/BUILD.gn b/BUILD.gn index 4d76100fbe6d20..82c8d855bfd291 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -57,6 +57,8 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { "${chip_root}/src/lib/core/tests:fuzz-tlv-reader", "${chip_root}/src/lib/dnssd/minimal_mdns/tests:fuzz-minmdns-packet-parsing", "${chip_root}/src/lib/format/tests:fuzz-payload-decoder", + "${chip_root}/src/setup_payload/tests:fuzz-setup-payload-base38", + "${chip_root}/src/setup_payload/tests:fuzz-setup-payload-base38-decode", ] } } diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 1e634152a61d49..93333078f6f477 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/pigweed.gni") +import("//build_overrides/pigweed_environment.gni") import("${build_root}/chip/java/config.gni") import("${build_root}/config/compiler/compiler.gni") import("${build_root}/config/sysroot.gni") @@ -348,7 +349,14 @@ config("cosmetic_default") { } config("runtime_default") { - if (is_clang) { # Using Pigweed clang instead of Darwin host clang + if (is_clang && + current_os == "mac") { # Using Pigweed clang instead of Darwin host clang + # Without pw_env_setup_CIPD_PIGWEED defined the hostclang:no_system_libcpp + # config silently uses the system libc++, usually resulting in linker errors. + assert( + defined(pw_env_setup_CIPD_PIGWEED), + "//build_overrides/pigweed_environment.gni must define pw_env_setup_CIPD_PIGWEED when using pigweed clang") + configs = [ "$dir_pw_toolchain/host_clang:no_system_libcpp", "$dir_pw_toolchain/host_clang:xcode_sysroot", diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index 6ddfc4839123ff..7929e8bbbd14aa 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -237,6 +237,12 @@ else() chip_gn_arg_append("chip_openthread_ftd" "false") endif() +if (CONFIG_OPENTHREAD_BORDER_ROUTER) + chip_gn_arg_append("chip_openthread_border_router" "true") +else() + chip_gn_arg_append("chip_openthread_border_router" "false") +endif() + if (CONFIG_ENABLE_OTA_REQUESTOR) chip_gn_arg_append("chip_enable_ota_requestor" "true") endif() @@ -466,7 +472,11 @@ if (CONFIG_ENABLE_ENCRYPTED_OTA) list(APPEND chip_libraries $) endif() -idf_component_get_property(main_lib main COMPONENT_LIB) +# Let user set EXECUTABLE_COMPONENT_NAME and defaults to main if not specified +if (NOT EXECUTABLE_COMPONENT_NAME) + set(EXECUTABLE_COMPONENT_NAME "main") +endif() +idf_component_get_property(main_lib ${EXECUTABLE_COMPONENT_NAME} COMPONENT_LIB) list(APPEND chip_libraries $) if (CONFIG_SEC_CERT_DAC_PROVIDER) diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index bccd16b1416160..20c5c692b68633 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -200,7 +200,6 @@ matter_generate_args_tmp_file() # ============================================================================== matter_build(chip - LIB_SHELL ${CONFIG_CHIP_LIB_SHELL} LIB_TESTS ${CONFIG_CHIP_BUILD_TESTS} DEVICE_INFO_EXAMPLE_PROVIDER ${CONFIG_CHIP_EXAMPLE_DEVICE_INFO_PROVIDER} GN_DEPENDENCIES kernel @@ -225,6 +224,16 @@ if (CONFIG_CHIP_MALLOC_SYS_HEAP_OVERRIDE) ) endif() +if (CONFIG_CHIP_LIB_SHELL) + # Force pulling chip::Shell::Engine::RunMainLoop() in the final binary. + # Without this workaround, the linker script does not process the shell and + # init objects defined in MainLoopZephyr.cpp unless the Matter library or + # the Matter shell library is linked using the '--whole-archive' flag. + target_link_options(chip INTERFACE + -Wl,-u,_ZN4chip5Shell6Engine11RunMainLoopEv + ) +endif() + # ============================================================================== # Define 'chip-ota-image' target for building CHIP OTA image # ============================================================================== diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index ea5a6822b74cb5..9c27fe1059451f 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -286,10 +286,10 @@ config NET_IPV6_NBR_CACHE default n config NET_MAX_CONN - default 1 + default 1 if !WIFI config NET_MAX_CONTEXTS - default 1 + default 1 if !WIFI config NET_CONFIG_INIT_TIMEOUT default 0 diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_70mai_Matter_PAA_vid_0x140B.der b/credentials/development/paa-root-certs/dcld_mirror_CN_70mai_Matter_PAA_vid_0x140B.der new file mode 100644 index 00000000000000..eb604af4036b25 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_70mai_Matter_PAA_vid_0x140B.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_70mai_Matter_PAA_vid_0x140B.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_70mai_Matter_PAA_vid_0x140B.pem new file mode 100644 index 00000000000000..64725b6729e88f --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_70mai_Matter_PAA_vid_0x140B.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBxjCCAWygAwIBAgIRANBskmmy8YAEmHofOp/xYmcwCgYIKoZIzj0EAwIwMTEZ +MBcGA1UEAwwQNzBtYWkgTWF0dGVyIFBBQTEUMBIGCisGAQQBgqJ8AgEMBDE0MEIw +IBcNMjMwNzI0MDcwMTMxWhgPMjUyMzAzMjUwODAxMzFaMDExGTAXBgNVBAMMEDcw +bWFpIE1hdHRlciBQQUExFDASBgorBgEEAYKifAIBDAQxNDBCMFkwEwYHKoZIzj0C +AQYIKoZIzj0DAQcDQgAEh7YSUJl3gJtgkIssE/7ZO9pRO5XbfS73b1zF2/Wjbi9r +igxSqAyIMVpObAMsfdin8f8+WwBeG4deexmwq5jzhKNjMGEwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUFFpRtZs7j1lqjNmWQvB1DDSYOG8wDgYDVR0PAQH/BAQD +AgGGMB8GA1UdIwQYMBaAFBRaUbWbO49ZaozZlkLwdQw0mDhvMAoGCCqGSM49BAMC +A0gAMEUCIEACwkh/UMcjnV6noWfg7pjYQt1Z9tB5S32YvDKUQg44AiEAkXj2t5TC +7huhrQmdHeBr3e1+Eci4q068qd2nI4zECM0= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Anker_Innovations_Matter_PAA_vid_0x1533.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Anker_Innovations_Matter_PAA_vid_0x1533.der new file mode 100644 index 00000000000000..1300a90a351e31 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Anker_Innovations_Matter_PAA_vid_0x1533.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Anker_Innovations_Matter_PAA_vid_0x1533.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Anker_Innovations_Matter_PAA_vid_0x1533.pem new file mode 100644 index 00000000000000..19b6468c3f20b5 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Anker_Innovations_Matter_PAA_vid_0x1533.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB0zCCAXqgAwIBAgIEEAAACTAKBggqhkjOPQQDAjA9MRQwEgYKKwYBBAGConwC +AQwEMTUzMzElMCMGA1UEAwwcQW5rZXIgSW5ub3ZhdGlvbnMgTWF0dGVyIFBBQTAg +Fw0yNDA1MTYwOTI2MjhaGA85OTk5MTIzMDA5MjYyOFowPTEUMBIGCisGAQQBgqJ8 +AgEMBDE1MzMxJTAjBgNVBAMMHEFua2VyIElubm92YXRpb25zIE1hdHRlciBQQUEw +WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQGMvtbso2avjK1ARPNTFoXX/3kpKmu +e8i4zfRjCFjs8mxZkOrmbS4IOw3wlWgaL91danRizORhbWilHsdyDiKOo2YwZDAS +BgNVHRMBAf8ECDAGAQH/AgEBMB8GA1UdIwQYMBaAFF0RbnEDG5pPw1S1mMx4V6Su +ULKGMB0GA1UdDgQWBBRdEW5xAxuaT8NUtZjMeFekrlCyhjAOBgNVHQ8BAf8EBAMC +AQYwCgYIKoZIzj0EAwIDRwAwRAIgfLXElnmPFMYwytT/mOOkp7enq1G6a/zpYKQu +oSJ6EUoCIDdhtSd9z6h+/dN4mSly8OIRE2Zo6z9bFpQVZFt6BzBy +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Aqara_Matter_PAA_01_O_Lumi_United_Technology_Co__Ltd.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Aqara_Matter_PAA_01_O_Lumi_United_Technology_Co__Ltd.der new file mode 100644 index 00000000000000..6887a91e999698 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Aqara_Matter_PAA_01_O_Lumi_United_Technology_Co__Ltd.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Aqara_Matter_PAA_01_O_Lumi_United_Technology_Co__Ltd.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Aqara_Matter_PAA_01_O_Lumi_United_Technology_Co__Ltd.pem new file mode 100644 index 00000000000000..1df7012d14a480 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Aqara_Matter_PAA_01_O_Lumi_United_Technology_Co__Ltd.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB9TCCAZygAwIBAgIRAJ4ckIzu1/EXWiYXT/3PzuEwCgYIKoZIzj0EAwIwSTEo +MCYGA1UECgwfTHVtaSBVbml0ZWQgVGVjaG5vbG9neSBDby4sIEx0ZDEdMBsGA1UE +AwwUQXFhcmEgTWF0dGVyIFBBQSAjMDEwIBcNMjMwNjIwMDgxMjM3WhgPOTk5OTEy +MzEyMzU5NTlaMEkxKDAmBgNVBAoMH0x1bWkgVW5pdGVkIFRlY2hub2xvZ3kgQ28u +LCBMdGQxHTAbBgNVBAMMFEFxYXJhIE1hdHRlciBQQUEgIzAxMFkwEwYHKoZIzj0C +AQYIKoZIzj0DAQcDQgAEy3JmW4dkIzN5HbDL3v9Kr3ZY9c9an7DUCwY6CyKRyzxE +QE6z5Yy3TzannQBoomkMbnK9wkCPJJTNnR8NOr9S8qNjMGEwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUmpf77hNiX3/vVXQL+TXxdHHeS3YwDgYDVR0PAQH/BAQD +AgGGMB8GA1UdIwQYMBaAFJqX++4TYl9/71V0C/k18XRx3kt2MAoGCCqGSM49BAMC +A0cAMEQCIEWIzz9hCLfUsSNzuDWrWgI+omq1E9NlP2heP4ugfB2PAiB21Wzrf7m/ +jk0rmvAP1eqJjCwh9uvI34offdV04/bHfA== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_BouffaloLab_Matter_PAA_vid_0x130D.der b/credentials/development/paa-root-certs/dcld_mirror_CN_BouffaloLab_Matter_PAA_vid_0x130D.der new file mode 100644 index 00000000000000..af9aa7f1c2d153 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_BouffaloLab_Matter_PAA_vid_0x130D.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_BouffaloLab_Matter_PAA_vid_0x130D.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_BouffaloLab_Matter_PAA_vid_0x130D.pem new file mode 100644 index 00000000000000..a7553c76ab1361 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_BouffaloLab_Matter_PAA_vid_0x130D.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB0TCCAXegAwIBAgIQaITTalFdhyvSwC28BV1ngjAKBggqhkjOPQQDAjA3MR8w +HQYDVQQDDBZCb3VmZmFsb0xhYiBNYXR0ZXIgUEFBMRQwEgYKKwYBBAGConwCAQwE +MTMwRDAgFw0yMzA2MTkwNDI3MDVaGA8yMTIyMDYxOTA1MjcwNVowNzEfMB0GA1UE +AwwWQm91ZmZhbG9MYWIgTWF0dGVyIFBBQTEUMBIGCisGAQQBgqJ8AgEMBDEzMEQw +WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT9qtlVs5p+5yzS91xz5hmcfXOglIDW +p7fqYE9uFmq2x8IthHxwXF9PXG4LbMlgaq3cL/ijr9kqfSjQ1q+3iaY3o2MwYTAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRltKiB/t9YUSOvkqlSypCPRj116zAO +BgNVHQ8BAf8EBAMCAYYwHwYDVR0jBBgwFoAUZbSogf7fWFEjr5KpUsqQj0Y9desw +CgYIKoZIzj0EAwIDSAAwRQIgOXeXdhQxz1kKq5W+Pt0QDPVfR4OqRvFW4GZ3Kj0K +fFoCIQC7qxHppHx023BdMTCyAXoDDqKQ5z5BFNw1k/Xil2Q8lw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_DSC_Matter_PAA_O_Dream_Security_Co__Ltd_C_KR.der b/credentials/development/paa-root-certs/dcld_mirror_CN_DSC_Matter_PAA_O_Dream_Security_Co__Ltd_C_KR.der new file mode 100644 index 00000000000000..38871931650057 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_DSC_Matter_PAA_O_Dream_Security_Co__Ltd_C_KR.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_DSC_Matter_PAA_O_Dream_Security_Co__Ltd_C_KR.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_DSC_Matter_PAA_O_Dream_Security_Co__Ltd_C_KR.pem new file mode 100644 index 00000000000000..f2d5c366c63bab --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_DSC_Matter_PAA_O_Dream_Security_Co__Ltd_C_KR.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB/DCCAaKgAwIBAgIUAUlzLLkOLfiBQM1Mtdd715RoIpcwCgYIKoZIzj0EAwIw +STELMAkGA1UEBhMCS1IxITAfBgNVBAoMGERyZWFtIFNlY3VyaXR5IENvLiwgTHRk +LjEXMBUGA1UEAwwORFNDIE1hdHRlciBQQUEwIBcNMjMxMDEzMDM0ODUzWhgPOTk5 +OTEyMzExNDU5NTlaMEkxCzAJBgNVBAYTAktSMSEwHwYDVQQKDBhEcmVhbSBTZWN1 +cml0eSBDby4sIEx0ZC4xFzAVBgNVBAMMDkRTQyBNYXR0ZXIgUEFBMFkwEwYHKoZI +zj0CAQYIKoZIzj0DAQcDQgAEwna+mEy1wfCZ0iDK4hoKP4js4HE9XmiRe7pZ1RLp +ahkjnkABlV+R4CixltIwnagyn0HuyhEWRFXhf2Na6nGORqNmMGQwHwYDVR0jBBgw +FoAUSvBR2pNudxvmFRNxKN5AJTNeaY0wHQYDVR0OBBYEFErwUdqTbncb5hUTcSje +QCUzXmmNMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAGAQH/AgEBMAoGCCqG +SM49BAMCA0gAMEUCIBFvRkkx9tuuocwTIBdNWg7or7XqaNp0pNK0BRKfEOkRAiEA +ykq93kYuFbX6lSzl3n0eJJ8Wo3L7b/l1mHtYTdhBQzE= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Ecovacs_Matter_PAA_O_ECOVACS_IOT_vid_0x1405.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Ecovacs_Matter_PAA_O_ECOVACS_IOT_vid_0x1405.der new file mode 100644 index 00000000000000..ecf361dae6cc39 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Ecovacs_Matter_PAA_O_ECOVACS_IOT_vid_0x1405.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Ecovacs_Matter_PAA_O_ECOVACS_IOT_vid_0x1405.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Ecovacs_Matter_PAA_O_ECOVACS_IOT_vid_0x1405.pem new file mode 100644 index 00000000000000..8cef24133c1c0c --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Ecovacs_Matter_PAA_O_ECOVACS_IOT_vid_0x1405.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB1DCCAXqgAwIBAgIQW09Lv9ptt+IhqXXbbGzKTzAKBggqhkjOPQQDAjBJMRsw +GQYDVQQDDBJFY292YWNzIE1hdHRlciBQQUExFDASBgorBgEEAYKifAIBDAQxNDA1 +MRQwEgYDVQQKDAtFQ09WQUNTIElPVDAgFw0yNDAyMjEwNjM0MzlaGA85OTk5MTIz +MTIzNTk1OVowSTEbMBkGA1UEAwwSRWNvdmFjcyBNYXR0ZXIgUEFBMRQwEgYKKwYB +BAGConwCAQwEMTQwNTEUMBIGA1UECgwLRUNPVkFDUyBJT1QwWTATBgcqhkjOPQIB +BggqhkjOPQMBBwNCAAT/Qmenu+SAjEForNL9yxVa9swLcalKRiuZaH/DzH1yLP4X +JCmLbx6G67zSQoQSfpp77LqgutIbSJ8r7+oqANY5o0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBQiJnIKCNppY2KxFpI8tHQtEus6UDAOBgNVHQ8BAf8EBAMC +AYYwCgYIKoZIzj0EAwIDSAAwRQIhAOGDpMmCrjYdlz102PIkf2DHsIg1rdocfPTc +340dgyNxAiA9GmencY7sOJp5KjYmHgppFtuKkY6/k7x1xD0GlCOcyQ== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Energy_Magic_Cube_Matter_PAA_001_vid_0x1462.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Energy_Magic_Cube_Matter_PAA_001_vid_0x1462.der new file mode 100644 index 00000000000000..6438781dc45163 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Energy_Magic_Cube_Matter_PAA_001_vid_0x1462.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Energy_Magic_Cube_Matter_PAA_001_vid_0x1462.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Energy_Magic_Cube_Matter_PAA_001_vid_0x1462.pem new file mode 100644 index 00000000000000..67697392583be6 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Energy_Magic_Cube_Matter_PAA_001_vid_0x1462.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5jCCAYygAwIBAgIRAPlpOvhByCYEtN9DBypV0jQwCgYIKoZIzj0EAwIwQTEp +MCcGA1UEAwwgRW5lcmd5IE1hZ2ljIEN1YmUgTWF0dGVyIFBBQSAwMDExFDASBgor +BgEEAYKifAIBDAQxNDYyMCAXDTIzMDcyNzEzMDA1NloYDzIyOTcwNTEwMTQwMDU2 +WjBBMSkwJwYDVQQDDCBFbmVyZ3kgTWFnaWMgQ3ViZSBNYXR0ZXIgUEFBIDAwMTEU +MBIGCisGAQQBgqJ8AgEMBDE0NjIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARe +uoz+NvT1NIHBc0aNiaHp1Vcw2ysyUq6Pgi61CSJMLQ6seo1WhSVMCYof6NCJNGan +M8YeVOQINZI4h0iXKnwDo2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSu +akG67t30MGPMHc7nzcgTP8ynODAOBgNVHQ8BAf8EBAMCAYYwHwYDVR0jBBgwFoAU +rmpBuu7d9DBjzB3O583IEz/MpzgwCgYIKoZIzj0EAwIDSAAwRQIgXd+gekuzZQlD +nEnpvn16oe8qf83XWNLOBU7kpYvXjjYCIQDhbZRrEq6U7skYoqJn478a+b4EEexA +4790Zm8JHbhRlQ== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Espressif_Matter_Open_PAA_O_Espressif_Systems.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Espressif_Matter_Open_PAA_O_Espressif_Systems.der new file mode 100644 index 00000000000000..7ec9d617be0fc5 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Espressif_Matter_Open_PAA_O_Espressif_Systems.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Espressif_Matter_Open_PAA_O_Espressif_Systems.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Espressif_Matter_Open_PAA_O_Espressif_Systems.pem new file mode 100644 index 00000000000000..459570181a08b3 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Espressif_Matter_Open_PAA_O_Espressif_Systems.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB6DCCAY2gAwIBAgIRANvFEo4HItdgmPRAoZzjBm0wCgYIKoZIzj0EAwIwQDEi +MCAGA1UEAwwZRXNwcmVzc2lmIE1hdHRlciBPcGVuIFBBQTEaMBgGA1UECgwRRXNw +cmVzc2lmIFN5c3RlbXMwIBcNMjQwMTA1MDUxMzI1WhgPOTk5OTEyMzEyMzU5NTla +MEAxIjAgBgNVBAMMGUVzcHJlc3NpZiBNYXR0ZXIgT3BlbiBQQUExGjAYBgNVBAoM +EUVzcHJlc3NpZiBTeXN0ZW1zMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOXAK +KrklPSU2LY/wvSf2GWxEHXqyHPm5cid870KN3R8LSHWshC9kH54QFUmoNHcTviE3 +5DkjJwhNL5OR/ccfq6NmMGQwEgYDVR0TAQH/BAgwBgEB/wIBATAfBgNVHSMEGDAW +gBRmTMGwLTMc15FUbp4UiDMxib1v0DAdBgNVHQ4EFgQUZkzBsC0zHNeRVG6eFIgz +MYm9b9AwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA0kAMEYCIQD+igSgqYgP +rKC7jLCWGQ8NydYpU591po+wJ6Vc6PkWWgIhANPW0FQv9FuBMXP8zp0l8eAW8h6A +4GB6+MmFQeq97qcz +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Feit_Electric_PAA_vid_0x1423.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Feit_Electric_PAA_vid_0x1423.der new file mode 100644 index 00000000000000..94dcffaedae0f6 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Feit_Electric_PAA_vid_0x1423.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Feit_Electric_PAA_vid_0x1423.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Feit_Electric_PAA_vid_0x1423.pem new file mode 100644 index 00000000000000..963d6673897371 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Feit_Electric_PAA_vid_0x1423.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIByzCCAXGgAwIBAgIUe3w51hygpwHd6Tlxj2adk6IF5pswCgYIKoZIzj0EAwIw +MjEaMBgGA1UEAwwRRmVpdCBFbGVjdHJpYyBQQUExFDASBgorBgEEAYKifAIBDAQx +NDIzMCAXDTIzMDcyMTA1MzM1MFoYDzgzMjMwOTA3MDUzMzUwWjAyMRowGAYDVQQD +DBFGZWl0IEVsZWN0cmljIFBBQTEUMBIGCisGAQQBgqJ8AgEMBDE0MjMwWTATBgcq +hkjOPQIBBggqhkjOPQMBBwNCAAQT516150jQlChLACUsk9Y+KWG6i53J9UFXF8hS +QeD91fdRMagNnT9fvq67FaQxw+I8ZJlhr0S6dmWcJ2mg/l+io2MwYTAPBgNVHRMB +Af8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBp6Gv3HbUvnfPOp9 +5CkMn1uZaPEwHwYDVR0jBBgwFoAUBp6Gv3HbUvnfPOp95CkMn1uZaPEwCgYIKoZI +zj0EAwIDSAAwRQIgL85qVK45czuhx53cqICB+NUVZTnyx5n+Yxc1hjZjrt4CIQDQ ++vG34+tSW9Yu870l08ArF9MDmh2slLXKEOlXKXZ4Ew== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Freedompro_vid_0x1411_vid_0x1411.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Freedompro_vid_0x1411_vid_0x1411.der new file mode 100644 index 00000000000000..f05b1fa37a5a0d Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Freedompro_vid_0x1411_vid_0x1411.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Freedompro_vid_0x1411_vid_0x1411.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Freedompro_vid_0x1411_vid_0x1411.pem new file mode 100644 index 00000000000000..40c6b0ce9c2459 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Freedompro_vid_0x1411_vid_0x1411.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIByzCCAXCgAwIBAgIIGBv/c3jnq0YwCgYIKoZIzj0EAwIwNjEeMBwGA1UEAwwV +RnJlZWRvbXBybyx2aWQ9MHgxNDExMRQwEgYKKwYBBAGConwCAQwEMTQxMTAgFw0y +NDAxMDEwMDAwMDBaGA85OTk5MTIzMTIzNTk1OVowNjEeMBwGA1UEAwwVRnJlZWRv +bXBybyx2aWQ9MHgxNDExMRQwEgYKKwYBBAGConwCAQwEMTQxMTBZMBMGByqGSM49 +AgEGCCqGSM49AwEHA0IABJZ76CU2fZUWA7xdv+qJmsHWVH8BhZGeaph0IdSGYhc2 +EHuKTqnwHt/RdfJFwx23BLAWAkCIZajILqxSo8CCqKSjZjBkMBIGA1UdEwEB/wQI +MAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQ8wKeoW2LBxfThfQZH +KREr2wkGwzAfBgNVHSMEGDAWgBQ8wKeoW2LBxfThfQZHKREr2wkGwzAKBggqhkjO +PQQDAgNJADBGAiEA3RyF7r8Us70mn2qUBWuSqLZqHxfc5Vf+ojENI7jaGOoCIQDd +RFsNUBD5e8rGbBENvySrN9JpRu4s8T6xiqB0bJUwbA== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_HOPERF_Matter_PAA_01_vid_0x1470.der b/credentials/development/paa-root-certs/dcld_mirror_CN_HOPERF_Matter_PAA_01_vid_0x1470.der new file mode 100644 index 00000000000000..db85defaeed865 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_HOPERF_Matter_PAA_01_vid_0x1470.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_HOPERF_Matter_PAA_01_vid_0x1470.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_HOPERF_Matter_PAA_01_vid_0x1470.pem new file mode 100644 index 00000000000000..85255162c07d1b --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_HOPERF_Matter_PAA_01_vid_0x1470.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBzjCCAXSgAwIBAgIRAMB+YpaZQeu05JIuF/AMsiYwCgYIKoZIzj0EAwIwNTEd +MBsGA1UEAwwUSE9QRVJGIE1hdHRlciBQQUEgMDExFDASBgorBgEEAYKifAIBDAQx +NDcwMCAXDTIzMDgyNTA1Mjk1N1oYDzIyMjMwNzA4MDYyOTU3WjA1MR0wGwYDVQQD +DBRIT1BFUkYgTWF0dGVyIFBBQSAwMTEUMBIGCisGAQQBgqJ8AgEMBDE0NzAwWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAATVxJPVN3fr7vg9sOX24AO3WyMLWN/O9u5Z +pjjquJNYiPXVziNj1Yq7o1fFT+JJ/V8gEkq3az3CMfTgr5A3DhHko2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTpFg3EF/dBnJUyC782VnGTP/MSIjAOBgNV +HQ8BAf8EBAMCAYYwHwYDVR0jBBgwFoAU6RYNxBf3QZyVMgu/NlZxkz/zEiIwCgYI +KoZIzj0EAwIDSAAwRQIhAMghj3vry4WnuZhyPK8ZGqyFG2aNdKkJCqwy/4SkcHT7 +AiBxxCLcAC5bDcze/6tJcCuLX5vWaVQYw6IVwBwciEo+rw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_HuaCheng_vid_0x1517.der b/credentials/development/paa-root-certs/dcld_mirror_CN_HuaCheng_vid_0x1517.der new file mode 100644 index 00000000000000..70f88707babe26 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_HuaCheng_vid_0x1517.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_HuaCheng_vid_0x1517.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_HuaCheng_vid_0x1517.pem new file mode 100644 index 00000000000000..46c19d08a6ebaf --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_HuaCheng_vid_0x1517.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBtDCCAVugAwIBAgIQMTnvQ8Ysuuff3Cmdn0VyATAKBggqhkjOPQQDAjApMREw +DwYDVQQDDAhIdWFDaGVuZzEUMBIGCisGAQQBgqJ8AgEMBDE1MTcwIBcNMjQwNjA1 +MDcyMTEwWhgPMjA1NDA1MjkwODIxMTBaMCkxETAPBgNVBAMMCEh1YUNoZW5nMRQw +EgYKKwYBBAGConwCAQwEMTUxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABO6k +hF5Vx6fsRTeVPGUif/NVZ5oehv2GaTvLCubOPs5JmoTkFold5kbDRIYHQ9CjKZRR +HnvMX7bnXfceXrgg8vyjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJbG +HZztCtKeBCkmjjgkc8j432nNMA4GA1UdDwEB/wQEAwIBhjAfBgNVHSMEGDAWgBSW +xh2c7QrSngQpJo44JHPI+N9pzTAKBggqhkjOPQQDAgNHADBEAiBzn5SFeh8DbTI8 +73sMeGFpwfgGOyBnhPxHQW/U6al/3QIgJqYZB8V0Kp+IpFP6BGrrqeqXBCvEOsdh +r83FJwSB0E0= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_IKEA_of_Sweden_Matter_PAA_G1_vid_0x117C.der b/credentials/development/paa-root-certs/dcld_mirror_CN_IKEA_of_Sweden_Matter_PAA_G1_vid_0x117C.der new file mode 100644 index 00000000000000..acfdd885ebfe9f Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_IKEA_of_Sweden_Matter_PAA_G1_vid_0x117C.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_IKEA_of_Sweden_Matter_PAA_G1_vid_0x117C.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_IKEA_of_Sweden_Matter_PAA_G1_vid_0x117C.pem new file mode 100644 index 00000000000000..d275a9a64f8ec0 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_IKEA_of_Sweden_Matter_PAA_G1_vid_0x117C.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4zCCAYqgAwIBAgIUPqEhcfoGwW/yt/qRsBs+jf7MklswCgYIKoZIzj0EAwIw +PTElMCMGA1UEAwwcSUtFQSBvZiBTd2VkZW4gTWF0dGVyIFBBQSBHMTEUMBIGCisG +AQQBgqJ8AgEMBDExN0MwIBcNMjQwMjE0MTQ1ODMzWhgPMjA5OTAxMjYxNDU4MzJa +MD0xJTAjBgNVBAMMHElLRUEgb2YgU3dlZGVuIE1hdHRlciBQQUEgRzExFDASBgor +BgEEAYKifAIBDAQxMTdDMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6/PMOZHP +VJqqJbBLzK6Q5+9kjTEnjCnJ6Ba9+/3kCQPRZmiZnXYHB0Z0cUYmenTFXPlGfUCp +blSOtmL48AtPF6NmMGQwEgYDVR0TAQH/BAgwBgEB/wIBATAfBgNVHSMEGDAWgBRr +MYz86Zkg1zKPX0NtXqMyuLddmjAdBgNVHQ4EFgQUazGM/OmZINcyj19DbV6jMri3 +XZowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA0cAMEQCIETlgc4Us5SE7gPJ +TY9W4D9Fh27DGjtosGP/l99EWrmYAiAXFqbpGtFV1FAx2GxDNa5zYssd4ZpLoewg +rJdUrJOP/g== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Nexus_Matter_PAA_G1_O_Technology_Nexus_SBS_AB_C_SE.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Nexus_Matter_PAA_G1_O_Technology_Nexus_SBS_AB_C_SE.der new file mode 100644 index 00000000000000..cae1616ad4858b Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Nexus_Matter_PAA_G1_O_Technology_Nexus_SBS_AB_C_SE.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Nexus_Matter_PAA_G1_O_Technology_Nexus_SBS_AB_C_SE.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Nexus_Matter_PAA_G1_O_Technology_Nexus_SBS_AB_C_SE.pem new file mode 100644 index 00000000000000..aba32c22d0e4a9 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Nexus_Matter_PAA_G1_O_Technology_Nexus_SBS_AB_C_SE.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIICATCCAaagAwIBAgIQQbk6g1NwvzyrSGCoTI9JgDAKBggqhkjOPQQDAjBNMQsw +CQYDVQQGEwJTRTEgMB4GA1UEChMXVGVjaG5vbG9neSBOZXh1cyBTQlMgQUIxHDAa +BgNVBAMTE05leHVzIE1hdHRlciBQQUEgRzEwIBcNMjMxMjA2MDkxODUyWhgPOTk5 +OTEyMzEyMzU5NTlaME0xCzAJBgNVBAYTAlNFMSAwHgYDVQQKExdUZWNobm9sb2d5 +IE5leHVzIFNCUyBBQjEcMBoGA1UEAxMTTmV4dXMgTWF0dGVyIFBBQSBHMTBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABBvboumawHfPKRmcmdS+qMiSiSb2JdGnbcge +qGGDIfs+iwLVIy3mX8LQNNUftI8MGcfr+wlxZBcbsDeIfRr6oUCjZjBkMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFKjZp1YgGMB2xrt8vfZ3dEZB3ranMB8G +A1UdIwQYMBaAFKjZp1YgGMB2xrt8vfZ3dEZB3ranMA4GA1UdDwEB/wQEAwIBBjAK +BggqhkjOPQQDAgNJADBGAiEA58S/WXdqoF5E23LJ4B00fZNEZY1NumThNsDV18Td +YCkCIQC8Rt3z9E1Gb6aa6/l6tYCTHjuJSTLXU1fU06tYgXuFVw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Quectel_Matter_CA_PAA_vid_0x1410.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Quectel_Matter_CA_PAA_vid_0x1410.der new file mode 100644 index 00000000000000..c328fa914b5514 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Quectel_Matter_CA_PAA_vid_0x1410.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Quectel_Matter_CA_PAA_vid_0x1410.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Quectel_Matter_CA_PAA_vid_0x1410.pem new file mode 100644 index 00000000000000..9d55c08f1fa355 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Quectel_Matter_CA_PAA_vid_0x1410.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB0DCCAXagAwIBAgIRAIEvACmo2CmWcJt7n1iIlgUwCgYIKoZIzj0EAwIwNjEe +MBwGA1UEAwwVUXVlY3RlbCBNYXR0ZXIgQ0EgUEFBMRQwEgYKKwYBBAGConwCAQwE +MTQxMDAgFw0yMzA3MDMwMjQyMDlaGA85OTk5MDcwMzAzNDIwOVowNjEeMBwGA1UE +AwwVUXVlY3RlbCBNYXR0ZXIgQ0EgUEFBMRQwEgYKKwYBBAGConwCAQwEMTQxMDBZ +MBMGByqGSM49AgEGCCqGSM49AwEHA0IABHbK+6EZuOMXSfvxUMciJk195OMMkqqo +ni2yuhqViOOoUbIrYORv3KUOEGEQXv90jBNztsY6GqITxulM0rQnzr6jYzBhMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFACMIPa55crFKDvbu/C8KWu4f4BTMA4G +A1UdDwEB/wQEAwIBhjAfBgNVHSMEGDAWgBQAjCD2ueXKxSg727vwvClruH+AUzAK +BggqhkjOPQQDAgNIADBFAiEAi5IdUgcMX656APT93NrxihH6nHtC4Xq6xm1ok5Jb +sI0CIF/e32TmBhYfaJGuy3aTt3uf64/u7dwrtyJJdinAAAvT +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Safemo_Matter_PAA_vid_0x1506.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Safemo_Matter_PAA_vid_0x1506.der new file mode 100644 index 00000000000000..aa0fee19220bf6 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Safemo_Matter_PAA_vid_0x1506.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Safemo_Matter_PAA_vid_0x1506.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Safemo_Matter_PAA_vid_0x1506.pem new file mode 100644 index 00000000000000..74cf5e689e0856 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Safemo_Matter_PAA_vid_0x1506.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIByDCCAW6gAwIBAgIRAJbGQ0wgEtKWe2yXGITJcggwCgYIKoZIzj0EAwIwMjEa +MBgGA1UEAwwRU2FmZW1vIE1hdHRlciBQQUExFDASBgorBgEEAYKifAIBDAQxNTA2 +MCAXDTIzMTIxOTAyNTExNVoYDzk5OTkxMjMxMjM1OTU5WjAyMRowGAYDVQQDDBFT +YWZlbW8gTWF0dGVyIFBBQTEUMBIGCisGAQQBgqJ8AgEMBDE1MDYwWTATBgcqhkjO +PQIBBggqhkjOPQMBBwNCAASnyGSMLdXvtFpLCf3ER4b2cWnzsDIuGDqV5qdOqwHV +MMgOOMf3CIIG1eIapDIIynEGH814Kgo2MwmACe3Sl7mJo2MwYTAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBQrACL5tHEfXSTZbQ8Dc6oJDqXbkzAOBgNVHQ8BAf8E +BAMCAYYwHwYDVR0jBBgwFoAUKwAi+bRxH10k2W0PA3OqCQ6l25MwCgYIKoZIzj0E +AwIDSAAwRQIhAO4k9enw9QkBsaNJiqaYsq4GOXCNY5KwEHsijJ/R72dtAiAqLfFC +QLytRarca/d8H1ebYil3mTULKIw+T9SdF2DTtQ== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Schneider_Electric_Matter_PAA_01_vid_0x105E.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Schneider_Electric_Matter_PAA_01_vid_0x105E.der new file mode 100644 index 00000000000000..a4fb97ac768bd0 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Schneider_Electric_Matter_PAA_01_vid_0x105E.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Schneider_Electric_Matter_PAA_01_vid_0x105E.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Schneider_Electric_Matter_PAA_01_vid_0x105E.pem new file mode 100644 index 00000000000000..0ff7d45e7e6b66 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Schneider_Electric_Matter_PAA_01_vid_0x105E.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB6jCCAY+gAwIBAgIUTLcD1z2L5rjjLDgXGe9eaRjDJbIwCgYIKoZIzj0EAwIw +QTEpMCcGA1UEAwwgU2NobmVpZGVyIEVsZWN0cmljIE1hdHRlciBQQUEgMDExFDAS +BgorBgEEAYKifAIBDAQxMDVFMCAXDTIzMDUzMDA4NTkzNVoYDzk5OTkxMjMxMjM1 +OTU5WjBBMSkwJwYDVQQDDCBTY2huZWlkZXIgRWxlY3RyaWMgTWF0dGVyIFBBQSAw +MTEUMBIGCisGAQQBgqJ8AgEMBDEwNUUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC +AASeiLYu4iC/FuzAZky9ZRnekYyoAQp3mFJlvSk45uOzShg0H3atpNOjHnLJsT3c +y33TIL8d2QECHk3lxh32KQ3Uo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQY +MBaAFKrUcaKhFhHJQSjxqzXLwmy0pksAMB0GA1UdDgQWBBSq1HGioRYRyUEo8as1 +y8JstKZLADAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDSQAwRgIhAJFw9Pzr +wPbnxoI+kmjiyVJWTbbEdEj851UVqUQzQyyzAiEA39kgmOdpo8i+IQK0JeybWT1O +y5R/tH3fkBE1UmdU9vs= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Siterwell_Matter_PAA_vid_0x1280.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Siterwell_Matter_PAA_vid_0x1280.der new file mode 100644 index 00000000000000..3bef6e3cd241ed Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Siterwell_Matter_PAA_vid_0x1280.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Siterwell_Matter_PAA_vid_0x1280.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Siterwell_Matter_PAA_vid_0x1280.pem new file mode 100644 index 00000000000000..058ad61c6bbd4e --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Siterwell_Matter_PAA_vid_0x1280.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBrDCCAVKgAwIBAgIQRiyCdXmivf3OlrNzD0ppxzAKBggqhkjOPQQDAjA1MR0w +GwYDVQQDDBRTaXRlcndlbGwgTWF0dGVyIFBBQTEUMBIGCisGAQQBgqJ8AgEMBDEy +ODAwIBcNMjMwNzMxMDUxOTExWhgPMjA3MzA3MzEwNjE4NThaMDUxHTAbBgNVBAMM +FFNpdGVyd2VsbCBNYXR0ZXIgUEFBMRQwEgYKKwYBBAGConwCAQwEMTI4MDBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABKqK8wz3+8y4v2tI4y5yLxS7MgELWsbOD+7M +BnwC5bnvMmep7k1J/Izj+w5csov3X6DXfnM/2pAWdkW5zNEdOjmjQjBAMA8GA1Ud +EwEB/wQFMAMBAf8wHQYDVR0OBBYEFFRB4Wuy7Mz+27DfvgBZeJfvUQpCMA4GA1Ud +DwEB/wQEAwIBhjAKBggqhkjOPQQDAgNIADBFAiBDG8NgmpCao831XgOF2Z3O68Xi +Rfjt/aIMJP75T7aZAwIhAIPnZzUVnXzqjSwvwjAs7NoN8GFHR2IMtTPX/eCfQ9Mb +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Snowball_Matter_PAA_01.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Snowball_Matter_PAA_01.der new file mode 100644 index 00000000000000..1918a5ab7a88a6 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Snowball_Matter_PAA_01.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Snowball_Matter_PAA_01.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Snowball_Matter_PAA_01.pem new file mode 100644 index 00000000000000..a16459e91393b3 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Snowball_Matter_PAA_01.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBpjCCAUygAwIBAgIRALcJaooAL54UjCdg4g1WTlkwCgYIKoZIzj0EAwIwITEf +MB0GA1UEAwwWU25vd2JhbGwgTWF0dGVyIFBBQSAwMTAgFw0yMzA1MjYwMjQ2NDZa +GA85OTk5MTIzMTIzNTk1OVowITEfMB0GA1UEAwwWU25vd2JhbGwgTWF0dGVyIFBB +QSAwMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABIg+JlpiMQ4B2XmkKsdifmVg +VTUyynb14BHfL+QYMtJOUh9OD+gncUsI/kUMpsZIsfQZMvmjVcAhFyCyofgXAR+j +YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPMKfvfKk0OqvqSAG79FSE/+ ++B5lMA4GA1UdDwEB/wQEAwIBhjAfBgNVHSMEGDAWgBTzCn73ypNDqr6kgBu/RUhP +/vgeZTAKBggqhkjOPQQDAgNIADBFAiBIqFNj7y0/uczzcen/QRBBtaCEx95taH/Y +/L6AGycY3AIhAJsGJzv3Dp79e89XvqjUIpZ6Gc26YYBjIslm1RiPJqOh +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_SwitchBot_Matter_PAA_vid_0x1397.der b/credentials/development/paa-root-certs/dcld_mirror_CN_SwitchBot_Matter_PAA_vid_0x1397.der new file mode 100644 index 00000000000000..c790f5f8275d0b Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_SwitchBot_Matter_PAA_vid_0x1397.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_SwitchBot_Matter_PAA_vid_0x1397.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_SwitchBot_Matter_PAA_vid_0x1397.pem new file mode 100644 index 00000000000000..3357104a819302 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_SwitchBot_Matter_PAA_vid_0x1397.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBrTCCAVOgAwIBAgIRAKH/1ohrnkBd4iGtRVxQypEwCgYIKoZIzj0EAwIwNTEd +MBsGA1UEAwwUU3dpdGNoQm90IE1hdHRlciBQQUExFDASBgorBgEEAYKifAIBDAQx +Mzk3MCAXDTI0MDUyMDA2NTM1NloYDzk5OTkxMjMxMjM1OTU5WjA1MR0wGwYDVQQD +DBRTd2l0Y2hCb3QgTWF0dGVyIFBBQTEUMBIGCisGAQQBgqJ8AgEMBDEzOTcwWTAT +BgcqhkjOPQIBBggqhkjOPQMBBwNCAASEiZlGTnuCQv6nMESGdy6k8Mmfjx594NlF +6LbfNAy+7lzF9kwWHNe8LJ8tfy0K2s/lhj6nE5+lGJDiyx6J6GOUo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBTDlqbmlIzEa0Kigk0qb2lHl+pgBDAOBgNV +HQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDSAAwRQIhAIA5Bmac8qsY0Nn0As13JtAS +NiTo10DyhJgcH4JTAkHmAiBvDxfGuxxmPcBd3Z32m+vWvRJWdRdAxeUWOThq/VEc +Gw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Tuya_Global_Matter_PAA.der b/credentials/development/paa-root-certs/dcld_mirror_CN_Tuya_Global_Matter_PAA.der new file mode 100644 index 00000000000000..5fbe23e150fbe5 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_Tuya_Global_Matter_PAA.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_Tuya_Global_Matter_PAA.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_Tuya_Global_Matter_PAA.pem new file mode 100644 index 00000000000000..c7acc15eff6d6e --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_Tuya_Global_Matter_PAA.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBqTCCAU+gAwIBAgIRAjag4Z9E4rs66DU81lWM2BowCgYIKoZIzj0EAwIwITEf +MB0GA1UEAwwWVHV5YSBHbG9iYWwgTWF0dGVyIFBBQTAgFw0yMzA1MTEwMzM3NTJa +GA85OTk5MTIzMTIzNTk1OVowITEfMB0GA1UEAwwWVHV5YSBHbG9iYWwgTWF0dGVy +IFBBQTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH4CeKD2gYwer2ruMLHlaHHQ +rAOojboW2PVJgF1yNaoWJX7kJpMvL3l2g95Ia687IpmYCbtoH6Q4hZwwaSICO/Gj +ZjBkMBIGA1UdEwEB/wQIMAYBAf8CAQEwHwYDVR0jBBgwFoAUhLmLZqwa/Za2RQ8j +07uWTU6KnGYwHQYDVR0OBBYEFIS5i2asGv2WtkUPI9O7lk1OipxmMA4GA1UdDwEB +/wQEAwIBBjAKBggqhkjOPQQDAgNIADBFAiEA/b0F0/4AiOXOexodWOFMjHDTc3Wu +IyZPa6pbKDgROdsCIGBPa6+9WufbJfEDqMG6APR6y4UL6EJ38aQ0nzfvGL7X +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_U-tec_Group_Matter_PAA_vid_0x147F.der b/credentials/development/paa-root-certs/dcld_mirror_CN_U-tec_Group_Matter_PAA_vid_0x147F.der new file mode 100644 index 00000000000000..ea374038f5f675 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_U-tec_Group_Matter_PAA_vid_0x147F.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_U-tec_Group_Matter_PAA_vid_0x147F.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_U-tec_Group_Matter_PAA_vid_0x147F.pem new file mode 100644 index 00000000000000..2b9a9f28045d8a --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_U-tec_Group_Matter_PAA_vid_0x147F.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB0TCCAXegAwIBAgIQcW2ozBN3DXDRxu5WB+7pQDAKBggqhkjOPQQDAjA3MR8w +HQYDVQQDDBZVLXRlYyBHcm91cCBNYXR0ZXIgUEFBMRQwEgYKKwYBBAGConwCAQwE +MTQ3RjAgFw0yMzA5MjgwODIwMjVaGA85OTk5MTIzMTIzNTk1OVowNzEfMB0GA1UE +AwwWVS10ZWMgR3JvdXAgTWF0dGVyIFBBQTEUMBIGCisGAQQBgqJ8AgEMBDE0N0Yw +WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQwlTnGXMTv/ti+2RiWW+jo5YAnQZCQ +O5YRB/H2CsJxaPGd8vMO+dkAojDGZ75WeX9i6BANsumrTVPxQEMEHF6Oo2MwYTAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSd4k9reLK0iTyCYxhrD2lOaLdwQDAO +BgNVHQ8BAf8EBAMCAYYwHwYDVR0jBBgwFoAUneJPa3iytIk8gmMYaw9pTmi3cEAw +CgYIKoZIzj0EAwIDSAAwRQIgeXVod4h2ZTejsAUFkqLHqhJoRl+6SMAIdx30vb3J +oAICIQCBsHNxeUOBR5Wr1mAislT44BDbwxg+1ImdAmcmicK/Qw== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_heiman_Matter_Protocol_PAA_vid_0x120B.der b/credentials/development/paa-root-certs/dcld_mirror_CN_heiman_Matter_Protocol_PAA_vid_0x120B.der new file mode 100644 index 00000000000000..306b4606d06e99 Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_CN_heiman_Matter_Protocol_PAA_vid_0x120B.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_CN_heiman_Matter_Protocol_PAA_vid_0x120B.pem b/credentials/development/paa-root-certs/dcld_mirror_CN_heiman_Matter_Protocol_PAA_vid_0x120B.pem new file mode 100644 index 00000000000000..9a310f1fa5f28d --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_CN_heiman_Matter_Protocol_PAA_vid_0x120B.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2zCCAYCgAwIBAgIRAPzT02W5Sj7DtbZGJF4Hm9cwCgYIKoZIzj0EAwIwOzEj +MCEGA1UEAwwaaGVpbWFuIE1hdHRlciBQcm90b2NvbCBQQUExFDASBgorBgEEAYKi +fAIBDAQxMjBCMCAXDTIzMDYwNjA1MTcyOFoYDzIyOTcwMzIwMDYxNzI4WjA7MSMw +IQYDVQQDDBpoZWltYW4gTWF0dGVyIFByb3RvY29sIFBBQTEUMBIGCisGAQQBgqJ8 +AgEMBDEyMEIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR8ZlgiorZXXfbaRRJr +qfcK8VMnJHVAmn1nx112Z7NAgrib9rBtXdga8llOxxxxHcEw463RFRkNKl3BioIz +V4Xao2MwYTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTZElNw6DDRCBGCv5UH +zVBPY1tnTzAOBgNVHQ8BAf8EBAMCAYYwHwYDVR0jBBgwFoAU2RJTcOgw0QgRgr+V +B81QT2NbZ08wCgYIKoZIzj0EAwIDSQAwRgIhAPoAVZ3kzmh3VI2pEDxx/7Gj0raO +9qPmjQ+fiEj+FOFSAiEAvzSukdMbjA26I55CG23E/LAfpzzQFFfJEN+r5G4bWk8= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/credentials/development/paa-root-certs/dcld_mirror_SERIALNUMBER_63709330400004_CN_NXP_Matter_PAA_G2.der b/credentials/development/paa-root-certs/dcld_mirror_SERIALNUMBER_63709330400004_CN_NXP_Matter_PAA_G2.der new file mode 100644 index 00000000000000..660cda4956548c Binary files /dev/null and b/credentials/development/paa-root-certs/dcld_mirror_SERIALNUMBER_63709330400004_CN_NXP_Matter_PAA_G2.der differ diff --git a/credentials/development/paa-root-certs/dcld_mirror_SERIALNUMBER_63709330400004_CN_NXP_Matter_PAA_G2.pem b/credentials/development/paa-root-certs/dcld_mirror_SERIALNUMBER_63709330400004_CN_NXP_Matter_PAA_G2.pem new file mode 100644 index 00000000000000..2a5978727a7756 --- /dev/null +++ b/credentials/development/paa-root-certs/dcld_mirror_SERIALNUMBER_63709330400004_CN_NXP_Matter_PAA_G2.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB0TCCAXagAwIBAgIQPG2i2IIJe1nGYTjIGE2dRDAKBggqhkjOPQQDAjA1MRow +GAYDVQQDDBFOWFAgTWF0dGVyIFBBQSBHMjEXMBUGA1UEBRMONjM3MDkzMzA0MDAw +MDQwIBcNMjQwMzI1MTIwMDAwWhgPOTk5OTEyMzEyMzU5NTlaMDUxGjAYBgNVBAMM +EU5YUCBNYXR0ZXIgUEFBIEcyMRcwFQYDVQQFEw42MzcwOTMzMDQwMDAwNDBZMBMG +ByqGSM49AgEGCCqGSM49AwEHA0IABFQG9AzXs7Vj4mSfBcAotpFch33eiMtSmSPh +ppZWEcu+536+jhBeMcTqAxQKVxXYWVSVrSO8eAM/qnDav0LKmumjZjBkMBIGA1Ud +EwEB/wQIMAYBAf8CAQEwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBREifg5wyJ0 +XTDaZrzD4bI7HzjPCDAfBgNVHSMEGDAWgBREifg5wyJ0XTDaZrzD4bI7HzjPCDAK +BggqhkjOPQQDAgNJADBGAiEA6Y7u2GyMhQ6m01NW7k/mSo1LNOXKZvSHwDYhoyS4 +jNECIQDofYDdYnwlCiGvhO05iTTO91Nfs1ZPBcBpQwWWV19SdA== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/data_model/master/clusters/ACL-Cluster.xml b/data_model/master/clusters/ACL-Cluster.xml index d5fbf419ba4daf..2278f7c7920ce4 100644 --- a/data_model/master/clusters/ACL-Cluster.xml +++ b/data_model/master/clusters/ACL-Cluster.xml @@ -57,15 +57,18 @@ Davis, CA 95616, USA --> - - + + - + + + + @@ -80,11 +83,6 @@ Davis, CA 95616, USA - - - - - @@ -106,6 +104,20 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + @@ -164,6 +176,45 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -175,7 +226,9 @@ Davis, CA 95616, USA - + + + @@ -196,8 +249,17 @@ Davis, CA 95616, USA - - + + + + + + + + + + + @@ -205,6 +267,27 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + @@ -229,7 +312,9 @@ Davis, CA 95616, USA - + + + @@ -248,5 +333,30 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/clusters/AccountLogin.xml b/data_model/master/clusters/AccountLogin.xml index 8a9ed7d9389f40..6205fb6cb73261 100644 --- a/data_model/master/clusters/AccountLogin.xml +++ b/data_model/master/clusters/AccountLogin.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/AdminCommissioningCluster.xml b/data_model/master/clusters/AdminCommissioningCluster.xml index 8e95e46f128db0..77a8862b2eedc7 100644 --- a/data_model/master/clusters/AdminCommissioningCluster.xml +++ b/data_model/master/clusters/AdminCommissioningCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/AirQuality.xml b/data_model/master/clusters/AirQuality.xml index c05717863c5ff4..69387d451a38c0 100644 --- a/data_model/master/clusters/AirQuality.xml +++ b/data_model/master/clusters/AirQuality.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ApplicationBasic.xml b/data_model/master/clusters/ApplicationBasic.xml index 28e47e7800352e..93ffeeb958ad3a 100644 --- a/data_model/master/clusters/ApplicationBasic.xml +++ b/data_model/master/clusters/ApplicationBasic.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ApplicationLauncher.xml b/data_model/master/clusters/ApplicationLauncher.xml index 27fa528a81e8cf..51fcde769007e9 100644 --- a/data_model/master/clusters/ApplicationLauncher.xml +++ b/data_model/master/clusters/ApplicationLauncher.xml @@ -57,9 +57,10 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - + + @@ -75,10 +76,19 @@ Davis, CA 95616, USA - + - + + + + + + + + + + diff --git a/data_model/master/clusters/AudioOutput.xml b/data_model/master/clusters/AudioOutput.xml index 27bb5a20bb7952..9972a8a87e7a6f 100644 --- a/data_model/master/clusters/AudioOutput.xml +++ b/data_model/master/clusters/AudioOutput.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/BasicInformationCluster.xml b/data_model/master/clusters/BasicInformationCluster.xml index 538b4f5e9e9f8b..168a0353761159 100644 --- a/data_model/master/clusters/BasicInformationCluster.xml +++ b/data_model/master/clusters/BasicInformationCluster.xml @@ -57,20 +57,15 @@ Davis, CA 95616, USA --> - + - + - - - - - @@ -308,23 +303,12 @@ Davis, CA 95616, USA - + - - - - - - - - - - - @@ -351,15 +335,5 @@ Davis, CA 95616, USA - - - - - - - - - - \ No newline at end of file diff --git a/data_model/master/clusters/Binding-Cluster.xml b/data_model/master/clusters/Binding-Cluster.xml index 055725f0b9ee47..72fc1eb6b3282d 100644 --- a/data_model/master/clusters/Binding-Cluster.xml +++ b/data_model/master/clusters/Binding-Cluster.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/BooleanState.xml b/data_model/master/clusters/BooleanState.xml index ddb16e26a1d6ad..9754a7af60b57a 100644 --- a/data_model/master/clusters/BooleanState.xml +++ b/data_model/master/clusters/BooleanState.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/BooleanStateConfiguration.xml b/data_model/master/clusters/BooleanStateConfiguration.xml index 719cd9569b5ae2..d4ae791ad7649f 100644 --- a/data_model/master/clusters/BooleanStateConfiguration.xml +++ b/data_model/master/clusters/BooleanStateConfiguration.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Channel.xml b/data_model/master/clusters/Channel.xml index 6177bfe6a652cc..a2edf151cb6001 100644 --- a/data_model/master/clusters/Channel.xml +++ b/data_model/master/clusters/Channel.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/CommissionerControlCluster.xml b/data_model/master/clusters/CommissionerControlCluster.xml index eaaa3c51ec4a30..9cda8f414c89da 100644 --- a/data_model/master/clusters/CommissionerControlCluster.xml +++ b/data_model/master/clusters/CommissionerControlCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ContentAppObserver.xml b/data_model/master/clusters/ContentAppObserver.xml index d6808baf982215..7ffe0b11d04377 100644 --- a/data_model/master/clusters/ContentAppObserver.xml +++ b/data_model/master/clusters/ContentAppObserver.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ContentControl.xml b/data_model/master/clusters/ContentControl.xml index 6848886c43ac02..6b72a298ebeead 100644 --- a/data_model/master/clusters/ContentControl.xml +++ b/data_model/master/clusters/ContentControl.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ContentLauncher.xml b/data_model/master/clusters/ContentLauncher.xml index b4d6e7fa26500c..5470a14ce1da64 100644 --- a/data_model/master/clusters/ContentLauncher.xml +++ b/data_model/master/clusters/ContentLauncher.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Descriptor-Cluster.xml b/data_model/master/clusters/Descriptor-Cluster.xml index 9c0bcf0b2348e3..fabc3a2a16c658 100644 --- a/data_model/master/clusters/Descriptor-Cluster.xml +++ b/data_model/master/clusters/Descriptor-Cluster.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/DeviceEnergyManagement.xml b/data_model/master/clusters/DeviceEnergyManagement.xml index efc027f27cdeee..cb7f46c008f5e1 100644 --- a/data_model/master/clusters/DeviceEnergyManagement.xml +++ b/data_model/master/clusters/DeviceEnergyManagement.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/DiagnosticLogsCluster.xml b/data_model/master/clusters/DiagnosticLogsCluster.xml index 38520e81a85e16..9dc7f4c7ef448d 100644 --- a/data_model/master/clusters/DiagnosticLogsCluster.xml +++ b/data_model/master/clusters/DiagnosticLogsCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/DiagnosticsEthernet.xml b/data_model/master/clusters/DiagnosticsEthernet.xml index fd2bb0341ca06c..f000669f64156c 100644 --- a/data_model/master/clusters/DiagnosticsEthernet.xml +++ b/data_model/master/clusters/DiagnosticsEthernet.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/DiagnosticsGeneral.xml b/data_model/master/clusters/DiagnosticsGeneral.xml index ff78100fe3a7d3..1266705ba6d0dc 100644 --- a/data_model/master/clusters/DiagnosticsGeneral.xml +++ b/data_model/master/clusters/DiagnosticsGeneral.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + @@ -200,12 +200,12 @@ Davis, CA 95616, USA - + - + diff --git a/data_model/master/clusters/DiagnosticsSoftware.xml b/data_model/master/clusters/DiagnosticsSoftware.xml index c7ee8ee842bf02..55e865af040763 100644 --- a/data_model/master/clusters/DiagnosticsSoftware.xml +++ b/data_model/master/clusters/DiagnosticsSoftware.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/DiagnosticsThread.xml b/data_model/master/clusters/DiagnosticsThread.xml index 1da3eba21a4e4e..a55412d7fd3eff 100644 --- a/data_model/master/clusters/DiagnosticsThread.xml +++ b/data_model/master/clusters/DiagnosticsThread.xml @@ -55,10 +55,11 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + + @@ -665,6 +666,16 @@ Davis, CA 95616, USA + + + + + + + + + + diff --git a/data_model/master/clusters/DiagnosticsWiFi.xml b/data_model/master/clusters/DiagnosticsWiFi.xml index 6ef28ee4cc09e0..87f7e44dc92b55 100644 --- a/data_model/master/clusters/DiagnosticsWiFi.xml +++ b/data_model/master/clusters/DiagnosticsWiFi.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/DoorLock.xml b/data_model/master/clusters/DoorLock.xml index 138d40bdd544d6..46d659da94a690 100644 --- a/data_model/master/clusters/DoorLock.xml +++ b/data_model/master/clusters/DoorLock.xml @@ -116,9 +116,6 @@ Davis, CA 95616, USA - - - @@ -279,23 +276,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - @@ -494,66 +474,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -598,29 +518,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - @@ -778,56 +675,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -871,7 +718,7 @@ Davis, CA 95616, USA - + @@ -1120,67 +967,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1958,47 +1744,6 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/data_model/master/clusters/ElectricalEnergyMeasurement.xml b/data_model/master/clusters/ElectricalEnergyMeasurement.xml index 77e05665b2d031..259f9f512aec02 100644 --- a/data_model/master/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/master/clusters/ElectricalEnergyMeasurement.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ElectricalPowerMeasurement.xml b/data_model/master/clusters/ElectricalPowerMeasurement.xml index ba9dd22f3fa799..5953d36b9d992e 100644 --- a/data_model/master/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/master/clusters/ElectricalPowerMeasurement.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/EnergyCalendar.xml b/data_model/master/clusters/EnergyCalendar.xml index 5e9b3b782a435c..5be0f8ff520aea 100644 --- a/data_model/master/clusters/EnergyCalendar.xml +++ b/data_model/master/clusters/EnergyCalendar.xml @@ -59,9 +59,9 @@ Davis, CA 95616, USA --> - + - + diff --git a/data_model/master/clusters/EnergyEVSE.xml b/data_model/master/clusters/EnergyEVSE.xml index e481e06aa4e5d4..a4c865c3096a60 100644 --- a/data_model/master/clusters/EnergyEVSE.xml +++ b/data_model/master/clusters/EnergyEVSE.xml @@ -57,12 +57,11 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + - + - - + @@ -76,16 +75,25 @@ Davis, CA 95616, USA - + + + + - + + + + - + + + + diff --git a/data_model/master/clusters/EnergyPreference.xml b/data_model/master/clusters/EnergyPreference.xml index cd2b722607a45b..2534ccfc8474c6 100644 --- a/data_model/master/clusters/EnergyPreference.xml +++ b/data_model/master/clusters/EnergyPreference.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/EnergyPrice.xml b/data_model/master/clusters/EnergyPrice.xml index a4efa28e1b0dbf..aae07641398eeb 100644 --- a/data_model/master/clusters/EnergyPrice.xml +++ b/data_model/master/clusters/EnergyPrice.xml @@ -59,10 +59,10 @@ Davis, CA 95616, USA --> - + - + diff --git a/data_model/master/clusters/FanControl.xml b/data_model/master/clusters/FanControl.xml index daae13aff910d4..9eba1df549981c 100644 --- a/data_model/master/clusters/FanControl.xml +++ b/data_model/master/clusters/FanControl.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/GeneralCommissioningCluster.xml b/data_model/master/clusters/GeneralCommissioningCluster.xml index ed10afa8406a5a..2d9e65848f0c85 100644 --- a/data_model/master/clusters/GeneralCommissioningCluster.xml +++ b/data_model/master/clusters/GeneralCommissioningCluster.xml @@ -57,7 +57,7 @@ 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 35de0890bd87d3..784bdc903ec186 100644 --- a/data_model/master/clusters/Group-Key-Management-Cluster.xml +++ b/data_model/master/clusters/Group-Key-Management-Cluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Groups.xml b/data_model/master/clusters/Groups.xml index 6c53c1a602f255..214e6c18280afa 100644 --- a/data_model/master/clusters/Groups.xml +++ b/data_model/master/clusters/Groups.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Humidistat.xml b/data_model/master/clusters/Humidistat.xml index c3aac1dab85a20..1af54698489d31 100644 --- a/data_model/master/clusters/Humidistat.xml +++ b/data_model/master/clusters/Humidistat.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ICDManagement.xml b/data_model/master/clusters/ICDManagement.xml index d4731fb545ad9a..830f62fba2a63f 100644 --- a/data_model/master/clusters/ICDManagement.xml +++ b/data_model/master/clusters/ICDManagement.xml @@ -57,10 +57,11 @@ Davis, CA 95616, USA // Update Name --> - + - + + @@ -91,6 +92,14 @@ Davis, CA 95616, USA + + + + + + + + @@ -217,6 +226,9 @@ Davis, CA 95616, USA + + + diff --git a/data_model/master/clusters/Identify.xml b/data_model/master/clusters/Identify.xml index 0ab68abb8b1635..a6682b7233d30a 100644 --- a/data_model/master/clusters/Identify.xml +++ b/data_model/master/clusters/Identify.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/JointFabricDatastoreCluster.xml b/data_model/master/clusters/JointFabricDatastoreCluster.xml index 40e46ecc78519c..79143f34d03f55 100644 --- a/data_model/master/clusters/JointFabricDatastoreCluster.xml +++ b/data_model/master/clusters/JointFabricDatastoreCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + @@ -75,14 +75,33 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + @@ -90,309 +109,376 @@ Davis, CA 95616, USA + - + + + + + + + + + - - + + + - + + - - + + + + + + + + + + + - + + - - - + + + - + + + - + + + - - + + + - + + + - + + - + + - - + + + - + + - - + + + + + - - + + + + + + + + + + + + + + + - + + - + + - + + - + - + - + - + - + - - - - - - - + - + - + - + + - + + - - - - - + + - - - - - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + + - - - - - + + + - + + + - + - - - - + - + - + - + + - + + + + + - + - + + - + - - - - + - + - + - + + - + - + - + - + - + - + - + - + - - - - + - + - + @@ -402,32 +488,23 @@ Davis, CA 95616, USA - + - - - - + - + - + - - - - + - - - - + diff --git a/data_model/master/clusters/JointFabricPKICluster.xml b/data_model/master/clusters/JointFabricPKICluster.xml index 3519a11cec79c6..b8c9474b0163d8 100644 --- a/data_model/master/clusters/JointFabricPKICluster.xml +++ b/data_model/master/clusters/JointFabricPKICluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/KeypadInput.xml b/data_model/master/clusters/KeypadInput.xml index 57d6ef4650e013..efeb92ba28fb73 100644 --- a/data_model/master/clusters/KeypadInput.xml +++ b/data_model/master/clusters/KeypadInput.xml @@ -59,7 +59,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 b915e77bb5a01f..a172d1e281eff5 100644 --- a/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml @@ -59,7 +59,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 43148b6dc9186f..2f8a371f74042c 100644 --- a/data_model/master/clusters/Label-Cluster-LabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-LabelCluster.xml @@ -59,7 +59,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 40dac53a4242cd..466550f12520f1 100644 --- a/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/LaundryDryerControls.xml b/data_model/master/clusters/LaundryDryerControls.xml index d860d2ef9dcf21..85f7871b267be5 100644 --- a/data_model/master/clusters/LaundryDryerControls.xml +++ b/data_model/master/clusters/LaundryDryerControls.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/LaundryWasherControls.xml b/data_model/master/clusters/LaundryWasherControls.xml index 6fbfc0a882d3d1..046ecc3c51d697 100644 --- a/data_model/master/clusters/LaundryWasherControls.xml +++ b/data_model/master/clusters/LaundryWasherControls.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/LevelControl.xml b/data_model/master/clusters/LevelControl.xml index 5da823bc1dceb0..28f88b96832c32 100644 --- a/data_model/master/clusters/LevelControl.xml +++ b/data_model/master/clusters/LevelControl.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/LocalizationConfiguration.xml b/data_model/master/clusters/LocalizationConfiguration.xml index 7ddfba8efcc9cb..6bc3abd50600ab 100644 --- a/data_model/master/clusters/LocalizationConfiguration.xml +++ b/data_model/master/clusters/LocalizationConfiguration.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/LocalizationTimeFormat.xml b/data_model/master/clusters/LocalizationTimeFormat.xml index 2ede281c7352a9..2de3724879701d 100644 --- a/data_model/master/clusters/LocalizationTimeFormat.xml +++ b/data_model/master/clusters/LocalizationTimeFormat.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/LocalizationUnit.xml b/data_model/master/clusters/LocalizationUnit.xml index 0157ebb53b0d39..e08ce0e8810f26 100644 --- a/data_model/master/clusters/LocalizationUnit.xml +++ b/data_model/master/clusters/LocalizationUnit.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/LowPower.xml b/data_model/master/clusters/LowPower.xml index cf75cb0c680164..2e91a02c16a4b3 100644 --- a/data_model/master/clusters/LowPower.xml +++ b/data_model/master/clusters/LowPower.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/MediaInput.xml b/data_model/master/clusters/MediaInput.xml index a92985ff924a75..c01567f6e1ae3e 100644 --- a/data_model/master/clusters/MediaInput.xml +++ b/data_model/master/clusters/MediaInput.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/MediaPlayback.xml b/data_model/master/clusters/MediaPlayback.xml index dae60d7a1b2572..e37d5944aeb366 100644 --- a/data_model/master/clusters/MediaPlayback.xml +++ b/data_model/master/clusters/MediaPlayback.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Messages.xml b/data_model/master/clusters/Messages.xml index 402310c4b92eea..d2dbd28ba87f81 100644 --- a/data_model/master/clusters/Messages.xml +++ b/data_model/master/clusters/Messages.xml @@ -98,7 +98,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/MicrowaveOvenControl.xml b/data_model/master/clusters/MicrowaveOvenControl.xml index 360b9edeaa55f1..2169f7b1437945 100644 --- a/data_model/master/clusters/MicrowaveOvenControl.xml +++ b/data_model/master/clusters/MicrowaveOvenControl.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ModeBase.xml b/data_model/master/clusters/ModeBase.xml index 4a70ad670d0dca..c874eee69d3eb6 100644 --- a/data_model/master/clusters/ModeBase.xml +++ b/data_model/master/clusters/ModeBase.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + @@ -105,7 +105,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ModeSelect.xml b/data_model/master/clusters/ModeSelect.xml index 76ebf5874af273..6e6f062182e503 100644 --- a/data_model/master/clusters/ModeSelect.xml +++ b/data_model/master/clusters/ModeSelect.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + @@ -116,7 +116,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml index 08c4044617d716..ff8f7e910e94b0 100644 --- a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Mode_Dishwasher.xml b/data_model/master/clusters/Mode_Dishwasher.xml index 40a19828d44ebb..8069fdddcf0cc3 100644 --- a/data_model/master/clusters/Mode_Dishwasher.xml +++ b/data_model/master/clusters/Mode_Dishwasher.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + @@ -80,6 +80,11 @@ Davis, CA 95616, USA + + + + + @@ -88,10 +93,10 @@ Davis, CA 95616, USA - + - + \ No newline at end of file diff --git a/data_model/master/clusters/Mode_EVSE.xml b/data_model/master/clusters/Mode_EVSE.xml index f139ab3cbfaf9a..daf8042cc3293b 100644 --- a/data_model/master/clusters/Mode_EVSE.xml +++ b/data_model/master/clusters/Mode_EVSE.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Mode_LaundryWasher.xml b/data_model/master/clusters/Mode_LaundryWasher.xml index 5d3cce891790e1..444d536fd178fd 100644 --- a/data_model/master/clusters/Mode_LaundryWasher.xml +++ b/data_model/master/clusters/Mode_LaundryWasher.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + @@ -80,6 +80,11 @@ Davis, CA 95616, USA + + + + + @@ -88,10 +93,10 @@ Davis, CA 95616, USA - + - + \ No newline at end of file diff --git a/data_model/master/clusters/Mode_MicrowaveOven.xml b/data_model/master/clusters/Mode_MicrowaveOven.xml index 6f1e8ed895f489..b5076d8c270099 100644 --- a/data_model/master/clusters/Mode_MicrowaveOven.xml +++ b/data_model/master/clusters/Mode_MicrowaveOven.xml @@ -59,12 +59,17 @@ Davis, CA 95616, USA --> - + + + + + + diff --git a/data_model/master/clusters/Mode_Oven.xml b/data_model/master/clusters/Mode_Oven.xml index bf6c1b57928a57..f7e8c8a4268cf2 100644 --- a/data_model/master/clusters/Mode_Oven.xml +++ b/data_model/master/clusters/Mode_Oven.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + @@ -79,4 +79,23 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/clusters/Mode_RVCClean.xml b/data_model/master/clusters/Mode_RVCClean.xml index b48ffa24a35b50..26b5d15c185fe3 100644 --- a/data_model/master/clusters/Mode_RVCClean.xml +++ b/data_model/master/clusters/Mode_RVCClean.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + @@ -81,6 +81,11 @@ Davis, CA 95616, USA + + + + + diff --git a/data_model/master/clusters/Mode_RVCRun.xml b/data_model/master/clusters/Mode_RVCRun.xml index ddfad8adc89d2e..ad0d7601a45c22 100644 --- a/data_model/master/clusters/Mode_RVCRun.xml +++ b/data_model/master/clusters/Mode_RVCRun.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + @@ -81,6 +81,11 @@ Davis, CA 95616, USA + + + + + diff --git a/data_model/master/clusters/Mode_Refrigerator.xml b/data_model/master/clusters/Mode_Refrigerator.xml index b4550283daf9e5..84410d1ddfc465 100644 --- a/data_model/master/clusters/Mode_Refrigerator.xml +++ b/data_model/master/clusters/Mode_Refrigerator.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + @@ -80,6 +80,11 @@ Davis, CA 95616, USA + + + + + @@ -88,10 +93,10 @@ Davis, CA 95616, USA - + - + \ No newline at end of file diff --git a/data_model/master/clusters/Mode_WaterHeater.xml b/data_model/master/clusters/Mode_WaterHeater.xml index 482ea0e33d0f9a..1779e74bab8c84 100644 --- a/data_model/master/clusters/Mode_WaterHeater.xml +++ b/data_model/master/clusters/Mode_WaterHeater.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/NetworkCommissioningCluster.xml b/data_model/master/clusters/NetworkCommissioningCluster.xml index 63efd6c3d3cbb2..8eefb234a2920a 100644 --- a/data_model/master/clusters/NetworkCommissioningCluster.xml +++ b/data_model/master/clusters/NetworkCommissioningCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/NetworkIdentityManagement.xml b/data_model/master/clusters/NetworkIdentityManagement.xml index b432b8b68f6b23..cef2f88f6ddad9 100644 --- a/data_model/master/clusters/NetworkIdentityManagement.xml +++ b/data_model/master/clusters/NetworkIdentityManagement.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/OTAProvider.xml b/data_model/master/clusters/OTAProvider.xml index 2a5be10961f02c..f300a419518675 100644 --- a/data_model/master/clusters/OTAProvider.xml +++ b/data_model/master/clusters/OTAProvider.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/OTARequestor.xml b/data_model/master/clusters/OTARequestor.xml index 3a562c9f18a046..83314d14d9551a 100644 --- a/data_model/master/clusters/OTARequestor.xml +++ b/data_model/master/clusters/OTARequestor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/OccupancySensing.xml b/data_model/master/clusters/OccupancySensing.xml index 2852ce812f9308..4cd027deb07279 100644 --- a/data_model/master/clusters/OccupancySensing.xml +++ b/data_model/master/clusters/OccupancySensing.xml @@ -410,7 +410,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/OnOff.xml b/data_model/master/clusters/OnOff.xml index b06c96a64376ac..b1ea6ebba4af7d 100644 --- a/data_model/master/clusters/OnOff.xml +++ b/data_model/master/clusters/OnOff.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/OperationalCredentialCluster.xml b/data_model/master/clusters/OperationalCredentialCluster.xml index b3811db4a5774a..338a8af007c5b9 100644 --- a/data_model/master/clusters/OperationalCredentialCluster.xml +++ b/data_model/master/clusters/OperationalCredentialCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/OperationalState.xml b/data_model/master/clusters/OperationalState.xml index 06c77fc29a2c19..354efa2400bda7 100644 --- a/data_model/master/clusters/OperationalState.xml +++ b/data_model/master/clusters/OperationalState.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/OperationalState_Oven.xml b/data_model/master/clusters/OperationalState_Oven.xml index fbcc634330faa7..710dea9806bf57 100644 --- a/data_model/master/clusters/OperationalState_Oven.xml +++ b/data_model/master/clusters/OperationalState_Oven.xml @@ -59,10 +59,21 @@ Davis, CA 95616, USA --> - + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/clusters/OperationalState_RVC.xml b/data_model/master/clusters/OperationalState_RVC.xml index f33791fcf86407..5d2d28db2c2cad 100644 --- a/data_model/master/clusters/OperationalState_RVC.xml +++ b/data_model/master/clusters/OperationalState_RVC.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/PowerSourceCluster.xml b/data_model/master/clusters/PowerSourceCluster.xml index 4596880e32b938..a0b6b91c565dd8 100644 --- a/data_model/master/clusters/PowerSourceCluster.xml +++ b/data_model/master/clusters/PowerSourceCluster.xml @@ -55,10 +55,11 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + + @@ -631,7 +632,7 @@ Davis, CA 95616, USA - + @@ -639,7 +640,7 @@ Davis, CA 95616, USA - + @@ -744,7 +745,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/PowerSourceConfigurationCluster.xml b/data_model/master/clusters/PowerSourceConfigurationCluster.xml index 5348f6f0b091b6..61df60149ca00f 100644 --- a/data_model/master/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/master/clusters/PowerSourceConfigurationCluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/PowerTopology.xml b/data_model/master/clusters/PowerTopology.xml index b958d03c01aeb1..eb0a2d74f5e585 100644 --- a/data_model/master/clusters/PowerTopology.xml +++ b/data_model/master/clusters/PowerTopology.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ProxyConfiguration-Cluster.xml b/data_model/master/clusters/ProxyConfiguration-Cluster.xml index c33ed5cd03b841..6796e79ac9bf59 100644 --- a/data_model/master/clusters/ProxyConfiguration-Cluster.xml +++ b/data_model/master/clusters/ProxyConfiguration-Cluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ProxyDiscovery-Cluster.xml b/data_model/master/clusters/ProxyDiscovery-Cluster.xml index 159bdff7333853..7353386929c109 100644 --- a/data_model/master/clusters/ProxyDiscovery-Cluster.xml +++ b/data_model/master/clusters/ProxyDiscovery-Cluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ResourceMonitoring.xml b/data_model/master/clusters/ResourceMonitoring.xml index feb6394fd6b47d..b9d26ff6dd9ecf 100644 --- a/data_model/master/clusters/ResourceMonitoring.xml +++ b/data_model/master/clusters/ResourceMonitoring.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ServiceArea.xml b/data_model/master/clusters/ServiceArea.xml index 4980fc5ad40274..6a54264a94928b 100644 --- a/data_model/master/clusters/ServiceArea.xml +++ b/data_model/master/clusters/ServiceArea.xml @@ -57,95 +57,77 @@ Davis, CA 95616, USA --> - + - + - + + + + - - - - - - - - - - - - - - - - - - + - + - + - + - - - - - - - - - - - - - + + - + - - + + + - + + - - - + - - + + + - + + - + @@ -154,7 +136,7 @@ Davis, CA 95616, USA - + @@ -164,92 +146,91 @@ Davis, CA 95616, USA - + - - + + - + - - - + + + + - + - - + - - + - + - - - + + + + - + - + - - - - - - + + + - + - + - - - + + + + - + - + - + + diff --git a/data_model/master/clusters/SmokeCOAlarm.xml b/data_model/master/clusters/SmokeCOAlarm.xml index 4ba9bd2708b476..482a8a82f2abf5 100644 --- a/data_model/master/clusters/SmokeCOAlarm.xml +++ b/data_model/master/clusters/SmokeCOAlarm.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Switch.xml b/data_model/master/clusters/Switch.xml index bb2066269b4f94..92489c1e9228a3 100644 --- a/data_model/master/clusters/Switch.xml +++ b/data_model/master/clusters/Switch.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/TargetNavigator.xml b/data_model/master/clusters/TargetNavigator.xml index c5fb59919585c1..b1fcff6d60cd1e 100644 --- a/data_model/master/clusters/TargetNavigator.xml +++ b/data_model/master/clusters/TargetNavigator.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/TemperatureControl.xml b/data_model/master/clusters/TemperatureControl.xml index 2f2527ce4ad0fa..79519716ea1cf8 100644 --- a/data_model/master/clusters/TemperatureControl.xml +++ b/data_model/master/clusters/TemperatureControl.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/Thermostat.xml b/data_model/master/clusters/Thermostat.xml index 4374bc3f1c8a7d..de1743d8addf1a 100644 --- a/data_model/master/clusters/Thermostat.xml +++ b/data_model/master/clusters/Thermostat.xml @@ -1,6 +1,6 @@ - + @@ -63,8 +63,9 @@ Davis, CA 95616, USA - - + @@ -396,10 +397,10 @@ Davis, CA 95616, USA - + - + @@ -409,6 +410,11 @@ Davis, CA 95616, USA + + + + + @@ -589,7 +595,7 @@ Davis, CA 95616, USA - + @@ -654,12 +660,11 @@ Davis, CA 95616, USA - + - @@ -726,7 +731,7 @@ Davis, CA 95616, USA - + @@ -734,7 +739,7 @@ Davis, CA 95616, USA - + @@ -816,7 +821,7 @@ Davis, CA 95616, USA - + @@ -1047,7 +1052,7 @@ Davis, CA 95616, USA - + @@ -1055,7 +1060,7 @@ Davis, CA 95616, USA - + @@ -1079,16 +1084,7 @@ Davis, CA 95616, USA - - - - - - - - - - + @@ -1223,36 +1219,5 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/master/clusters/ThermostatUserInterfaceConfiguration.xml b/data_model/master/clusters/ThermostatUserInterfaceConfiguration.xml index b4ecd49f93ae4a..d6a52248282321 100644 --- a/data_model/master/clusters/ThermostatUserInterfaceConfiguration.xml +++ b/data_model/master/clusters/ThermostatUserInterfaceConfiguration.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ThreadBorderRouterManagement.xml b/data_model/master/clusters/ThreadBorderRouterManagement.xml index b22d4038219647..7ae4edab62f8b3 100644 --- a/data_model/master/clusters/ThreadBorderRouterManagement.xml +++ b/data_model/master/clusters/ThreadBorderRouterManagement.xml @@ -59,12 +59,12 @@ Davis, CA 95616, USA --> - + - + @@ -119,7 +119,7 @@ Davis, CA 95616, USA - + @@ -130,7 +130,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/ThreadNetworkDirectory.xml b/data_model/master/clusters/ThreadNetworkDirectory.xml index aeabdcf19f93d1..098b490fa5d369 100644 --- a/data_model/master/clusters/ThreadNetworkDirectory.xml +++ b/data_model/master/clusters/ThreadNetworkDirectory.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + @@ -67,8 +67,9 @@ Davis, CA 95616, USA - + + @@ -77,17 +78,21 @@ Davis, CA 95616, USA + + + - - + + + - + @@ -111,15 +116,17 @@ Davis, CA 95616, USA - + + - + - + + @@ -130,13 +137,4 @@ Davis, CA 95616, USA - - - - - - - - - \ No newline at end of file diff --git a/data_model/master/clusters/TimeSync.xml b/data_model/master/clusters/TimeSync.xml index a506a647aeb8a3..e72a9d32467983 100644 --- a/data_model/master/clusters/TimeSync.xml +++ b/data_model/master/clusters/TimeSync.xml @@ -60,7 +60,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ValidProxies-Cluster.xml b/data_model/master/clusters/ValidProxies-Cluster.xml index c5740c90e52433..51cfeedb46926d 100644 --- a/data_model/master/clusters/ValidProxies-Cluster.xml +++ b/data_model/master/clusters/ValidProxies-Cluster.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/ValveConfigurationControl.xml b/data_model/master/clusters/ValveConfigurationControl.xml index 736672bc78f716..03d40acd480ff4 100644 --- a/data_model/master/clusters/ValveConfigurationControl.xml +++ b/data_model/master/clusters/ValveConfigurationControl.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/WakeOnLAN.xml b/data_model/master/clusters/WakeOnLAN.xml index 7f5c08bdd624ad..092e0a8ea8f4de 100644 --- a/data_model/master/clusters/WakeOnLAN.xml +++ b/data_model/master/clusters/WakeOnLAN.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/WaterHeaterManagement.xml b/data_model/master/clusters/WaterHeaterManagement.xml index ee38a0058b50fb..cadf8e0a8af53b 100644 --- a/data_model/master/clusters/WaterHeaterManagement.xml +++ b/data_model/master/clusters/WaterHeaterManagement.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/WiFiNetworkManagement.xml b/data_model/master/clusters/WiFiNetworkManagement.xml index cfa10af25f0dd6..3aad5935d2843d 100644 --- a/data_model/master/clusters/WiFiNetworkManagement.xml +++ b/data_model/master/clusters/WiFiNetworkManagement.xml @@ -59,23 +59,28 @@ Davis, CA 95616, USA --> - + - + + + + + + - + diff --git a/data_model/master/clusters/WindowCovering.xml b/data_model/master/clusters/WindowCovering.xml index 2f087914405cf3..f8c60b46901dc9 100644 --- a/data_model/master/clusters/WindowCovering.xml +++ b/data_model/master/clusters/WindowCovering.xml @@ -340,13 +340,13 @@ Davis, CA 95616, USA - + - + - + @@ -464,7 +464,7 @@ Davis, CA 95616, USA - + @@ -474,7 +474,7 @@ Davis, CA 95616, USA - + @@ -491,7 +491,7 @@ Davis, CA 95616, USA - + @@ -501,7 +501,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/clusters/bridge-clusters-ActionsCluster.xml b/data_model/master/clusters/bridge-clusters-ActionsCluster.xml index 5b9b54429b9429..4874aca26bc504 100644 --- a/data_model/master/clusters/bridge-clusters-ActionsCluster.xml +++ b/data_model/master/clusters/bridge-clusters-ActionsCluster.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml b/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml index 318ad7fa54dd2a..4368d991c832f4 100644 --- a/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml +++ b/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml @@ -59,17 +59,17 @@ Davis, CA 95616, USA --> - + - + - + @@ -86,9 +86,7 @@ Davis, CA 95616, USA - - - + @@ -148,7 +146,7 @@ Davis, CA 95616, USA - + @@ -178,11 +176,15 @@ Davis, CA 95616, USA - + + + + + \ No newline at end of file diff --git a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml b/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml index 4801cbf88800ae..22cc88097acf75 100644 --- a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml +++ b/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml @@ -59,7 +59,7 @@ Davis, CA 95616, USA --> - + @@ -68,69 +68,79 @@ Davis, CA 95616, USA + - - - + + + - + + - - + + + + + + - + + + - + + - - + + + - - - - + + + + - - + + - - + + - + - - + + - + \ No newline at end of file diff --git a/data_model/master/device_types/Aggregator.xml b/data_model/master/device_types/Aggregator.xml index 48aa4347d850e1..a99ee1108c3b50 100644 --- a/data_model/master/device_types/Aggregator.xml +++ b/data_model/master/device_types/Aggregator.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/AirPurifier.xml b/data_model/master/device_types/AirPurifier.xml index 538d9a4e341efb..62045f090c71a5 100644 --- a/data_model/master/device_types/AirPurifier.xml +++ b/data_model/master/device_types/AirPurifier.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/AirQualitySensor.xml b/data_model/master/device_types/AirQualitySensor.xml index bf56eb754f24c6..756b42e437ac9a 100644 --- a/data_model/master/device_types/AirQualitySensor.xml +++ b/data_model/master/device_types/AirQualitySensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/BaseDeviceType.xml b/data_model/master/device_types/BaseDeviceType.xml index ddcc49f258f0cb..272b74feb5ff67 100644 --- a/data_model/master/device_types/BaseDeviceType.xml +++ b/data_model/master/device_types/BaseDeviceType.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/BasicVideoPlayer.xml b/data_model/master/device_types/BasicVideoPlayer.xml index ed82d08bc7a112..d35bbed3211422 100644 --- a/data_model/master/device_types/BasicVideoPlayer.xml +++ b/data_model/master/device_types/BasicVideoPlayer.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/BatteryStorage.xml b/data_model/master/device_types/BatteryStorage.xml index 321e9f9dfe2159..5f09eeb1d2dac9 100644 --- a/data_model/master/device_types/BatteryStorage.xml +++ b/data_model/master/device_types/BatteryStorage.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/BridgedNode.xml b/data_model/master/device_types/BridgedNode.xml index 59414205c052b5..6f309001975627 100644 --- a/data_model/master/device_types/BridgedNode.xml +++ b/data_model/master/device_types/BridgedNode.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/CastingVideoClient.xml b/data_model/master/device_types/CastingVideoClient.xml index 8f816b3e2a8056..949142a6bca151 100644 --- a/data_model/master/device_types/CastingVideoClient.xml +++ b/data_model/master/device_types/CastingVideoClient.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/CastingVideoPlayer.xml b/data_model/master/device_types/CastingVideoPlayer.xml index 0b65f4f7aab57d..5c88cf92947e0b 100644 --- a/data_model/master/device_types/CastingVideoPlayer.xml +++ b/data_model/master/device_types/CastingVideoPlayer.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ColorDimmerSwitch.xml b/data_model/master/device_types/ColorDimmerSwitch.xml index 190ab6c7fc8b7e..abc027eaec711c 100644 --- a/data_model/master/device_types/ColorDimmerSwitch.xml +++ b/data_model/master/device_types/ColorDimmerSwitch.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ColorTemperatureLight.xml b/data_model/master/device_types/ColorTemperatureLight.xml index 4f7cf64a9fd0a2..56db5416cf02c9 100644 --- a/data_model/master/device_types/ColorTemperatureLight.xml +++ b/data_model/master/device_types/ColorTemperatureLight.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ContactSensor.xml b/data_model/master/device_types/ContactSensor.xml index 6fa5620a77bebb..2767e5e37a384b 100644 --- a/data_model/master/device_types/ContactSensor.xml +++ b/data_model/master/device_types/ContactSensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ContentApp.xml b/data_model/master/device_types/ContentApp.xml index 300e3122336ef4..81b967db9c8dc1 100644 --- a/data_model/master/device_types/ContentApp.xml +++ b/data_model/master/device_types/ContentApp.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ControlBridge.xml b/data_model/master/device_types/ControlBridge.xml index 04ff66db808cc9..ab07228e728f52 100644 --- a/data_model/master/device_types/ControlBridge.xml +++ b/data_model/master/device_types/ControlBridge.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/CookSurface.xml b/data_model/master/device_types/CookSurface.xml index a32425e2f1df08..3a0e8f062c7495 100644 --- a/data_model/master/device_types/CookSurface.xml +++ b/data_model/master/device_types/CookSurface.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/Cooktop.xml b/data_model/master/device_types/Cooktop.xml index ea94653008d25a..2c7795de12233b 100644 --- a/data_model/master/device_types/Cooktop.xml +++ b/data_model/master/device_types/Cooktop.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/DeviceEnergyManagement.xml b/data_model/master/device_types/DeviceEnergyManagement.xml index cf148dabc13679..85f7c5d9a7cd66 100644 --- a/data_model/master/device_types/DeviceEnergyManagement.xml +++ b/data_model/master/device_types/DeviceEnergyManagement.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/DimmableLight.xml b/data_model/master/device_types/DimmableLight.xml index 059a0802f77906..4d6c53e4ae36fd 100644 --- a/data_model/master/device_types/DimmableLight.xml +++ b/data_model/master/device_types/DimmableLight.xml @@ -57,7 +57,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 65f6b6e1dd2e9c..73fd2a37c48bab 100644 --- a/data_model/master/device_types/DimmablePlug-InUnit.xml +++ b/data_model/master/device_types/DimmablePlug-InUnit.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/DimmerSwitch.xml b/data_model/master/device_types/DimmerSwitch.xml index 0ad9f23638349a..9dce28fdd7ce71 100644 --- a/data_model/master/device_types/DimmerSwitch.xml +++ b/data_model/master/device_types/DimmerSwitch.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/Dishwasher.xml b/data_model/master/device_types/Dishwasher.xml index 6e351f38360e4e..b13f9a42ebcc49 100644 --- a/data_model/master/device_types/Dishwasher.xml +++ b/data_model/master/device_types/Dishwasher.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/DoorLock.xml b/data_model/master/device_types/DoorLock.xml index 8b73bbf8679a6b..121ea179d14589 100644 --- a/data_model/master/device_types/DoorLock.xml +++ b/data_model/master/device_types/DoorLock.xml @@ -57,8 +57,8 @@ Davis, CA 95616, USA --> - - + + @@ -95,14 +95,49 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/device_types/DoorLockController.xml b/data_model/master/device_types/DoorLockController.xml index 64d26eba8d8eeb..101dc46f5ccd40 100644 --- a/data_model/master/device_types/DoorLockController.xml +++ b/data_model/master/device_types/DoorLockController.xml @@ -57,8 +57,8 @@ Davis, CA 95616, USA --> - - + + diff --git a/data_model/master/device_types/EVSE.xml b/data_model/master/device_types/EVSE.xml index a6a1e3854c88eb..d468cb8a180f22 100644 --- a/data_model/master/device_types/EVSE.xml +++ b/data_model/master/device_types/EVSE.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ElectricalSensor.xml b/data_model/master/device_types/ElectricalSensor.xml index 62c6dd9b4128b2..75c4b0bb7cbbed 100644 --- a/data_model/master/device_types/ElectricalSensor.xml +++ b/data_model/master/device_types/ElectricalSensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/EnergyTariff.xml b/data_model/master/device_types/EnergyTariff.xml index bf27554ff281db..887bfa420d8fd8 100644 --- a/data_model/master/device_types/EnergyTariff.xml +++ b/data_model/master/device_types/EnergyTariff.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/EnergyTariffCalendar.xml b/data_model/master/device_types/EnergyTariffCalendar.xml index ee3a6b9347db38..70d74b7239f41c 100644 --- a/data_model/master/device_types/EnergyTariffCalendar.xml +++ b/data_model/master/device_types/EnergyTariffCalendar.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ExtendedColorLight.xml b/data_model/master/device_types/ExtendedColorLight.xml index b4057d6b5bc997..0678094669459f 100644 --- a/data_model/master/device_types/ExtendedColorLight.xml +++ b/data_model/master/device_types/ExtendedColorLight.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ExtractorHood.xml b/data_model/master/device_types/ExtractorHood.xml index 6606b377f47a39..3e8064adb149f4 100644 --- a/data_model/master/device_types/ExtractorHood.xml +++ b/data_model/master/device_types/ExtractorHood.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/Fan.xml b/data_model/master/device_types/Fan.xml index 8bf8347e93c5b0..e5184cfe22aec7 100644 --- a/data_model/master/device_types/Fan.xml +++ b/data_model/master/device_types/Fan.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/FlowSensor.xml b/data_model/master/device_types/FlowSensor.xml index bcc27b318aac36..6a9023060e12f9 100644 --- a/data_model/master/device_types/FlowSensor.xml +++ b/data_model/master/device_types/FlowSensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/GenericSwitch.xml b/data_model/master/device_types/GenericSwitch.xml index acfa0a95005291..b8bc394b96e2e8 100644 --- a/data_model/master/device_types/GenericSwitch.xml +++ b/data_model/master/device_types/GenericSwitch.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/HeatPump.xml b/data_model/master/device_types/HeatPump.xml index ae0ce0e9a4d30a..61f556c6ed2a9b 100644 --- a/data_model/master/device_types/HeatPump.xml +++ b/data_model/master/device_types/HeatPump.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/HumidifierDehumidifier.xml b/data_model/master/device_types/HumidifierDehumidifier.xml index a917cbff4450f0..973919635fb4ae 100644 --- a/data_model/master/device_types/HumidifierDehumidifier.xml +++ b/data_model/master/device_types/HumidifierDehumidifier.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + \ No newline at end of file diff --git a/data_model/master/device_types/HumiditySensor.xml b/data_model/master/device_types/HumiditySensor.xml index 4a1808d7e0c580..c6def400a2a6bb 100644 --- a/data_model/master/device_types/HumiditySensor.xml +++ b/data_model/master/device_types/HumiditySensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/JointFabricAdmin.xml b/data_model/master/device_types/JointFabricAdmin.xml index eb57fad58127a4..7d29cbba1305d5 100644 --- a/data_model/master/device_types/JointFabricAdmin.xml +++ b/data_model/master/device_types/JointFabricAdmin.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/LaundryDryer.xml b/data_model/master/device_types/LaundryDryer.xml index d4692c7ad818a5..36dc182c393bd7 100644 --- a/data_model/master/device_types/LaundryDryer.xml +++ b/data_model/master/device_types/LaundryDryer.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/LaundryWasher.xml b/data_model/master/device_types/LaundryWasher.xml index 03b85f3bd363b4..d88ee7e9fd94ca 100644 --- a/data_model/master/device_types/LaundryWasher.xml +++ b/data_model/master/device_types/LaundryWasher.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/LightSensor.xml b/data_model/master/device_types/LightSensor.xml index 0eca130f921623..e7200e347726aa 100644 --- a/data_model/master/device_types/LightSensor.xml +++ b/data_model/master/device_types/LightSensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/MicrowaveOven.xml b/data_model/master/device_types/MicrowaveOven.xml index 3ae1fd8d5bf22d..98d2902d049610 100644 --- a/data_model/master/device_types/MicrowaveOven.xml +++ b/data_model/master/device_types/MicrowaveOven.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/ModeSelectDeviceType.xml b/data_model/master/device_types/ModeSelectDeviceType.xml index 7848ba0adc787f..ad4cf56671243b 100644 --- a/data_model/master/device_types/ModeSelectDeviceType.xml +++ b/data_model/master/device_types/ModeSelectDeviceType.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/MountedDimmableLoadControl.xml b/data_model/master/device_types/MountedDimmableLoadControl.xml new file mode 100644 index 00000000000000..2527eb6aaefcd2 --- /dev/null +++ b/data_model/master/device_types/MountedDimmableLoadControl.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/device_types/MountedOnOffControl.xml b/data_model/master/device_types/MountedOnOffControl.xml new file mode 100644 index 00000000000000..1be3cf746418aa --- /dev/null +++ b/data_model/master/device_types/MountedOnOffControl.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data_model/master/device_types/NetworkInfraManager.xml b/data_model/master/device_types/NetworkInfraManager.xml index a4d17e11c0faaa..58cbae2e7ab440 100644 --- a/data_model/master/device_types/NetworkInfraManager.xml +++ b/data_model/master/device_types/NetworkInfraManager.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/OccupancySensor.xml b/data_model/master/device_types/OccupancySensor.xml index 233d04f196e388..f257bab38a7686 100644 --- a/data_model/master/device_types/OccupancySensor.xml +++ b/data_model/master/device_types/OccupancySensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/OnOffLight.xml b/data_model/master/device_types/OnOffLight.xml index f71c0bf77fa42c..c74f5f79000919 100644 --- a/data_model/master/device_types/OnOffLight.xml +++ b/data_model/master/device_types/OnOffLight.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/OnOffLightSwitch.xml b/data_model/master/device_types/OnOffLightSwitch.xml index d6ac7f79520d26..0cfa5ba7a3702c 100644 --- a/data_model/master/device_types/OnOffLightSwitch.xml +++ b/data_model/master/device_types/OnOffLightSwitch.xml @@ -57,7 +57,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 888f365bed0b83..946f7919516e2d 100644 --- a/data_model/master/device_types/OnOffPlug-inUnit.xml +++ b/data_model/master/device_types/OnOffPlug-inUnit.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/OnOffSensor.xml b/data_model/master/device_types/OnOffSensor.xml index 935a438fb0bbef..0fc76f8314a6b5 100644 --- a/data_model/master/device_types/OnOffSensor.xml +++ b/data_model/master/device_types/OnOffSensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/OtaProvider.xml b/data_model/master/device_types/OtaProvider.xml index 375ab4e36aa987..b148d27ebb74e5 100644 --- a/data_model/master/device_types/OtaProvider.xml +++ b/data_model/master/device_types/OtaProvider.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/OtaRequestor.xml b/data_model/master/device_types/OtaRequestor.xml index 840e322bdccb72..d782ee992c454b 100644 --- a/data_model/master/device_types/OtaRequestor.xml +++ b/data_model/master/device_types/OtaRequestor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/Oven.xml b/data_model/master/device_types/Oven.xml index 9c5d23e86afda7..d34bc4c52bfbb6 100644 --- a/data_model/master/device_types/Oven.xml +++ b/data_model/master/device_types/Oven.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/PowerSource.xml b/data_model/master/device_types/PowerSource.xml index 9ed71e905535bd..4e6c6defabccf9 100644 --- a/data_model/master/device_types/PowerSource.xml +++ b/data_model/master/device_types/PowerSource.xml @@ -58,7 +58,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/master/device_types/PressureSensor.xml b/data_model/master/device_types/PressureSensor.xml index f2b7855db91c83..5b7ef86c25cc3d 100644 --- a/data_model/master/device_types/PressureSensor.xml +++ b/data_model/master/device_types/PressureSensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/Pump.xml b/data_model/master/device_types/Pump.xml index 461725136abaec..a39cd97b87e7ad 100644 --- a/data_model/master/device_types/Pump.xml +++ b/data_model/master/device_types/Pump.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/PumpController.xml b/data_model/master/device_types/PumpController.xml index 99acf1fa1c5757..25e9a8e982b5ff 100644 --- a/data_model/master/device_types/PumpController.xml +++ b/data_model/master/device_types/PumpController.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/RainSensor.xml b/data_model/master/device_types/RainSensor.xml index 473de6e31d1598..a03060c5415dc0 100644 --- a/data_model/master/device_types/RainSensor.xml +++ b/data_model/master/device_types/RainSensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/Refrigerator.xml b/data_model/master/device_types/Refrigerator.xml index 4899906c3b985e..c8bdf86e3ef737 100644 --- a/data_model/master/device_types/Refrigerator.xml +++ b/data_model/master/device_types/Refrigerator.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/RoboticVacuumCleaner.xml b/data_model/master/device_types/RoboticVacuumCleaner.xml index 2657a560109829..fd30668cd2e084 100644 --- a/data_model/master/device_types/RoboticVacuumCleaner.xml +++ b/data_model/master/device_types/RoboticVacuumCleaner.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/RoomAirConditioner.xml b/data_model/master/device_types/RoomAirConditioner.xml index 305a893dabc0fe..e2b3061a42b515 100644 --- a/data_model/master/device_types/RoomAirConditioner.xml +++ b/data_model/master/device_types/RoomAirConditioner.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/RootNodeDeviceType.xml b/data_model/master/device_types/RootNodeDeviceType.xml index 7dfd31996cc8e5..c96759503bfb13 100644 --- a/data_model/master/device_types/RootNodeDeviceType.xml +++ b/data_model/master/device_types/RootNodeDeviceType.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/SecondaryNetworkInterface.xml b/data_model/master/device_types/SecondaryNetworkInterface.xml index 51b4dc0e2ec4fa..8217aea71529d0 100644 --- a/data_model/master/device_types/SecondaryNetworkInterface.xml +++ b/data_model/master/device_types/SecondaryNetworkInterface.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/SmokeCOAlarm.xml b/data_model/master/device_types/SmokeCOAlarm.xml index 518809d449e35a..769e6f5f91bbe1 100644 --- a/data_model/master/device_types/SmokeCOAlarm.xml +++ b/data_model/master/device_types/SmokeCOAlarm.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/SolarPower.xml b/data_model/master/device_types/SolarPower.xml index 743da25e7a9a20..7556fb519a685d 100644 --- a/data_model/master/device_types/SolarPower.xml +++ b/data_model/master/device_types/SolarPower.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/Speaker.xml b/data_model/master/device_types/Speaker.xml index d1d9d85beb84c8..d3f9b1166e4458 100644 --- a/data_model/master/device_types/Speaker.xml +++ b/data_model/master/device_types/Speaker.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/TemperatureControlledCabinet.xml b/data_model/master/device_types/TemperatureControlledCabinet.xml index 299037e145d901..68788e22d7db06 100644 --- a/data_model/master/device_types/TemperatureControlledCabinet.xml +++ b/data_model/master/device_types/TemperatureControlledCabinet.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/TemperatureSensor.xml b/data_model/master/device_types/TemperatureSensor.xml index d6ccd5c18db89f..bf3221858dc103 100644 --- a/data_model/master/device_types/TemperatureSensor.xml +++ b/data_model/master/device_types/TemperatureSensor.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/Thermostat.xml b/data_model/master/device_types/Thermostat.xml index 6acdf63b10eba0..dfc55d628a5b6e 100644 --- a/data_model/master/device_types/Thermostat.xml +++ b/data_model/master/device_types/Thermostat.xml @@ -55,11 +55,12 @@ Connectivity Standards Alliance 508 Second Street, Suite 206 Davis, CA 95616, USA --> - + - + + @@ -72,60 +73,27 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - + - - - - + + - - - - + + diff --git a/data_model/master/device_types/ThreadBorderRouter.xml b/data_model/master/device_types/ThreadBorderRouter.xml index 73561999d60eba..abe38a81396cd6 100644 --- a/data_model/master/device_types/ThreadBorderRouter.xml +++ b/data_model/master/device_types/ThreadBorderRouter.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/VideoRemoteControl.xml b/data_model/master/device_types/VideoRemoteControl.xml index 7896a6f6ee6be5..de83b02508a89f 100644 --- a/data_model/master/device_types/VideoRemoteControl.xml +++ b/data_model/master/device_types/VideoRemoteControl.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/WaterFreezeDetector.xml b/data_model/master/device_types/WaterFreezeDetector.xml index f3c5f0580af21f..b2f4a49a7847e4 100644 --- a/data_model/master/device_types/WaterFreezeDetector.xml +++ b/data_model/master/device_types/WaterFreezeDetector.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/WaterHeater.xml b/data_model/master/device_types/WaterHeater.xml index 6e80928d792cfc..9d038d89c55563 100644 --- a/data_model/master/device_types/WaterHeater.xml +++ b/data_model/master/device_types/WaterHeater.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/WaterLeakDetector.xml b/data_model/master/device_types/WaterLeakDetector.xml index 0518d148910c78..7277ce69908fb6 100644 --- a/data_model/master/device_types/WaterLeakDetector.xml +++ b/data_model/master/device_types/WaterLeakDetector.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/WaterValve.xml b/data_model/master/device_types/WaterValve.xml index 5c65f4565f6746..21b77edf5fc614 100644 --- a/data_model/master/device_types/WaterValve.xml +++ b/data_model/master/device_types/WaterValve.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + diff --git a/data_model/master/device_types/WindowCovering.xml b/data_model/master/device_types/WindowCovering.xml index a2d54453b7337f..a2e16beba60ee1 100644 --- a/data_model/master/device_types/WindowCovering.xml +++ b/data_model/master/device_types/WindowCovering.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + @@ -75,15 +75,6 @@ Davis, CA 95616, USA - - - - - - - - - diff --git a/data_model/master/device_types/WindowCoveringController.xml b/data_model/master/device_types/WindowCoveringController.xml index c48f327754c599..189fee3d9d6303 100644 --- a/data_model/master/device_types/WindowCoveringController.xml +++ b/data_model/master/device_types/WindowCoveringController.xml @@ -57,7 +57,7 @@ Davis, CA 95616, USA --> - + @@ -78,15 +78,6 @@ Davis, CA 95616, USA - - - - - - - - - diff --git a/data_model/master/spec_sha b/data_model/master/spec_sha index 51aac4d9e877f4..16b2cbb1caa026 100644 --- a/data_model/master/spec_sha +++ b/data_model/master/spec_sha @@ -1 +1 @@ -358a64a52ea9583f19be23c7da0e33f19d4b1ee0 +12e2fa3014b316b202eed892cb50dec7b6851d8e diff --git a/docs/guides/esp32/config_options.md b/docs/guides/esp32/config_options.md index 646e725daa9d1e..6dc94b814b8335 100644 --- a/docs/guides/esp32/config_options.md +++ b/docs/guides/esp32/config_options.md @@ -11,3 +11,18 @@ Configure below options through `idf.py menuconfig` and build the app. CONFIG_DISABLE_IPV4=y CONFIG_LWIP_IPV4=n ``` + +### Executable component not in "main" component + +The ESP-IDF framework allows renaming the main component, which can be useful if +you want to place the app_main() function in a different component. + +For required changes in the executable component, please refer to the +[esp-idf documentation](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-guides/build-system.html#renaming-main-component). + +If you're building applications that support Matter and want to place app_main() +in a component other than main, use the following command: + +``` +idf.py -DEXECUTABLE_COMPONENT_NAME="your_component" build +``` diff --git a/docs/guides/esp32/setup_idf_chip.md b/docs/guides/esp32/setup_idf_chip.md index 5a6728c44d8417..035964bdfab1b5 100644 --- a/docs/guides/esp32/setup_idf_chip.md +++ b/docs/guides/esp32/setup_idf_chip.md @@ -13,25 +13,25 @@ step. ### Install Prerequisites -- [Linux](https://docs.espressif.com/projects/esp-idf/en/v5.1.2/esp32/get-started/linux-macos-setup.html#for-linux-users) -- [macOS](https://docs.espressif.com/projects/esp-idf/en/v5.1.2/esp32/get-started/linux-macos-setup.html#for-macos-users) +- [Linux](https://docs.espressif.com/projects/esp-idf/en/v5.3/esp32/get-started/linux-macos-setup.html#for-linux-users) +- [macOS](https://docs.espressif.com/projects/esp-idf/en/v5.3/esp32/get-started/linux-macos-setup.html#for-macos-users) ### Get IDF v5.1.2 -- Clone ESP-IDF [v5.1.2 - release](https://github.com/espressif/esp-idf/releases/tag/v5.1.2 +- Clone ESP-IDF [v5.3 + release](https://github.com/espressif/esp-idf/releases/tag/v5.3 ``` - git clone -b v5.1.2 --recursive --depth 1 --shallow-submodule https://github.com/espressif/esp-idf.git + git clone -b v5.3 --recursive --depth 1 --shallow-submodule https://github.com/espressif/esp-idf.git cd esp-idf ./install.sh ``` -- To update an existing esp-idf toolchain to v5.1.2: +- To update an existing esp-idf toolchain to v5.3: ``` cd path/to/esp-idf - git fetch --depth 1 origin v5.1.2 + git fetch --depth 1 origin v5.3 git reset --hard FETCH_HEAD git submodule update --depth 1 --recursive --init diff --git a/docs/spec_clusters.md b/docs/spec_clusters.md index ef58f016154446..05bd215fe583dc 100644 --- a/docs/spec_clusters.md +++ b/docs/spec_clusters.md @@ -7,7 +7,6 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |4 |0x0004 |Groups | |6 |0x0006 |On/Off | |8 |0x0008 |Level Control | -|28 |0x001C |Pulse Width Modulation | |29 |0x001D |Descriptor | |30 |0x001E |Binding | |31 |0x001F |AccessControl | @@ -63,23 +62,31 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |98 |0x0062 |Scenes Management | |113 |0x0071 |HEPA Filter Monitoring | |114 |0x0072 |Activated Carbon Filter Monitoring | +|121 |0x0079 |Water Tank Level Monitoring | |128 |0x0080 |Boolean State Configuration | |129 |0x0081 |Valve Configuration and Control | |144 |0x0090 |Electrical Power Measurement | |145 |0x0091 |Electrical Energy Measurement | +|148 |0x0094 |Water Heater Management | +|149 |0x0095 |Energy Price | +|150 |0x0096 |Demand Response Load Control | |151 |0x0097 |Messages | |152 |0x0098 |Device Energy Management | |153 |0x0099 |Energy EVSE | +|154 |0x009A |Energy Calendar | |155 |0x009B |Energy Preference | |156 |0x009C |Power Topology | |157 |0x009D |Energy EVSE Mode | +|158 |0x009E |Water Heater Mode | |159 |0x009F |Device Energy Management Mode | |257 |0x0101 |Door Lock | |258 |0x0102 |Window Covering | +|336 |0x0150 |Service Area | |512 |0x0200 |Pump Configuration and Control | |513 |0x0201 |Thermostat | |514 |0x0202 |Fan Control | |516 |0x0204 |Thermostat User Interface Configuration | +|517 |0x0205 |Humidistat | |768 |0x0300 |Color Control | |769 |0x0301 |Ballast Configuration | |1024 |0x0400 |Illuminance Measurement | @@ -98,6 +105,10 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |1069 |0x042D |PM10 Concentration Measurement | |1070 |0x042E |Total Volatile Organic Compounds Concentration Measurement| |1071 |0x042F |Radon Concentration Measurement | +|1104 |0x0450 |Network Identity Management | +|1105 |0x0451 |Wi-Fi Network Management | +|1106 |0x0452 |Thread Border Router Management | +|1107 |0x0453 |Thread Network Directory | |1283 |0x0503 |Wake on LAN | |1284 |0x0504 |Channel | |1285 |0x0505 |Target Navigator | @@ -112,3 +123,5 @@ This file was **AUTOMATICALLY** generated by `python scripts/generate_spec_xml.p |1294 |0x050E |Account Login | |1295 |0x050F |Content Control | |1296 |0x0510 |Content App Observer | +|1872 |0x0750 |Ecosystem Information | +|1873 |0x0751 |Commissioner Control | diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter index 864e3115bc06a9..993ad36232572f 100644 --- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter +++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -437,6 +491,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -445,6 +502,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -455,6 +516,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -488,12 +553,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1294,7 +1370,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1420,11 +1497,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1530,8 +1602,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1575,10 +1646,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1597,8 +1664,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter index 294d3a19cb5772..391b5450b00993 100644 --- a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter +++ b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -437,6 +491,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -445,6 +502,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -455,6 +516,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -488,12 +553,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ 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 c4a159841dc100..c0c22fc0df0191 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 @@ -508,7 +508,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -524,12 +524,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -565,17 +595,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ @@ -1375,6 +1429,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1383,6 +1440,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1393,6 +1454,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1426,12 +1491,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -4092,6 +4168,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 allows a client to manage the power draw of a device. An example of such a client could be an Energy Management System (EMS) which controls an Energy Smart Appliance (ESA). */ provisional cluster DeviceEnergyManagement = 152 { revision 4; @@ -5073,7 +5207,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5199,11 +5334,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5309,8 +5439,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5354,10 +5483,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5376,8 +5501,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ @@ -7974,7 +8097,7 @@ endpoint 1 { ram attribute numberOfPositions default = 2; ram attribute currentPosition; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } server cluster FixedLabel { @@ -8434,6 +8557,24 @@ endpoint 1 { ram attribute clusterRevision default = 1; } + server cluster WaterHeaterManagement { + callback attribute heaterTypes; + callback attribute heatDemand; + callback attribute tankVolume; + callback attribute estimatedHeatRequired; + callback attribute tankPercentage; + callback attribute boostState; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command Boost; + handle command CancelBoost; + } + server cluster DeviceEnergyManagement { emits event PowerAdjustStart; emits event PowerAdjustEnd; @@ -8672,18 +8813,6 @@ endpoint 1 { ram attribute minSetpointDeadBand default = 0x19; ram attribute controlSequenceOfOperation default = 0x04; ram attribute systemMode default = 0x01; - callback attribute presetTypes; - callback attribute scheduleTypes; - ram attribute numberOfPresets default = 0; - ram attribute numberOfSchedules default = 0; - ram attribute numberOfScheduleTransitionPerDay default = 0xFF; - ram attribute activePresetHandle; - ram attribute activeScheduleHandle; - callback attribute presets; - callback attribute schedules; - ram attribute presetsSchedulesEditable; - ram attribute temperatureSetpointHoldPolicy default = 0; - ram attribute setpointHoldExpiryTimestamp; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -8869,8 +8998,10 @@ endpoint 1 { ram attribute occupancy; ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute holdTime default = 10; + callback attribute holdTimeLimits; + ram attribute featureMap default = 0x01; + ram attribute clusterRevision default = 5; } server cluster CarbonMonoxideConcentrationMeasurement { @@ -9338,8 +9469,10 @@ endpoint 2 { ram attribute occupancy; ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute holdTime default = 20; + callback attribute holdTimeLimits; + ram attribute featureMap default = 0x01; + ram attribute clusterRevision default = 5; } } endpoint 3 { @@ -9384,6 +9517,41 @@ endpoint 3 { ram attribute clusterRevision default = 2; } } +endpoint 4 { + 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; + } + + 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 { + ram attribute numberOfPositions default = 2; + ram attribute currentPosition default = 0; + ram attribute multiPressMax default = 3; + ram attribute featureMap default = 30; + 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 2ed20d53a62605..31b6a05057dc74 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 @@ -8029,7 +8029,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -13413,6 +13413,227 @@ } ] }, + { + "name": "Water Heater Management", + "code": 148, + "mfgCode": null, + "define": "WATER_HEATER_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "Boost", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CancelBoost", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "HeaterTypes", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "WaterHeaterTypeBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "HeatDemand", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "WaterHeaterDemandBitmap", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TankVolume", + "code": 2, + "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": "EstimatedHeatRequired", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "energy_mwh", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TankPercentage", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "percent", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BoostState", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "BoostStateEnum", + "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": "EventList", + "code": 65530, + "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": "Device Energy Management", "code": 152, @@ -14781,7 +15002,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14797,7 +15018,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14845,7 +15066,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14861,7 +15082,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14877,7 +15098,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14893,7 +15114,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14909,7 +15130,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -16416,8 +16637,8 @@ "reportableChange": 0 }, { - "name": "PresetTypes", - "code": 72, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", "type": "array", @@ -16432,8 +16653,8 @@ "reportableChange": 0 }, { - "name": "ScheduleTypes", - "code": 73, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -16448,264 +16669,56 @@ "reportableChange": 0 }, { - "name": "NumberOfPresets", - "code": 74, + "name": "EventList", + "code": 65530, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "NumberOfSchedules", - "code": 75, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "NumberOfScheduleTransitionPerDay", - "code": 77, + "name": "FeatureMap", + "code": 65532, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "bitmap32", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0xFF", + "defaultValue": "0x0023", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { - "name": "ActivePresetHandle", - "code": 78, - "mfgCode": null, - "side": "server", - "type": "octet_string", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ActiveScheduleHandle", - "code": 79, - "mfgCode": null, - "side": "server", - "type": "octet_string", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "Presets", - "code": 80, - "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": "Schedules", - "code": 81, - "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": "PresetsSchedulesEditable", - "code": 82, - "mfgCode": null, - "side": "server", - "type": "boolean", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "TemperatureSetpointHoldPolicy", - "code": 83, - "mfgCode": null, - "side": "server", - "type": "TemperatureSetpointHoldPolicyBitmap", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "SetpointHoldExpiryTimestamp", - "code": 84, - "mfgCode": null, - "side": "server", - "type": "epoch_s", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "QueuedPreset", - "code": 85, - "mfgCode": null, - "side": "server", - "type": "QueuedPresetStruct", - "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": "EventList", - "code": 65530, - "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": "0x0023", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, + "name": "ClusterRevision", + "code": 65533, "mfgCode": null, "side": "server", "type": "int16u", @@ -18984,6 +18997,38 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "HoldTime", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "10", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "HoldTimeLimits", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "HoldTimeLimitsStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -18994,7 +19039,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "0x01", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -19010,7 +19055,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -25013,6 +25058,38 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "HoldTime", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "20", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "HoldTimeLimits", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "HoldTimeLimitsStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -25023,7 +25100,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "0x01", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -25039,7 +25116,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -25510,6 +25587,417 @@ }, { "id": 5, + "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, + "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": "30", + "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 + } + ] + } + ] + }, + { + "id": 6, "name": "Anonymous Endpoint Type", "deviceTypeRef": { "code": 25, @@ -26050,12 +26538,20 @@ "parentEndpointIdentifier": null }, { - "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeName": "MA-genericswitch", "endpointTypeIndex": 4, "profileId": 259, + "endpointId": 4, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 5, + "profileId": 259, "endpointId": 65534, "networkId": 0, "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/all-clusters-app/all-clusters-common/include/WhmDelegate.h b/examples/all-clusters-app/all-clusters-common/include/WhmDelegate.h new file mode 100644 index 00000000000000..ad73239e77990d --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/WhmDelegate.h @@ -0,0 +1,270 @@ +/* + * + * 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 Clusters { +namespace WaterHeaterManagement { + +class WhmManufacturer; + +enum HeatingOp +{ + TurnHeatingOn, + TurnHeatingOff, + LeaveHeatingUnchanged +}; + +// This is an application level delegate to handle operational state commands according to the specific business logic. +class WaterHeaterManagementDelegate : public WaterHeaterManagement::Delegate +{ +public: + WaterHeaterManagementDelegate(EndpointId clustersEndpoint); + + virtual ~WaterHeaterManagementDelegate() = default; + + void SetWaterHeaterManagementInstance(WaterHeaterManagement::Instance & instance); + + void SetWhmManufacturer(WhmManufacturer & whmManufacturer); + + /********************************************************************************* + * + * Methods implementing the WaterHeaterManagement::Delegate interface + * + *********************************************************************************/ + + /** + * @brief Delegate should implement a handler to start boosting the water temperature as required. + * Upon receipt, the Water Heater SHALL transition into the BOOST state, which SHALL cause the + * water in the tank (or the TargetPercentage of the water, if included) to be heated towards + * the set point (or the TemporarySetpoint, if included), which in turn may cause a call for heat, + * even if the mode is OFF, or is TIMED and it is during one of the Off periods. + * + * @param duration Indicates the time period in seconds for which the BOOST state is activated before it + * automatically reverts to the previous mode (e.g. OFF, MANUAL or TIMED). + * @param oneShot Indicates whether the BOOST state should be automatically canceled once the hot water has + * first reached the set point temperature (or the TemporarySetpoint temperature, if specified) + * for the TargetPercentage (if specified). + * @param emergencyBoost Indicates that the consumer wants the water to be heated as quickly as practicable. + * This MAY cause multiple heat sources to be activated (e.g. a heat pump and direct + * electric heating element). + * @param temporarySetpoint Indicates the target temperature to which to heat the hot water for this Boost command. + * It SHALL be used instead of the normal set point temperature whilst the BOOST state is active. + * @param targetPercentage If the tank supports the TankPercent feature, this field indicates the amount of water + * that SHALL be heated by this Boost command before the heater is switched off. + * @param targetReheat If the tank supports the TankPercent feature, and the heating by this Boost command has ceased + * because the TargetPercentage of the water in the tank has been heated to the set point (or + * TemporarySetpoint if included), this field indicates the percentage to which the hot water in + * the tank SHALL be allowed to fall before again beginning to reheat it. + * + * @return Success if the boost command is accepted; otherwise the command SHALL be rejected with appropriate error. + */ + Protocols::InteractionModel::Status HandleBoost(uint32_t duration, Optional oneShot, Optional emergencyBoost, + Optional temporarySetpoint, Optional targetPercentage, + Optional targetReheat) override; + + /** + * @brief Delegate should implement a handler to cancel a boost command. + * Upon receipt, the Water Heater SHALL transition back from the BOOST state to the previous mode + * (e.g. OFF, MANUAL or TIMED). + * + * @return It should report SUCCESS if successful and FAILURE otherwise. + */ + Protocols::InteractionModel::Status HandleCancelBoost() override; + + // ------------------------------------------------------------------ + // Get attribute methods + BitMask GetHeaterTypes() override; + BitMask GetHeatDemand() override; + uint16_t GetTankVolume() override; + int64_t GetEstimatedHeatRequired() override; + Percent GetTankPercentage() override; + BoostStateEnum GetBoostState() override; + + // ------------------------------------------------------------------ + // Set attribute methods + void SetHeaterTypes(BitMask heaterTypes); + void SetHeatDemand(BitMask heatDemand); + void SetTankVolume(uint16_t tankVolume); + void SetEstimatedHeatRequired(int64_t estimatedHeatRequired); + void SetTankPercentage(Percent tankPercentage); + void SetBoostState(BoostStateEnum boostState); + + /********************************************************************************* + * + * WaterHeaterManagementDelegate specific methods + * + *********************************************************************************/ + + /** + * @brief Set the Water Header Mode and act accordingly. + * + * @param mode The Water Heater Mode (e.g. OFF, MANUAL or TIMED). + */ + Protocols::InteractionModel::Status SetWaterHeaterMode(uint8_t mode); + + /** + * @brief Set the water temperature of the tank + * + * @param waterTemperature The water temperature in 100th's Celsius + */ + void SetWaterTemperature(uint16_t waterTemperature); + + /** + * @brief Set the target water temperature of the tank + * + * @param targetWaterTemperature The water temperature in 100th's Celsius + */ + void SetTargetWaterTemperature(uint16_t targetWaterTemperature); + + /** + * @brief Determine whether the heating sources need to be turned on or off + */ + Protocols::InteractionModel::Status CheckIfHeatNeedsToBeTurnedOnOrOff(); + + /** + * @brief Static timer callback for when Boost timer expires. + */ + static void BoostTimerExpiry(System::Layer * systemLayer, void * delegate); + + /** + * @brief Object timer callback for when Boost timer expires. + */ + void HandleBoostTimerExpiry(); + + /** + * Determines whether the tank water temperature has reached the target temperature. + * + * @return Returns True is tank water temperature has reached the target temperature, False otherwise. + */ + bool HasWaterTemperatureReachedTarget() const; + + /** + * Simulates water being drawn from the water tank. + * + * @param percentageReplaced The % of water being replaced with water with a temperature of replacedWaterTemperature. + * @param replacedWaterTemperature The temperature of the percentageReplaced water. + */ + void DrawOffHotWater(chip::Percent percentageReplaced, uint16_t replacedWaterTemperature); + +private: + /** + * @brief Determine whether heating needs to be turned on or off or left as is. + * + * @param heatingOp[out] Set as determined whether heating needs to be turned on/off or left unchanged. + * + * @return Success if the heating operation could be determined otherwise returns with appropriate error. + */ + Protocols::InteractionModel::Status DetermineIfChangingHeatingState(HeatingOp & heatingOp); + +private: + /********************************************************************************* + * + * WaterHeaterManagementDelegate specific attributes + * + *********************************************************************************/ + + // Need the following so can determine which features are supported + WaterHeaterManagement::Instance * mpWhmInstance; + + // Pointer to the manufacturer specific object which understand the hardware + WhmManufacturer * mpWhmManufacturer; + + // Target water temperature in 100ths of a C + uint16_t mTargetWaterTemperature; + + // Actual water temperature in 100ths of a C + uint16_t mWaterTemperature; + + // The % of water at temperature mReplacedWaterTemperature + uint16_t mReplacedWaterTemperature; + + // Boost command parameters + + // This field SHALL indicate whether the BOOST state should be automatically canceled once the hot water has first reached the + // set point temperature (or the TemporarySetpoint temperature, if specified) for the TargetPercentage (if specified). + Optional mBoostOneShot; + + // This field indicates that the consumer wants the water to be heated as quickly as practicable. This MAY cause multiple heat + // sources to be activated (e.g. a heat pump and direct electric heating element). + Optional mBoostEmergencyBoost; + + // This field indicates the target temperature to which to heat the hot water for this Boost command. It SHALL be used instead + // of the normal set point temperature whilst the BOOST state is active. + Optional mBoostTemporarySetpoint; + + // If the tank supports the TankPercent feature, this field indicates the amount of water that SHALL be heated by this Boost + // command before the heater is switched off. This field is optional, however it SHALL be included if the TargetReheat field is + // included. + Optional mBoostTargetPercentage; + + // If the tank supports the TankPercent feature, and the heating by this Boost command has ceased because the TargetPercentage + // of the water in the tank has been heated to the set point (or TemporarySetpoint if included), this field indicates the + // percentage to which the hot water in the tank SHALL be allowed to fall before again beginning to reheat it. For example if + // the TargetPercentage was 80%, and the TargetReheat was 40%, then after initial heating to 80% hot water, the tank may have + // hot water drawn off until only 40% hot water remains. At this point the heater will begin to heat back up to 80% of hot + // water. If this field and the OneShot field were both omitted, heating would begin again after any water draw which reduced + // the TankPercentage below 80%. + Optional mBoostTargetReheat; + + // Track whether the water temperature has reached the water temperature specified in the boost command. Used in conjunction + // with the boost command boostTargetReheat parameter + bool mBoostTargetTemperatureReached; + + /********************************************************************************* + * + * Member variables implementing the WaterHeaterManagement::Delegate interface + * + *********************************************************************************/ + + // This attribute SHALL indicate the methods to call for heat that the controller supports. If a bit is set then the controller + // supports the corresponding method. + BitMask mHeaterTypes; + + // This attribute SHALL indicate if the controller is asking for heat. If a bit is set then the corresponding call for heat is + // active. + BitMask mHeatDemand; + + // This attribute SHALL indicate the volume of water that the hot water tank can hold (in units of Litres). This allows an + // energy management system to estimate the required heating energy needed to reach the target temperature. + uint16_t mTankVolume; + + // This attribute SHALL indicate the estimated heat energy needed to raise the water temperature to the target setpoint. This + // can be computed by taking the specific heat capacity of water (4182 J/kg °C) and by knowing the current temperature of the + // water, the tank volume and target temperature. + int64_t mEstimatedHeatRequired; + + // This attribute SHALL indicate an approximate level of hot water stored in the tank, which may help consumers understand the + // amount of hot water remaining in the tank. + Percent mTankPercentage; + + // This attribute SHALL indicate if the BOOST state, as triggered by a Boost command, is currently active. + BoostStateEnum mBoostState; +}; + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/WhmInstance.h b/examples/all-clusters-app/all-clusters-common/include/WhmInstance.h new file mode 100644 index 00000000000000..a776bd92b99534 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/WhmInstance.h @@ -0,0 +1,58 @@ +/* + * + * 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 + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { +using namespace chip::app::Clusters::WaterHeaterManagement; + +class WaterHeaterManagementInstance : public Instance +{ +public: + WaterHeaterManagementInstance(EndpointId aEndpointId, WaterHeaterManagementDelegate & aDelegate, Feature aFeature) : + WaterHeaterManagement::Instance(aEndpointId, aDelegate, aFeature) + { + mDelegate = &aDelegate; + } + + // Delete copy constructor and assignment operator. + WaterHeaterManagementInstance(const WaterHeaterManagementInstance &) = delete; + WaterHeaterManagementInstance(const WaterHeaterManagementInstance &&) = delete; + WaterHeaterManagementInstance & operator=(const WaterHeaterManagementInstance &) = delete; + + CHIP_ERROR Init(); + void Shutdown(); + + WaterHeaterManagementDelegate * GetDelegate() { return mDelegate; }; + +private: + WaterHeaterManagementDelegate * mDelegate; +}; + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/WhmMain.h b/examples/all-clusters-app/all-clusters-common/include/WhmMain.h new file mode 100644 index 00000000000000..21dc9d86519307 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/WhmMain.h @@ -0,0 +1,32 @@ +/* + * + * 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 + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { + +void WhmApplicationInit(); +void WhmApplicationShutdown(); + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/WhmManufacturer.h b/examples/all-clusters-app/all-clusters-common/include/WhmManufacturer.h new file mode 100644 index 00000000000000..d51e6a62f2021c --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/WhmManufacturer.h @@ -0,0 +1,139 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { + +/** + * The WhmManufacturer example class + * + * Helps with handling the test triggers. + */ + +class WhmManufacturer +{ +public: + WhmManufacturer(WaterHeaterManagementInstance * whmInstance) { mWhmInstance = whmInstance; } + + WaterHeaterManagementInstance * GetWhmInstance() { return mWhmInstance; } + + WaterHeaterManagementDelegate * GetWhmDelegate() + { + if (mWhmInstance) + { + return mWhmInstance->GetDelegate(); + } + + return nullptr; + } + + /** + * @brief Called at start up to apply hardware settings + */ + CHIP_ERROR Init(); + + /** + * @brief Called at shutdown + */ + CHIP_ERROR Shutdown(); + + /** + * @brief Called to determine which heating sources to use, + */ + BitMask DetermineHeatingSources(); + + /** + * @brief Turn the heating of the water tank on. + * + * @param emergencyBoost Indicates that the consumer wants the water to be heated as quickly as practicable. This MAY cause + * multiple heat sources to be activated (e.g. a heat pump and direct electric heating element). + * @return An error if a problem occurs turning the heating on + */ + Protocols::InteractionModel::Status TurnHeatingOn(bool emergencyBoost); + + /** + * @brief Turn the heating of the water tank off. + * + * @return An error if a problem occurs turning the heating off + */ + Protocols::InteractionModel::Status TurnHeatingOff(); + + /** + * @brief Called to handle a boost command. + * + * @param duration Indicates the time period in seconds for which the BOOST state is activated before it automatically reverts + * to the previous mode (e.g. OFF, MANUAL or TIMED). + * @param oneShot Indicates whether the BOOST state should be automatically canceled once the hot water has first reached the + * set point temperature (or the TemporarySetpoint temperature, if specified) for the TargetPercentage (if + * specified). + * @param emergencyBoost Indicates that the consumer wants the water to be heated as quickly as practicable. This MAY cause + * multiple heat sources to be activated (e.g. a heat pump and direct electric heating element). + * @param temporarySetpoint Indicates the target temperature to which to heat the hot water for this Boost command. It SHALL be + * used instead of the normal set point temperature whilst the BOOST state is active. + * @param targetPercentage If the tank supports the TankPercent feature, this field indicates the amount of water that SHALL be + * heated by this Boost command before the heater is switched off. + * @param targetReheat If the tank supports the TankPercent feature, and the heating by this Boost command has ceased because + * the TargetPercentage of the water in the tank has been heated to the set point (or TemporarySetpoint if + * included), this field indicates the percentage to which the hot water in the tank SHALL be allowed to fall before again + * beginning to reheat it. + * + * @return Success if the boost command is successful; otherwise return the appropriate error. + */ + Protocols::InteractionModel::Status BoostCommandStarted(uint32_t duration, Optional oneShot, + Optional emergencyBoost, Optional temporarySetpoint, + Optional targetPercentage, + Optional targetReheat); + + /** + * @brief Called when the Boost command has been cancelled. + * + * @return It should report SUCCESS if successful and FAILURE otherwise. + */ + Protocols::InteractionModel::Status BoostCommandCancelled(); + + /** + * @brief Called when a boost command has completed. + */ + void BoostCommandFinished(); + +private: + WaterHeaterManagementInstance * mWhmInstance; +}; + +/** @brief Helper function to return the singleton WhmManufacturer instance + * + * This is needed by the WhmManufacturer class to support TestEventTriggers + * which are called outside of any class context. This allows the WhmManufacturer + * class to return the relevant Delegate instance in which to invoke the test + * events on. + * + * This function is typically found in main.cpp or wherever the singleton is created. + */ +WhmManufacturer * GetWhmManufacturer(); + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/include/water-heater-mode.h b/examples/all-clusters-app/all-clusters-common/include/water-heater-mode.h old mode 100644 new mode 100755 diff --git a/examples/all-clusters-app/all-clusters-common/src/WhmDelegateImpl.cpp b/examples/all-clusters-app/all-clusters-common/src/WhmDelegateImpl.cpp new file mode 100644 index 00000000000000..0568e5c9c7d002 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/WhmDelegateImpl.cpp @@ -0,0 +1,461 @@ +/* + * + * 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 + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::WaterHeaterManagement; + +using Protocols::InteractionModel::Status; + +WaterHeaterManagementDelegate::WaterHeaterManagementDelegate(EndpointId clustersEndpoint) : + mpWhmInstance(nullptr), mpWhmManufacturer(nullptr), mWaterTemperature(0), mReplacedWaterTemperature(0), + mBoostTargetTemperatureReached(false), mTankVolume(0), mEstimatedHeatRequired(0), mTankPercentage(0), + mBoostState(BoostStateEnum::kInactive) +{} + +void WaterHeaterManagementDelegate::SetWaterHeaterManagementInstance(WaterHeaterManagement::Instance & instance) +{ + mpWhmInstance = &instance; +} + +void WaterHeaterManagementDelegate::SetWhmManufacturer(WhmManufacturer & whmManufacturer) +{ + mpWhmManufacturer = &whmManufacturer; +} + +/********************************************************************************* + * + * Methods implementing the WaterHeaterManagement::Delegate interace + * + *********************************************************************************/ + +BitMask WaterHeaterManagementDelegate::GetHeaterTypes() +{ + return mHeaterTypes; +} + +BitMask WaterHeaterManagementDelegate::GetHeatDemand() +{ + return mHeatDemand; +} + +uint16_t WaterHeaterManagementDelegate::GetTankVolume() +{ + return mTankVolume; +} + +int64_t WaterHeaterManagementDelegate::GetEstimatedHeatRequired() +{ + return mEstimatedHeatRequired; +} + +Percent WaterHeaterManagementDelegate::GetTankPercentage() +{ + return mTankPercentage; +} + +BoostStateEnum WaterHeaterManagementDelegate::GetBoostState() +{ + return mBoostState; +} + +void WaterHeaterManagementDelegate::SetHeaterTypes(BitMask heaterTypes) +{ + if (mHeaterTypes != heaterTypes) + { + mHeaterTypes = heaterTypes; + + MatterReportingAttributeChangeCallback(mEndpointId, WaterHeaterManagement::Id, Attributes::HeaterTypes::Id); + } +} + +void WaterHeaterManagementDelegate::SetHeatDemand(BitMask heatDemand) +{ + if (mHeatDemand != heatDemand) + { + mHeatDemand = heatDemand; + + MatterReportingAttributeChangeCallback(mEndpointId, WaterHeaterManagement::Id, Attributes::HeatDemand::Id); + } +} + +void WaterHeaterManagementDelegate::SetTankVolume(uint16_t tankVolume) +{ + if (mTankVolume != tankVolume) + { + mTankVolume = tankVolume; + + MatterReportingAttributeChangeCallback(mEndpointId, WaterHeaterManagement::Id, Attributes::TankVolume::Id); + } +} + +void WaterHeaterManagementDelegate::SetEstimatedHeatRequired(int64_t estimatedHeatRequired) +{ + if (mEstimatedHeatRequired != estimatedHeatRequired) + { + mEstimatedHeatRequired = estimatedHeatRequired; + + MatterReportingAttributeChangeCallback(mEndpointId, WaterHeaterManagement::Id, Attributes::EstimatedHeatRequired::Id); + } +} + +void WaterHeaterManagementDelegate::SetTankPercentage(Percent tankPercentage) +{ + if (mpWhmInstance != nullptr && mpWhmInstance->HasFeature(Feature::kTankPercent)) + { + if (mTankPercentage != tankPercentage) + { + mTankPercentage = tankPercentage; + + CheckIfHeatNeedsToBeTurnedOnOrOff(); + + MatterReportingAttributeChangeCallback(mEndpointId, WaterHeaterManagement::Id, Attributes::TankPercentage::Id); + } + } +} + +void WaterHeaterManagementDelegate::SetBoostState(BoostStateEnum boostState) +{ + if (mBoostState != boostState) + { + mBoostState = boostState; + + MatterReportingAttributeChangeCallback(mEndpointId, WaterHeaterManagement::Id, Attributes::BoostState::Id); + } +} + +/** + * @brief Handles the boost command + * + * Upon receipt, the Water Heater SHALL transition into the BOOST state, which SHALL cause the water in the tank (or + * the TargetPercentage of the water, if included) to be heated towards the set point (or the TemporarySetpoint, if + * included), which in turn may cause a call for heat, even if the mode is OFF, or is TIMED and it is during one of + * the Off periods. + */ +Status WaterHeaterManagementDelegate::HandleBoost(uint32_t durationS, Optional oneShot, Optional emergencyBoost, + Optional temporarySetpoint, Optional targetPercentage, + Optional targetReheat) +{ + Status status = Status::Success; + + ChipLogProgress(AppServer, "HandleBoost"); + + // Keep track of the boost command parameters + mBoostOneShot = oneShot; + mBoostEmergencyBoost = emergencyBoost; + mBoostTemporarySetpoint = temporarySetpoint; + mBoostTargetPercentage = targetPercentage; + mBoostTargetReheat = targetReheat; + + mBoostTargetTemperatureReached = false; + + // If a timer is running, cancel it so we can start a new boost command with the new duration + if (mBoostState == BoostStateEnum::kActive) + { + DeviceLayer::SystemLayer().CancelTimer(BoostTimerExpiry, this); + } + + CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(durationS), BoostTimerExpiry, this); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "HandleBoost: Unable to start a Boost timer: %" CHIP_ERROR_FORMAT, err.Format()); + + // Not a lot we can do -> just set the boost state to inactive + SetBoostState(BoostStateEnum::kInactive); + + return Status::Failure; + } + + // Now running a boost command + SetBoostState(BoostStateEnum::kActive); + + if (mpWhmManufacturer != nullptr) + { + status = mpWhmManufacturer->BoostCommandStarted(durationS, oneShot, emergencyBoost, temporarySetpoint, targetPercentage, + targetReheat); + } + else + { + status = Status::InvalidInState; + ChipLogError(AppServer, "HandleBoost: mpWhmManufacturer == nullptr"); + } + + if (status == Status::Success) + { + // See if the heat needs to be turned on or off as a result of this boost command + status = CheckIfHeatNeedsToBeTurnedOnOrOff(); + } + + return status; +} + +void WaterHeaterManagementDelegate::BoostTimerExpiry(System::Layer * systemLayer, void * delegate) +{ + WaterHeaterManagementDelegate * dg = static_cast(delegate); + + dg->HandleBoostTimerExpiry(); +} + +/** + * @brief Timer for handling the completion of a boost command + */ +void WaterHeaterManagementDelegate::HandleBoostTimerExpiry() +{ + ChipLogError(AppServer, "HandleBoostTimerExpiry"); + + // The PowerAdjustment is no longer in progress + SetBoostState(BoostStateEnum::kInactive); + + if (mpWhmManufacturer != nullptr) + { + mpWhmManufacturer->BoostCommandFinished(); + } + else + { + ChipLogError(AppServer, "HandleBoostTimerExpiry: mpWhmManufacturer == nullptr"); + } + + CheckIfHeatNeedsToBeTurnedOnOrOff(); +} + +/** + * @brief Cancels a boost command + * + * Upon receipt, the Water Heater SHALL transition back from the BOOST state to the previous mode (e.g. OFF, MANUAL or TIMED). + */ +Status WaterHeaterManagementDelegate::HandleCancelBoost() +{ + ChipLogProgress(AppServer, "HandleCancelBoost"); + + if (mBoostState == BoostStateEnum::kActive) + { + SetBoostState(BoostStateEnum::kInactive); + mBoostEmergencyBoost.ClearValue(); + + DeviceLayer::SystemLayer().CancelTimer(BoostTimerExpiry, this); + + VerifyOrReturnValue(mpWhmManufacturer != nullptr, Status::InvalidInState); + + Status status = mpWhmManufacturer->BoostCommandCancelled(); + VerifyOrReturnValue(status == Status::Success, status); + + status = CheckIfHeatNeedsToBeTurnedOnOrOff(); + VerifyOrReturnValue(status == Status::Success, status); + } + + return Status::Success; +} + +/********************************************************************************* + * + * WaterHeaterManagementDelegate specific methods + * + *********************************************************************************/ + +void WaterHeaterManagementDelegate::SetWaterTemperature(uint16_t waterTemperature) +{ + mWaterTemperature = waterTemperature; + + if (mpWhmInstance != nullptr && mpWhmInstance->HasFeature(Feature::kTankPercent)) + { + mTankPercentage = 100; + } + + // See if the heat needs to be turned on or off + CheckIfHeatNeedsToBeTurnedOnOrOff(); +} + +void WaterHeaterManagementDelegate::SetTargetWaterTemperature(uint16_t targetWaterTemperature) +{ + mTargetWaterTemperature = targetWaterTemperature; + + // See if the heat needs to be turned on or off + CheckIfHeatNeedsToBeTurnedOnOrOff(); +} + +void WaterHeaterManagementDelegate::DrawOffHotWater(Percent percentageReplaced, uint16_t replacedWaterTemperature) +{ + // Only supported in the kTankPercent is supported. + // Replaces percentageReplaced% of the water in the tank with water of a temperature replacedWaterTemperature + if (mpWhmInstance != nullptr && mpWhmInstance->HasFeature(Feature::kTankPercent)) + { + // See if all of the water has now been replaced with replacedWaterTemperature + if (mTankPercentage >= percentageReplaced) + { + mTankPercentage = static_cast(mTankPercentage - percentageReplaced); + } + else + { + mTankPercentage = 0; + } + + mReplacedWaterTemperature = replacedWaterTemperature; + + CheckIfHeatNeedsToBeTurnedOnOrOff(); + } +} + +bool WaterHeaterManagementDelegate::HasWaterTemperatureReachedTarget() const +{ + // Determine the target temperature. If a boost command is in progress and has a mBoostTemporarySetpoint value use that as the + // target temperature. + // Note, in practise the actual heating is likely to be controlled by the thermostat's occupiedHeatingSetpoint most of the + // time, and the TemporarySetpoint (if not null) would be overiding the thermostat's occupiedHeatingSetpoint. + // However, this code doesn't rely upon the thermostat cluster. + uint16_t targetTemperature = (mBoostState == BoostStateEnum::kActive && mBoostTemporarySetpoint.HasValue()) + ? static_cast(mBoostTemporarySetpoint.Value()) + : mTargetWaterTemperature; + + VerifyOrReturnValue(mWaterTemperature >= targetTemperature, false); + + if (mBoostState == BoostStateEnum::kActive) + { + if (mBoostTargetTemperatureReached && mBoostTargetReheat.HasValue()) + { + // If the tank supports the TankPercent feature, and the heating by this Boost command has ceased because the + // TargetPercentage of the water in the tank has been heated to the set point (or TemporarySetpoint if included), + // mBoostTargetReheat indicates the percentage to which the hot water in the tank SHALL be allowed to fall before + // again beginning to reheat it. + // + // For example if the TargetPercentage was 80%, and the TargetReheat was 40%, then after initial heating to 80% hot + // water, the tank may have hot water drawn off until only 40% hot water remains. At this point the heater will begin to + // heat back up to 80% of hot water. If this field and the OneShot field were both omitted, heating would begin again + // after any water draw which reduced the TankPercentage below 80%. + + // If this field is included then the TargetPercentage field SHALL also be included, and the OneShot excluded. + VerifyOrReturnValue(mTankPercentage >= mBoostTargetReheat.Value(), false); + } + else if (mBoostTargetPercentage.HasValue()) + { + // If tank percentage is supported AND the targetPercentage.HasValue() then use target percentage to heat up. + VerifyOrReturnValue(mTankPercentage >= mBoostTargetPercentage.Value(), false); + } + } + + // Must have reached the right temperature + return true; +} + +Status WaterHeaterManagementDelegate::CheckIfHeatNeedsToBeTurnedOnOrOff() +{ + VerifyOrReturnError(mpWhmManufacturer != nullptr, Status::InvalidInState); + + HeatingOp heatingOp = HeatingOp::LeaveHeatingUnchanged; + + Status status = DetermineIfChangingHeatingState(heatingOp); + + VerifyOrReturnError(status == Status::Success, status); + + if (heatingOp == HeatingOp::TurnHeatingOn) + { + status = mpWhmManufacturer->TurnHeatingOn(mBoostEmergencyBoost.HasValue() ? mBoostEmergencyBoost.Value() : false); + } + else if (heatingOp == HeatingOp::TurnHeatingOff) + { + // If running a boost command with the oneShot parameter and turning heat off, then must have + // reached the boost command target temperature -> that's the boost command complete. + if (mBoostState == BoostStateEnum::kActive && mBoostOneShot.HasValue() && mBoostOneShot.Value()) + { + SetBoostState(BoostStateEnum::kInactive); + + DeviceLayer::SystemLayer().CancelTimer(BoostTimerExpiry, this); + + mBoostEmergencyBoost.ClearValue(); + + status = mpWhmManufacturer->BoostCommandCancelled(); + } + + // Turn the heating off + status = mpWhmManufacturer->TurnHeatingOff(); + } + + return status; +} + +Status WaterHeaterManagementDelegate::DetermineIfChangingHeatingState(HeatingOp & heatingOp) +{ + heatingOp = LeaveHeatingUnchanged; + + if (!HasWaterTemperatureReachedTarget()) + { + VerifyOrReturnError(WaterHeaterMode::Instance() != nullptr, Status::InvalidInState); + + uint8_t mode = WaterHeaterMode::Instance()->GetCurrentMode(); + + // The water in the tank is not at the target temperature. See if heating is currently off + if (mHeatDemand.Raw() == 0) + { + // Need to track whether the water temperature has reached the target temperature for the boost + // command when a oneShot option has been applied. + if (mBoostState == BoostStateEnum::kActive) + { + mBoostTargetTemperatureReached = false; + } + + // If a boost command is in progress or in manual mode, find a heating source and "turn it on". + if (mBoostState == BoostStateEnum::kActive || mode == WaterHeaterMode::kModeManual) + { + heatingOp = HeatingOp::TurnHeatingOn; + } + } + else if (mBoostState == BoostStateEnum::kInactive && mode == WaterHeaterMode::kModeOff) + { + // The water temperature is not at the target temperature but there is no boost command in progress and the mode is Off + // so need to ensure the heating is turned off. + ChipLogError(AppServer, "DetermineIfChangingHeatingState turning heating off due to no boost cmd and kModeOff"); + + heatingOp = HeatingOp::TurnHeatingOff; + } + } + else if (mHeatDemand.Raw() != 0) + { + // The water in the tank has reached the target temperature - need to turn the heating off + heatingOp = HeatingOp::TurnHeatingOff; + + // If a boost command is in progress, record that the target temperature has been reached. + mBoostTargetTemperatureReached = (mBoostState == BoostStateEnum::kActive); + } + + return Status::Success; +} + +Status WaterHeaterManagementDelegate::SetWaterHeaterMode(uint8_t modeValue) +{ + VerifyOrReturnError(WaterHeaterMode::Instance() != nullptr, Status::InvalidInState); + + if (!WaterHeaterMode::Instance()->IsSupportedMode(modeValue)) + { + ChipLogError(AppServer, "SetWaterHeaterMode bad mode"); + return Status::ConstraintError; + } + + Status status = WaterHeaterMode::Instance()->UpdateCurrentMode(modeValue); + if (status != Status::Success) + { + ChipLogError(AppServer, "SetWaterHeaterMode updateMode failed 0x%02x", to_underlying(status)); + return status; + } + + return CheckIfHeatNeedsToBeTurnedOnOrOff(); +} diff --git a/examples/all-clusters-app/all-clusters-common/src/WhmInstance.cpp b/examples/all-clusters-app/all-clusters-common/src/WhmInstance.cpp new file mode 100644 index 00000000000000..9d4ad58fefd976 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/WhmInstance.cpp @@ -0,0 +1,34 @@ +/* + * + * 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 + +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::WaterHeaterManagement; + +CHIP_ERROR WaterHeaterManagementInstance::Init() +{ + ChipLogDetail(AppServer, "WaterHeaterManagementInstance::Init()"); + return Instance::Init(); +} + +void WaterHeaterManagementInstance::Shutdown() +{ + Instance::Shutdown(); +} diff --git a/examples/all-clusters-app/all-clusters-common/src/WhmMain.cpp b/examples/all-clusters-app/all-clusters-common/src/WhmMain.cpp new file mode 100644 index 00000000000000..ea59fef2d095f5 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/WhmMain.cpp @@ -0,0 +1,194 @@ +/* + * + * 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 + +static constexpr int WHM_ENDPOINT = 1; + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters; + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { + +static std::unique_ptr gWhmDelegate; +static std::unique_ptr gWhmInstance; + +static std::unique_ptr gWhmManufacturer; + +WhmManufacturer * GetWhmManufacturer() +{ + return gWhmManufacturer.get(); +} + +/* + * @brief Creates a Delegate and Instance for Water Heater Management cluster + * + * The Instance is a container around the Delegate, so + * create the Delegate first, then wrap it in the Instance + * Then call the Instance->Init() to register the attribute and command handlers + */ +CHIP_ERROR WhmInit() +{ + CHIP_ERROR err; + + if (gWhmDelegate || gWhmInstance) + { + ChipLogError(AppServer, "WaterHeaterManager Instance or Delegate already exist."); + return CHIP_ERROR_INCORRECT_STATE; + } + + gWhmDelegate = std::make_unique(WHM_ENDPOINT); + if (!gWhmDelegate) + { + ChipLogError(AppServer, "Failed to allocate memory for WaterHeaterManagementDelegate"); + return CHIP_ERROR_NO_MEMORY; + } + + /* Manufacturer may optionally not support all features, commands & attributes */ + gWhmInstance = std::make_unique( + EndpointId(WHM_ENDPOINT), *gWhmDelegate, BitMask(Feature::kEnergyManagement, Feature::kTankPercent)); + if (!gWhmInstance) + { + ChipLogError(AppServer, "Failed to allocate memory for WaterHeaterManagementInstance"); + gWhmDelegate.reset(); + return CHIP_ERROR_NO_MEMORY; + } + + /* Register Attribute & Command handlers */ + err = gWhmInstance->Init(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "gWhmInstance->Init failed %s", chip::ErrorStr(err)); + gWhmInstance.reset(); + gWhmDelegate.reset(); + return err; + } + + gWhmDelegate->SetWaterHeaterManagementInstance(*gWhmInstance); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WhmShutdown() +{ + /* Do this in the order Instance first, then delegate + * Ensure we call the Instance->Shutdown to free attribute & command handlers first + */ + if (gWhmInstance) + { + /* Deregister attribute & command handlers */ + gWhmInstance->Shutdown(); + gWhmInstance.reset(); + } + + if (gWhmDelegate) + { + gWhmDelegate.reset(); + } + + return CHIP_NO_ERROR; +} + +/* + * @brief Creates a WhmManufacturer class to hold the Whm cluster + * + * The Instance is a container around the Delegate, so + * create the Delegate first, then wrap it in the Instance + * Then call the Instance->Init() to register the attribute and command handlers + */ +CHIP_ERROR WhmManufacturerInit() +{ + CHIP_ERROR err; + + if (gWhmManufacturer) + { + ChipLogError(AppServer, "WhmManufacturer already exist."); + return CHIP_ERROR_INCORRECT_STATE; + } + + /* Now create WhmManufacturer */ + gWhmManufacturer = std::make_unique(gWhmInstance.get()); + if (!gWhmManufacturer) + { + ChipLogError(AppServer, "Failed to allocate memory for WhmManufacturer"); + return CHIP_ERROR_NO_MEMORY; + } + + /* Call Manufacturer specific init */ + err = gWhmManufacturer->Init(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Init failed on gWhmManufacturer"); + gWhmManufacturer.reset(); + return err; + } + + // Let the WhmDelegate know about the WhmManufacturer object. + gWhmDelegate->SetWhmManufacturer(*gWhmManufacturer); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WhmManufacturerShutdown() +{ + if (gWhmManufacturer) + { + /* Shutdown the WhmManufacturer */ + gWhmManufacturer->Shutdown(); + gWhmManufacturer.reset(); + } + + return CHIP_NO_ERROR; +} + +void WhmApplicationInit() +{ + if (WhmInit() != CHIP_NO_ERROR) + { + return; + } + + /* Do this last so that the instances for other clusters can be wrapped inside */ + if (WhmManufacturerInit() != CHIP_NO_ERROR) + { + WhmShutdown(); + return; + } +} + +void WhmApplicationShutdown() +{ + /* Shutdown in reverse order that they were created */ + WhmManufacturerShutdown(); +} + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/all-clusters-common/src/WhmManufacturer.cpp b/examples/all-clusters-app/all-clusters-common/src/WhmManufacturer.cpp new file mode 100644 index 00000000000000..dd8452a5c816ca --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/WhmManufacturer.cpp @@ -0,0 +1,286 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include + +using namespace chip; +using namespace chip::app::Clusters::WaterHeaterManagement; + +using Protocols::InteractionModel::Status; + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { + +CHIP_ERROR WhmManufacturer::Init() +{ + WaterHeaterManagementDelegate * dg = GetWhmManufacturer()->GetWhmDelegate(); + if (dg == nullptr) + { + ChipLogError(AppServer, "WhmDelegate is not initialized"); + return CHIP_ERROR_UNINITIALIZED; + } + + dg->SetHeaterTypes(BitMask(WaterHeaterTypeBitmap::kImmersionElement1)); + dg->SetHeatDemand(BitMask(WaterHeaterDemandBitmap::kImmersionElement1)); + dg->SetEstimatedHeatRequired(10000); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WhmManufacturer::Shutdown() +{ + return CHIP_NO_ERROR; +} + +BitMask WhmManufacturer::DetermineHeatingSources() +{ + WaterHeaterManagementDelegate * dg = GetWhmManufacturer()->GetWhmDelegate(); + if (dg == nullptr) + { + ChipLogError(AppServer, "WhmDelegate is not initialized"); + return BitMask(0); + } + + // A list of valid heaterTypes + uint8_t waterHeaterTypeValues[] = { + static_cast(WaterHeaterTypeBitmap::kImmersionElement1), + static_cast(WaterHeaterTypeBitmap::kImmersionElement2), + static_cast(WaterHeaterTypeBitmap::kHeatPump), + static_cast(WaterHeaterTypeBitmap::kBoiler), + static_cast(WaterHeaterTypeBitmap::kOther), + }; + + // The corresponding list of valid headerDemands + uint8_t waterHeaterDemandValues[] = { + static_cast(WaterHeaterDemandBitmap::kImmersionElement1), + static_cast(WaterHeaterDemandBitmap::kImmersionElement2), + static_cast(WaterHeaterDemandBitmap::kHeatPump), + static_cast(WaterHeaterDemandBitmap::kBoiler), + static_cast(WaterHeaterDemandBitmap::kOther), + }; + + // Iterate across the valid waterHeaterTypes seeing which heating sources are available based on heaterTypes. + // Set the corresponding bit in the heaterDemand bitmap. + BitMask heaterTypes = dg->GetHeaterTypes(); + + uint8_t heaterDemandMask = 0; + for (uint16_t idx = 0; idx < static_cast(sizeof(waterHeaterTypeValues) / sizeof(waterHeaterTypeValues[0])); idx++) + { + // Is this heating source being used? + if (heaterTypes.Raw() & waterHeaterTypeValues[idx]) + { + heaterDemandMask |= waterHeaterDemandValues[idx]; + } + } + + return BitMask(heaterDemandMask); +} + +Status WhmManufacturer::TurnHeatingOn(bool emergencyBoost) +{ + Status status = Status::Success; + + ChipLogProgress(AppServer, "WhmManufacturer::TurnHeatingOn"); + + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + if (emergencyBoost) + { + // emergencyBoost that the consumer wants the water to be heated as quickly as practicable. + // Thus, cause multiple heat sources to be activated + dg->SetHeatDemand(BitMask(WaterHeaterDemandBitmap::kImmersionElement1, + WaterHeaterDemandBitmap::kImmersionElement2)); + } + else + { + dg->SetHeatDemand(BitMask(WaterHeaterDemandBitmap::kImmersionElement1)); + } + + return status; +} + +Status WhmManufacturer::TurnHeatingOff() +{ + Status status = Status::Success; + + ChipLogProgress(AppServer, "WhmManufacturer::TurnHeatingOff"); + + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + dg->SetHeatDemand(BitMask(0)); + + return status; +} + +Status WhmManufacturer::BoostCommandStarted(uint32_t duration, Optional oneShot, Optional emergencyBoost, + Optional temporarySetpoint, Optional targetPercentage, + Optional targetReheat) +{ + return Status::Success; +} + +Status WhmManufacturer::BoostCommandCancelled() +{ + return Status::Success; +} + +void WhmManufacturer::BoostCommandFinished() {} + +WaterHeaterManagementDelegate * GetWhmDelegate() +{ + WhmManufacturer * mn = GetWhmManufacturer(); + VerifyOrDieWithMsg(mn != nullptr, AppServer, "WhmManufacturer is null"); + + WaterHeaterManagementDelegate * wg = mn->GetWhmDelegate(); + VerifyOrDieWithMsg(wg != nullptr, AppServer, "WhmDelegate is null"); + + return wg; +} + +void SetTestEventTrigger_BasicInstallationTestEvent() +{ + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + // Simulate installation in a 100L tank full of water at 20C, with a target temperature of 60C, in OFF mode + dg->SetTankVolume(100); + dg->SetTargetWaterTemperature(6000); + dg->SetHeaterTypes(BitMask(WaterHeaterTypeBitmap::kImmersionElement1)); + dg->DrawOffHotWater(100, 2000); +} + +void SetTestEventTrigger_BasicInstallationTestEventClear() {} + +void SetTestEventTrigger_WaterTemperature20CTestEvent() +{ + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + // Simulate 100% of the water in the tank being at 20C + dg->SetWaterTemperature(2000); +} + +void SetTestEventTrigger_WaterTemperature61CTestEvent() +{ + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + // Simulate 100% of the water in the tank being at 61C + dg->SetWaterTemperature(6100); +} + +void SetTestEventTrigger_WaterTemperature66CTestEvent() +{ + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + // Simulate 100% of the water in the tank being at 66C + dg->SetWaterTemperature(6600); +} + +void SetTestEventTrigger_ManualModeTestEvent() +{ + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + // Simulate the Water Heater Mode being set to MANUAL + Status status = dg->SetWaterHeaterMode(WaterHeaterMode::kModeManual); + if (status != Status::Success) + { + ChipLogError(Zcl, "SetTestEventTrigger_OffModeTestEvent setting mode -> KModeManual failed 0x%02x", to_underlying(status)); + } +} + +void SetTestEventTrigger_OffModeTestEvent() +{ + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + // Simulate the Water Heater Mode being set to OFF + Status status = dg->SetWaterHeaterMode(WaterHeaterMode::kModeOff); + if (status != Status::Success) + { + ChipLogError(Zcl, "SetTestEventTrigger_OffModeTestEvent setting mode -> KModeOff failed 0x%02x", to_underlying(status)); + } +} + +void SetTestEventTrigger_DrawOffHotWaterTestEvent() +{ + WaterHeaterManagementDelegate * dg = GetWhmDelegate(); + + // Simulate drawing off 25% of the tank volume of hot water, replaced with water at 20C + dg->DrawOffHotWater(25, 2000); +} + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip + +using namespace chip::app::Clusters::WaterHeaterManagement; + +bool HandleWaterHeaterManagementTestEventTrigger(uint64_t eventTrigger) +{ + WaterHeaterManagementTrigger trigger = static_cast(eventTrigger); + + switch (trigger) + { + case WaterHeaterManagementTrigger::kBasicInstallationTestEvent: + ChipLogProgress(Support, + "[Whm::kBasicInstallationTestEvent] => Simulate installation in a 100L tank full of water at 20C, with a " + "target temperature of 60C, in OFF mode"); + SetTestEventTrigger_BasicInstallationTestEvent(); + break; + case WaterHeaterManagementTrigger::kBasicInstallationTestEventClear: + ChipLogProgress(Support, "[Whm::kBasicInstallationTestEventClear] => End simulation of installation"); + SetTestEventTrigger_BasicInstallationTestEventClear(); + break; + case WaterHeaterManagementTrigger::kWaterTemperature20CTestEvent: + ChipLogProgress(Support, "[Whm::kWaterTemperature20CTestEvent] => Simulate 100%% of the water in the tank being at 20C"); + SetTestEventTrigger_WaterTemperature20CTestEvent(); + break; + case WaterHeaterManagementTrigger::kWaterTemperature61CTestEvent: + ChipLogProgress(Support, "[Whm::kWaterTemperature61CTestEvent] => Simulate 100%% of the water in the tank being at 61C"); + SetTestEventTrigger_WaterTemperature61CTestEvent(); + break; + case WaterHeaterManagementTrigger::kWaterTemperature66CTestEvent: + ChipLogProgress(Support, "[Whm::kWaterTemperature66CTestEvent] => Simulate 100%% of the water in the tank being at 66C"); + SetTestEventTrigger_WaterTemperature66CTestEvent(); + break; + case WaterHeaterManagementTrigger::kManualModeTestEvent: + ChipLogProgress(Support, "[Whm::kManualModeTestEvent] => Simulate the Water Heater Mode being set to MANUAL"); + SetTestEventTrigger_ManualModeTestEvent(); + break; + case WaterHeaterManagementTrigger::kOffModeTestEvent: + ChipLogProgress(Support, "[Whm::kOffModeTestEvent] => Simulate the Water Heater Mode being set to OFF"); + SetTestEventTrigger_OffModeTestEvent(); + break; + case WaterHeaterManagementTrigger::kDrawOffHotWaterTestEvent: + ChipLogProgress(Support, + "[Whm::kDrawOffHotWaterTestEvent] => Simulate drawing off 25%% of the tank volume of hot water, replaced " + "with water at 20C"); + SetTestEventTrigger_DrawOffHotWaterTestEvent(); + break; + default: + return false; + } + + return true; +} diff --git a/examples/all-clusters-app/all-clusters-common/src/occupancy-sensing-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/occupancy-sensing-stub.cpp new file mode 100644 index 00000000000000..dcbb90ff659bcb --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/occupancy-sensing-stub.cpp @@ -0,0 +1,57 @@ +/* + * + * 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 +#include +#include +#include + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::OccupancySensing; +using namespace chip::app::Clusters::OccupancySensing::Structs; +using namespace chip::DeviceLayer; + +using chip::Protocols::InteractionModel::Status; + +static std::unique_ptr + gAttrAccess[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT]; + +void emberAfOccupancySensingClusterInitCallback(EndpointId endpointId) +{ + VerifyOrDie(!gAttrAccess[endpointId]); + + gAttrAccess[endpointId] = std::make_unique( + BitMask(OccupancySensing::Feature::kOther)); + + OccupancySensing::Structs::HoldTimeLimitsStruct::Type holdTimeLimits = { + .holdTimeMin = 1, + .holdTimeMax = 300, + .holdTimeDefault = 10, + }; + + uint16_t holdTime = 10; + + if (gAttrAccess[endpointId]) + { + gAttrAccess[endpointId]->Init(); + + SetHoldTimeLimits(endpointId, holdTimeLimits); + + SetHoldTime(endpointId, holdTime); + } +} diff --git a/examples/all-clusters-app/all-clusters-common/src/water-heater-mode.cpp b/examples/all-clusters-app/all-clusters-common/src/water-heater-mode.cpp old mode 100644 new mode 100755 diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp index 3c42eb1dd6a32e..d620731e93dc5c 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp @@ -56,22 +56,23 @@ bool HasNumericField(Json::Value & jsonValue, const std::string & field) } /** - * Named pipe handler for simulated long press on an action switch. + * Named pipe handler for simulated long press * * Usage example: - * echo '{"Name": "SimulateActionSwitchLongPress", "EndpointId": 3, "ButtonId": 1, "LongPressDelayMillis": 800, + * echo '{"Name": "SimulateLongPress", "EndpointId": 3, "ButtonId": 1, "LongPressDelayMillis": 800, * "LongPressDurationMillis": 1000}' > /tmp/chip_all_clusters_fifo_1146610 * * JSON Arguments: - * - "Name": Must be "SimulateActionSwitchLongPress" - * - "EndpointId": number of endpoint having a switch cluster + * - "Name": Must be "SimulateLongPress" + * - "EndpointId": ID of endpoint having a switch cluster * - "ButtonId": switch position in the switch cluster for "down" button (not idle) * - "LongPressDelayMillis": Time in milliseconds before the LongPress * - "LongPressDurationMillis": Total duration in milliseconds from start of the press to LongRelease + * - "FeatureMap": The feature map to simulate * * @param jsonValue - JSON payload from named pipe */ -void HandleSimulateActionSwitchLongPress(Json::Value & jsonValue) +void HandleSimulateLongPress(Json::Value & jsonValue) { if (sButtonSimulatorInstance != nullptr) { @@ -83,13 +84,14 @@ void HandleSimulateActionSwitchLongPress(Json::Value & jsonValue) bool hasButtonId = HasNumericField(jsonValue, "ButtonId"); bool hasLongPressDelayMillis = HasNumericField(jsonValue, "LongPressDelayMillis"); bool hasLongPressDurationMillis = HasNumericField(jsonValue, "LongPressDurationMillis"); - if (!hasEndpointId || !hasButtonId || !hasLongPressDelayMillis || !hasLongPressDurationMillis) + bool hasFeatureMap = HasNumericField(jsonValue, "FeatureMap"); + if (!hasEndpointId || !hasButtonId || !hasLongPressDelayMillis || !hasLongPressDurationMillis || !hasFeatureMap) { std::string inputJson = jsonValue.toStyledString(); - ChipLogError( - NotSpecified, - "Missing or invalid value for one of EndpointId, ButtonId, LongPressDelayMillis or LongPressDurationMillis in %s", - inputJson.c_str()); + ChipLogError(NotSpecified, + "Missing or invalid value for one of EndpointId, ButtonId, LongPressDelayMillis, LongPressDurationMillis or " + "FeatureMap in %s", + inputJson.c_str()); return; } @@ -97,6 +99,7 @@ void HandleSimulateActionSwitchLongPress(Json::Value & jsonValue) uint8_t buttonId = static_cast(jsonValue["ButtonId"].asUInt()); System::Clock::Milliseconds32 longPressDelayMillis{ static_cast(jsonValue["LongPressDelayMillis"].asUInt()) }; System::Clock::Milliseconds32 longPressDurationMillis{ static_cast(jsonValue["LongPressDurationMillis"].asUInt()) }; + uint32_t featureMap = static_cast(jsonValue["FeatureMap"].asUInt()); auto buttonSimulator = std::make_unique(); bool success = buttonSimulator->SetMode(ButtonEventsSimulator::Mode::kModeLongPress) @@ -105,6 +108,7 @@ void HandleSimulateActionSwitchLongPress(Json::Value & jsonValue) .SetIdleButtonId(0) .SetPressedButtonId(buttonId) .SetEndpointId(endpointId) + .SetFeatureMap(featureMap) .Execute([]() { sButtonSimulatorInstance.reset(); }); if (!success) @@ -117,23 +121,25 @@ void HandleSimulateActionSwitchLongPress(Json::Value & jsonValue) } /** - * Named pipe handler for simulated multi-press on an action switch. + * Named pipe handler for simulated multi-press. * * Usage example: - * echo '{"Name": "SimulateActionSwitchMultiPress", "EndpointId": 3, "ButtonId": 1, "MultiPressPressedTimeMillis": 100, - * "MultiPressReleasedTimeMillis": 350, "MultiPressNumPresses": 2}' > /tmp/chip_all_clusters_fifo_1146610 + * echo '{"Name": "SimulateMultiPress", "EndpointId": 3, "ButtonId": 1, "MultiPressPressedTimeMillis": 100, + * "MultiPressReleasedTimeMillis": 350, "MultiPressNumPresses": 2, "FeatureMap": 58}' > /tmp/chip_all_clusters_fifo_1146610 * * JSON Arguments: * - "Name": Must be "SimulateActionSwitchMultiPress" - * - "EndpointId": number of endpoint having a switch cluster + * - "EndpointId": ID of endpoint having a switch cluster * - "ButtonId": switch position in the switch cluster for "down" button (not idle) * - "MultiPressPressedTimeMillis": Pressed time in milliseconds for each press * - "MultiPressReleasedTimeMillis": Released time in milliseconds after each press * - "MultiPressNumPresses": Number of presses to simulate + * - "FeatureMap": The feature map to simulate + * - "MultiPressMax": max number of presses (from attribute). * * @param jsonValue - JSON payload from named pipe */ -void HandleSimulateActionSwitchMultiPress(Json::Value & jsonValue) +void HandleSimulateMultiPress(Json::Value & jsonValue) { if (sButtonSimulatorInstance != nullptr) { @@ -146,13 +152,15 @@ void HandleSimulateActionSwitchMultiPress(Json::Value & jsonValue) bool hasMultiPressPressedTimeMillis = HasNumericField(jsonValue, "MultiPressPressedTimeMillis"); bool hasMultiPressReleasedTimeMillis = HasNumericField(jsonValue, "MultiPressReleasedTimeMillis"); bool hasMultiPressNumPresses = HasNumericField(jsonValue, "MultiPressNumPresses"); + bool hasFeatureMap = HasNumericField(jsonValue, "FeatureMap"); + bool hasMultiPressMax = HasNumericField(jsonValue, "MultiPressMax"); if (!hasEndpointId || !hasButtonId || !hasMultiPressPressedTimeMillis || !hasMultiPressReleasedTimeMillis || - !hasMultiPressNumPresses) + !hasMultiPressNumPresses || !hasFeatureMap || !hasMultiPressMax) { std::string inputJson = jsonValue.toStyledString(); ChipLogError(NotSpecified, "Missing or invalid value for one of EndpointId, ButtonId, MultiPressPressedTimeMillis, " - "MultiPressReleasedTimeMillis or MultiPressNumPresses in %s", + "MultiPressReleasedTimeMillis, MultiPressNumPresses, FeatureMap or MultiPressMax in %s", inputJson.c_str()); return; } @@ -164,6 +172,8 @@ void HandleSimulateActionSwitchMultiPress(Json::Value & jsonValue) System::Clock::Milliseconds32 multiPressReleasedTimeMillis{ static_cast( jsonValue["MultiPressReleasedTimeMillis"].asUInt()) }; uint8_t multiPressNumPresses = static_cast(jsonValue["MultiPressNumPresses"].asUInt()); + uint32_t featureMap = static_cast(jsonValue["FeatureMap"].asUInt()); + uint8_t multiPressMax = static_cast(jsonValue["MultiPressMax"].asUInt()); auto buttonSimulator = std::make_unique(); bool success = buttonSimulator->SetMode(ButtonEventsSimulator::Mode::kModeMultiPress) @@ -173,6 +183,8 @@ void HandleSimulateActionSwitchMultiPress(Json::Value & jsonValue) .SetIdleButtonId(0) .SetPressedButtonId(buttonId) .SetEndpointId(endpointId) + .SetFeatureMap(featureMap) + .SetMultiPressMax(multiPressMax) .Execute([]() { sButtonSimulatorInstance.reset(); }); if (!success) @@ -184,6 +196,56 @@ void HandleSimulateActionSwitchMultiPress(Json::Value & jsonValue) sButtonSimulatorInstance = std::move(buttonSimulator); } +/** + * Named pipe handler for simulating a latched switch movement. + * + * Usage example: + * echo '{"Name": "SimulateLatchPosition", "EndpointId": 3, "PositionId": 1}' > /tmp/chip_all_clusters_fifo_1146610 + * + * JSON Arguments: + * - "Name": Must be "SimulateLatchPosition" + * - "EndpointId": ID of endpoint having a switch cluster + * - "PositionId": switch position for new CurrentPosition to set in switch cluster + * + * @param jsonValue - JSON payload from named pipe + */ + +void HandleSimulateLatchPosition(Json::Value & jsonValue) +{ + bool hasEndpointId = HasNumericField(jsonValue, "EndpointId"); + bool hasPositionId = HasNumericField(jsonValue, "PositionId"); + + if (!hasEndpointId || !hasPositionId) + { + std::string inputJson = jsonValue.toStyledString(); + ChipLogError(NotSpecified, "Missing or invalid value for one of EndpointId, PositionId in %s", inputJson.c_str()); + return; + } + + EndpointId endpointId = static_cast(jsonValue["EndpointId"].asUInt()); + uint8_t positionId = static_cast(jsonValue["PositionId"].asUInt()); + + uint8_t previousPositionId = 0; + Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Get(endpointId, &previousPositionId); + VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, + ChipLogError(NotSpecified, "Failed to get CurrentPosition attribute")); + + if (positionId != previousPositionId) + { + status = Switch::Attributes::CurrentPosition::Set(endpointId, positionId); + VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, + ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute")); + ChipLogDetail(NotSpecified, "The latching switch is moved to a new position: %u", static_cast(positionId)); + + Clusters::SwitchServer::Instance().OnSwitchLatch(endpointId, positionId); + } + else + { + ChipLogDetail(NotSpecified, "Not moving latching switch to a new position, already at %u", + static_cast(positionId)); + } +} + } // namespace AllClustersAppCommandHandler * AllClustersAppCommandHandler::FromJSON(const char * json) @@ -333,17 +395,22 @@ void AllClustersAppCommandHandler::HandleCommand(intptr_t context) std::string operation = self->mJsonValue["Operation"].asString(); self->OnOperationalStateChange(device, operation, self->mJsonValue["Param"]); } - else if (name == "SimulateActionSwitchLongPress") + else if (name == "SimulateLongPress") + { + HandleSimulateLongPress(self->mJsonValue); + } + else if (name == "SimulateMultiPress") { - HandleSimulateActionSwitchLongPress(self->mJsonValue); + HandleSimulateMultiPress(self->mJsonValue); } - else if (name == "SimulateActionSwitchMultiPress") + else if (name == "SimulateLatchPosition") { - HandleSimulateActionSwitchMultiPress(self->mJsonValue); + HandleSimulateLatchPosition(self->mJsonValue); } else { - ChipLogError(NotSpecified, "Unhandled command: Should never happens"); + ChipLogError(NotSpecified, "Unhandled command '%s': this hould never happen", name.c_str()); + VerifyOrDie(false && "Named pipe command not supported, see log above."); } exit: diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index 3564153a482cca..e8671e701a7227 100644 --- a/examples/all-clusters-app/linux/BUILD.gn +++ b/examples/all-clusters-app/linux/BUILD.gn @@ -29,6 +29,10 @@ if (chip_enable_pw_rpc) { source_set("chip-all-clusters-common") { sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/WhmDelegateImpl.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/WhmInstance.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/WhmMain.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/WhmManufacturer.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/air-quality-instance.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/boolcfg-stub.cpp", @@ -46,6 +50,7 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-mode.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/microwave-oven-mode.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/occupancy-sensing-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-modes.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/oven-operational-state-delegate.cpp", diff --git a/examples/all-clusters-app/linux/ButtonEventsSimulator.cpp b/examples/all-clusters-app/linux/ButtonEventsSimulator.cpp index 44bf5657f5c2f6..53a08672fdbc07 100644 --- a/examples/all-clusters-app/linux/ButtonEventsSimulator.cpp +++ b/examples/all-clusters-app/linux/ButtonEventsSimulator.cpp @@ -114,6 +114,42 @@ void EmitMultiPressComplete(EndpointId endpointId, uint8_t previousPosition, uin } } +void EmitShortRelease(EndpointId endpointId, uint8_t previousPosition) +{ + Clusters::Switch::Events::ShortRelease::Type event{}; + event.previousPosition = previousPosition; + EventNumber eventNumber = 0; + + CHIP_ERROR err = LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to log ShortRelease event: %" CHIP_ERROR_FORMAT, err.Format()); + } + else + { + ChipLogProgress(NotSpecified, "Logged ShortRelease on Endpoint %u", static_cast(endpointId)); + } +} + +void EmitMultiPressOngoing(EndpointId endpointId, uint8_t newPosition, uint8_t count) +{ + Clusters::Switch::Events::MultiPressOngoing::Type event{}; + event.newPosition = newPosition; + event.currentNumberOfPressesCounted = count; + EventNumber eventNumber = 0; + + CHIP_ERROR err = LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to log MultiPressOngoing event: %" CHIP_ERROR_FORMAT, err.Format()); + } + else + { + ChipLogProgress(NotSpecified, "Logged MultiPressOngoing on Endpoint %u position %u, count %u", + static_cast(endpointId), newPosition, count); + } +} + } // namespace void ButtonEventsSimulator::OnTimerDone(System::Layer * layer, void * appState) @@ -186,19 +222,65 @@ void ButtonEventsSimulator::Next() } case ButtonEventsSimulator::State::kEmitLongRelease: { SetButtonPosition(mEndpointId, mIdleButtonId); - EmitLongRelease(mEndpointId, mPressedButtonId); + if (mFeatureMap & static_cast(Clusters::Switch::Feature::kMomentarySwitchLongPress)) + { + EmitLongRelease(mEndpointId, mPressedButtonId); + } + else if (mFeatureMap & static_cast(Clusters::Switch::Feature::kMomentarySwitchRelease)) + { + EmitShortRelease(mEndpointId, mPressedButtonId); + } SetState(ButtonEventsSimulator::State::kIdle); mDoneCallback(); break; } case ButtonEventsSimulator::State::kEmitStartOfMultiPress: { EmitInitialPress(mEndpointId, mPressedButtonId); - StartTimer(mMultiPressNumPresses * (mMultiPressPressedTimeMillis + mMultiPressReleasedTimeMillis)); - SetState(ButtonEventsSimulator::State::kEmitEndOfMultiPress); + if (mFeatureMap & static_cast(Clusters::Switch::Feature::kActionSwitch)) + { + StartTimer(mMultiPressNumPresses * (mMultiPressPressedTimeMillis + mMultiPressReleasedTimeMillis)); + SetState(ButtonEventsSimulator::State::kEmitEndOfMultiPress); + } + else + { + SetState(ButtonEventsSimulator::State::kMultiPressButtonRelease); + StartTimer(mMultiPressPressedTimeMillis); + } break; } + case ButtonEventsSimulator::State::kMultiPressButtonRelease: { + ++mMultiPressPressesDone; + if (mMultiPressPressesDone > 1) + { + EmitMultiPressOngoing(mEndpointId, mPressedButtonId, mMultiPressPressesDone); + } + + if (mMultiPressPressesDone == mMultiPressNumPresses) + { + SetState(ButtonEventsSimulator::State::kEmitEndOfMultiPress); + } + else + { + SetState(ButtonEventsSimulator::State::kEmitStartOfMultiPress); + } + + if (mFeatureMap & static_cast(Clusters::Switch::Feature::kMomentarySwitchRelease)) + { + EmitShortRelease(mEndpointId, mPressedButtonId); + } + StartTimer(mMultiPressReleasedTimeMillis); + break; + } + case ButtonEventsSimulator::State::kEmitEndOfMultiPress: { - EmitMultiPressComplete(mEndpointId, mPressedButtonId, mMultiPressNumPresses); + if (mFeatureMap & static_cast(Clusters::Switch::Feature::kActionSwitch) && mMultiPressNumPresses > mMultiPressMax) + { + EmitMultiPressComplete(mEndpointId, mPressedButtonId, 0); + } + else + { + EmitMultiPressComplete(mEndpointId, mPressedButtonId, mMultiPressNumPresses); + } SetState(ButtonEventsSimulator::State::kIdle); mDoneCallback(); break; diff --git a/examples/all-clusters-app/linux/ButtonEventsSimulator.h b/examples/all-clusters-app/linux/ButtonEventsSimulator.h index 658da98f14fefd..539b2010099bd6 100644 --- a/examples/all-clusters-app/linux/ButtonEventsSimulator.h +++ b/examples/all-clusters-app/linux/ButtonEventsSimulator.h @@ -42,7 +42,8 @@ class ButtonEventsSimulator enum class Mode { kModeLongPress, - kModeMultiPress + kModeMultiPress, + kModeMultiPressNonAs }; using DoneCallback = std::function; @@ -107,6 +108,18 @@ class ButtonEventsSimulator return *this; } + ButtonEventsSimulator & SetFeatureMap(uint32_t featureMap) + { + mFeatureMap = featureMap; + return *this; + } + + ButtonEventsSimulator & SetMultiPressMax(uint8_t multiPressMax) + { + mMultiPressMax = multiPressMax; + return *this; + } + private: enum class State { @@ -118,6 +131,8 @@ class ButtonEventsSimulator kEmitStartOfMultiPress = 4, kEmitEndOfMultiPress = 5, + + kMultiPressButtonRelease = 6, }; static void OnTimerDone(System::Layer * layer, void * appState); @@ -131,9 +146,12 @@ class ButtonEventsSimulator System::Clock::Milliseconds32 mMultiPressPressedTimeMillis{}; System::Clock::Milliseconds32 mMultiPressReleasedTimeMillis{}; uint8_t mMultiPressNumPresses{ 1 }; + uint8_t mMultiPressPressesDone{ 0 }; uint8_t mIdleButtonId{ 0 }; uint8_t mPressedButtonId{ 1 }; EndpointId mEndpointId{ 1 }; + uint32_t mFeatureMap{ 0 }; + uint8_t mMultiPressMax{ 0 }; Mode mMode{ Mode::kModeLongPress }; State mState{ State::kIdle }; diff --git a/examples/all-clusters-app/linux/args.gni b/examples/all-clusters-app/linux/args.gni index d414ad5dedaf5d..92d01ea3358b30 100644 --- a/examples/all-clusters-app/linux/args.gni +++ b/examples/all-clusters-app/linux/args.gni @@ -29,3 +29,4 @@ matter_log_json_payload_decode_full = true matter_log_json_payload_hex = true chip_enable_smoke_co_trigger = true chip_enable_boolean_state_configuration_trigger = true +chip_enable_water_heater_management_trigger = true diff --git a/examples/all-clusters-app/linux/main-common.cpp b/examples/all-clusters-app/linux/main-common.cpp index 1d1799ece3581b..bc547d5416377c 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -63,6 +63,8 @@ #include +#include + using namespace chip; using namespace chip::app; using namespace chip::DeviceLayer; @@ -80,13 +82,19 @@ Clusters::ValveConfigurationAndControl::ValveControlDelegate sValveDelegate; Clusters::TimeSynchronization::ExtendedTimeSyncDelegate sTimeSyncDelegate; // Please refer to https://github.com/CHIP-Specifications/connectedhomeip-spec/blob/master/src/namespaces -constexpr const uint8_t kNamespaceCommon = 7; +constexpr const uint8_t kNamespaceCommon = 7; +constexpr const uint8_t kNamespaceSwitches = 0x43; + // Common Number Namespace: 7, tag 0 (Zero) constexpr const uint8_t kTagCommonZero = 0; // Common Number Namespace: 7, tag 1 (One) constexpr const uint8_t kTagCommonOne = 1; // Common Number Namespace: 7, tag 2 (Two) constexpr const uint8_t kTagCommonTwo = 2; +// Switches namespace: 0x43, tag = 0x03 (Up) +constexpr const uint8_t kTagSwitchesUp = 0x03; +// Switches namespace: 0x43, tag = 0x04 (Down) +constexpr const uint8_t kTagSwitchesDown = 0x04; constexpr const uint8_t kNamespacePosition = 8; // Common Position Namespace: 8, tag: 0 (Left) @@ -104,6 +112,11 @@ const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp1TagList[] = { const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp2TagList[] = { { .namespaceID = kNamespaceCommon, .tag = kTagCommonTwo }, { .namespaceID = kNamespacePosition, .tag = kTagPositionRight } }; +// Endpoints 3 and 4 are an action switch and a non-action switch. On the device, they're tagged as up and down because why not. +const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp3TagList[] = { { .namespaceID = kNamespaceSwitches, + .tag = kTagSwitchesUp } }; +const Clusters::Descriptor::Structs::SemanticTagStruct::Type gEp4TagList[] = { { .namespaceID = kNamespaceSwitches, + .tag = kTagSwitchesDown } }; } // namespace #ifdef MATTER_DM_PLUGIN_DISHWASHER_ALARM_SERVER @@ -235,9 +248,13 @@ void ApplicationInit() Clusters::ValveConfigurationAndControl::SetDefaultDelegate(chip::EndpointId(1), &sValveDelegate); Clusters::TimeSynchronization::SetDefaultDelegate(&sTimeSyncDelegate); + Clusters::WaterHeaterManagement::WhmApplicationInit(); + SetTagList(/* endpoint= */ 0, Span(gEp0TagList)); SetTagList(/* endpoint= */ 1, Span(gEp1TagList)); SetTagList(/* endpoint= */ 2, Span(gEp2TagList)); + SetTagList(/* endpoint= */ 3, Span(gEp3TagList)); + SetTagList(/* endpoint= */ 4, Span(gEp4TagList)); } void ApplicationShutdown() @@ -262,6 +279,9 @@ void ApplicationShutdown() Clusters::EnergyEvseMode::Shutdown(); Clusters::WaterHeaterMode::Shutdown(); + Clusters::WaterHeaterManagement::WhmApplicationShutdown(); + Clusters::WaterHeaterMode::Shutdown(); + if (sChipNamedPipeCommands.Stop() != CHIP_NO_ERROR) { ChipLogError(NotSpecified, "Failed to stop CHIP NamedPipeCommands"); diff --git a/examples/all-clusters-app/nrfconnect/README.md b/examples/all-clusters-app/nrfconnect/README.md index 18df16f5e11654..3a58e448d76254 100644 --- a/examples/all-clusters-app/nrfconnect/README.md +++ b/examples/all-clusters-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect All Clusters Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF All Clusters Example Application implements various ZCL clusters populated on three endpoints. You can use this example as a reference for creating your own application. @@ -85,10 +101,10 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ------------------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| -| [nRF52840 Dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) | `nrf52840dongle_nrf52840` |
nRF52840 DonglenRF52840 Dongle
| -| [nRF7002 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF7002-DK) | `nrf7002dk_nrf5340_cpuapp` |
nRF7002 DKnRF7002 DK
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF52840 Dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) | `nrf52840dongle/nrf52840` |
nRF52840 DonglenRF52840 Dongle
| +| [nRF7002 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF7002-DK) | `nrf7002dk/nrf5340/cpuapp` |
nRF7002 DKnRF7002 DK
|
@@ -97,9 +113,9 @@ The example supports building and running on the following devices: The development kits for this sample offer the following IPv6 network support for Matter: -- Matter over Thread is supported for `nrf52840dk_nrf52840` and - `nrf5340dk_nrf5340_cpuapp`. -- Matter over Wi-Fi is supported for `nrf7002dk_nrf5340_cpuapp`. +- Matter over Thread is supported for `nrf52840dk/nrf52840` and + `nrf5340dk/nrf5340/cpuapp`. +- Matter over Wi-Fi is supported for `nrf7002dk/nrf5340/cpuapp`. ## Device UI @@ -248,14 +264,15 @@ Complete the following steps to build the sample: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: - $ west build -b build-target + $ west build -b build-target --sysbuild You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -270,7 +287,7 @@ following command: To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -281,9 +298,9 @@ Support for DFU using Matter OTA is disabled by default. To build the example with configuration that supports DFU, run the following command with _build-target_ replaced with the build target name of the Nordic -Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): +Semiconductor kit you are using (for example `nrf52840dk/nrf52840`): - $ west build -b build-target -- -DCONF_FILE=prj_dfu.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=dfu > **Note**: > @@ -299,7 +316,7 @@ Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. #### Changing flash memory settings @@ -311,8 +328,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -324,7 +342,7 @@ using the menuconfig utility. To open the menuconfig utility, run the following command from the example directory: - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. diff --git a/examples/all-clusters-app/nrfconnect/prj_release.conf b/examples/all-clusters-app/nrfconnect/prj_release.conf index b98004283b64b9..18685a7488fce5 100644 --- a/examples/all-clusters-app/nrfconnect/prj_release.conf +++ b/examples/all-clusters-app/nrfconnect/prj_release.conf @@ -62,3 +62,7 @@ CONFIG_CHIP_FACTORY_DATA_BUILD=y # Enable the Read Client for binding purposes CONFIG_CHIP_ENABLE_READ_CLIENT=y + +# Enable LTO to reduce the flash usage +CONFIG_LTO=y +CONFIG_ISR_TABLES_LOCAL_DECLARATION=y diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 946733b5ebe9da..4bf0d15e54f799 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -401,7 +401,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -417,12 +417,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -458,17 +488,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ @@ -1255,6 +1309,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1263,6 +1320,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1273,6 +1334,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1306,12 +1371,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -3568,7 +3644,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -3694,11 +3771,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -3804,8 +3876,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -3849,10 +3920,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -3871,8 +3938,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ @@ -6402,7 +6467,7 @@ endpoint 1 { ram attribute numberOfPositions default = 2; ram attribute currentPosition; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } server cluster FixedLabel { 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 8afff9a3507a3c..57f2c0412fca55 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 @@ -5593,7 +5593,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -12408,4 +12408,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/all-clusters-minimal-app/nrfconnect/README.md b/examples/all-clusters-minimal-app/nrfconnect/README.md index a015c7a61ed115..932db10a2f2c89 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/README.md +++ b/examples/all-clusters-minimal-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect All Clusters Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF All Clusters Example Application implements various ZCL clusters populated on three endpoints. You can use this example as a reference for creating your own application. @@ -77,9 +93,9 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ------------------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| -| [nRF52840 Dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) | `nrf52840dongle_nrf52840` |
nRF52840 DonglenRF52840 Dongle
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF52840 Dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) | `nrf52840dongle/nrf52840` |
nRF52840 DonglenRF52840 Dongle
|
@@ -240,14 +256,15 @@ environment: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: - $ west build -b build-target + $ west build -b build-target --sysbuild You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -262,7 +279,7 @@ following command: To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -273,9 +290,9 @@ Support for DFU using Matter OTA is disabled by default. To build the example with configuration that supports DFU, run the following command with _build-target_ replaced with the build target name of the Nordic -Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): +Semiconductor kit you are using (for example `nrf52840dk/nrf52840`): - $ west build -b build-target -- -DCONF_FILE=prj_dfu.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=dfu > **Note**: > @@ -291,7 +308,7 @@ Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. #### Changing flash memory settings @@ -303,8 +320,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -316,7 +334,7 @@ using the menuconfig utility. To open the menuconfig utility, run the following command from the example directory: - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. diff --git a/examples/bridge-app/bridge-common/bridge-app.matter b/examples/bridge-app/bridge-common/bridge-app.matter index 049e42d6f61e4f..c403ecd9d40ff6 100644 --- a/examples/bridge-app/bridge-common/bridge-app.matter +++ b/examples/bridge-app/bridge-common/bridge-app.matter @@ -324,7 +324,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -340,12 +340,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -381,17 +411,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** The Access Control Cluster exposes a data model view of a @@ -399,7 +453,7 @@ cluster AccessControl = 31 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -415,12 +469,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -456,17 +540,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ @@ -840,6 +948,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -848,6 +959,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -858,6 +973,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -891,12 +1010,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter index a8de6fab823b82..2557a01f257fff 100644 --- a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter @@ -401,7 +401,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -417,12 +417,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -458,17 +488,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -793,6 +847,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -801,6 +858,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -811,6 +872,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -844,12 +909,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ diff --git a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter index f00c909ce0a882..5cc3baccb0aa62 100644 --- a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter +++ b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter @@ -178,7 +178,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -194,12 +194,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -235,17 +265,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -509,6 +563,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -517,6 +574,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -527,6 +588,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -560,12 +625,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter index 1976a0d6af169b..9e1548b7dd36c5 100644 --- a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter +++ b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter @@ -183,7 +183,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -199,12 +199,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -240,17 +270,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -360,6 +414,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -368,6 +425,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -378,6 +439,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -411,12 +476,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1217,7 +1293,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1343,11 +1420,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1453,8 +1525,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1498,10 +1569,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1520,8 +1587,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter index a6d9cf022022f8..22282b4b3a8ffe 100644 --- a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter +++ b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -757,6 +811,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -765,6 +822,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -775,6 +836,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -808,12 +873,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter index 961eeaade9e1d6..4fb0ed83478012 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -303,7 +303,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -319,12 +319,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -360,17 +390,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -651,6 +705,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -659,6 +716,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -669,6 +730,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -702,12 +767,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter index 88ff138f11e1f0..31241e3a4ab637 100644 --- a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter +++ b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -711,6 +765,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -719,6 +776,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -729,6 +790,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -762,12 +827,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter index 8e62555955a2e1..5735b2cf936ff4 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -696,6 +750,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -704,6 +761,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -714,6 +775,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -747,12 +812,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter index 9f08c5a23aa601..657ce0dd5fe520 100644 --- a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter +++ b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -855,6 +909,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -863,6 +920,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -873,6 +934,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -906,12 +971,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter index 66c3432e2de60d..9495bcd7e6b61e 100644 --- a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter @@ -401,7 +401,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -417,12 +417,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -458,17 +488,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -793,6 +847,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -801,6 +858,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -811,6 +872,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -844,12 +909,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter index d395b259d4a9d6..e3a97805d6c5e8 100644 --- a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter +++ b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter @@ -401,7 +401,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -417,12 +417,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -458,17 +488,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -793,6 +847,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -801,6 +858,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -811,6 +872,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -844,12 +909,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter index 62da7396ee7c8f..ceaeeecc4a7ef2 100644 --- a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter +++ b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -370,6 +424,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -378,6 +435,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -388,6 +449,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -421,12 +486,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter index d808e2d25f478b..d07df97b8f173a 100644 --- a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter +++ b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -757,6 +811,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -765,6 +822,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -775,6 +836,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -808,12 +873,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter index 19a62b4feb5e1c..06cefc49a5ce84 100644 --- a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter +++ b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter @@ -401,7 +401,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -417,12 +417,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -458,17 +488,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -793,6 +847,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -801,6 +858,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -811,6 +872,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -844,12 +909,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter index 3ff6ab9cd9c23c..2eb6abd966f095 100644 --- a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter +++ b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter @@ -183,7 +183,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -199,12 +199,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -240,17 +270,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -575,6 +629,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -583,6 +640,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -593,6 +654,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -626,12 +691,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter index 73390f105c1b8f..5c4452aabd8986 100644 --- a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter +++ b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -596,6 +650,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -604,6 +661,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -614,6 +675,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -647,12 +712,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter index 81b9bf1c21cc17..76d90d2ad12398 100644 --- a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -542,6 +596,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -550,6 +607,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -560,6 +621,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -593,12 +658,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1509,7 +1585,7 @@ endpoint 1 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0xE; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } } diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap index b8f941b101de57..40df85e6248d6e 100644 --- a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.zap @@ -2742,7 +2742,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2801,4 +2801,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter index 11f915e6c4f860..5216ad0a5a3829 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -542,6 +596,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -550,6 +607,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -560,6 +621,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -593,12 +658,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1506,7 +1582,7 @@ endpoint 1 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } } diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap index ae37c5dbef1732..7404c36bb6a120 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.zap @@ -2742,7 +2742,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2780,4 +2780,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter index b0011ffb37983b..cbbedfa6080098 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter @@ -401,7 +401,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -417,12 +417,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -458,17 +488,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -793,6 +847,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -801,6 +858,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -811,6 +872,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -844,12 +909,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1574,7 +1650,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1700,11 +1777,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1810,8 +1882,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1855,10 +1926,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1877,8 +1944,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter index 32ab67c21b8593..05fd620ffd7518 100644 --- a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter +++ b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -596,6 +650,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -604,6 +661,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -614,6 +675,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -647,12 +712,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter index 34c4a8284e7851..7d10d932eefd39 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -370,6 +424,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -378,6 +435,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -388,6 +449,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -421,12 +486,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter index cfa2faa440b95f..c7334375df90b2 100644 --- a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter +++ b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -596,6 +650,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -604,6 +661,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -614,6 +675,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -647,12 +712,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter index 9425ccba0c313a..c3e38b16d96ad4 100644 --- a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter +++ b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -596,6 +650,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -604,6 +661,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -614,6 +675,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -647,12 +712,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter index 7360ede44aff51..17b66ebe5303ba 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter @@ -401,7 +401,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -417,12 +417,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -458,17 +488,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -793,6 +847,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -801,6 +858,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -811,6 +872,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -844,12 +909,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_onofflight_samplemei.matter b/examples/chef/devices/rootnode_onofflight_samplemei.matter index 58811796ed547a..9492a186a67c3e 100644 --- a/examples/chef/devices/rootnode_onofflight_samplemei.matter +++ b/examples/chef/devices/rootnode_onofflight_samplemei.matter @@ -401,7 +401,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -417,12 +417,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -458,17 +488,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -793,6 +847,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -801,6 +858,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -811,6 +872,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -844,12 +909,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter index b02e20255349fe..03046a45af8ac8 100644 --- a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter +++ b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter @@ -348,7 +348,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -364,12 +364,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -405,17 +435,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -740,6 +794,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -748,6 +805,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -758,6 +819,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -791,12 +856,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter index 03716c4ce00425..a25ba3dafb35ac 100644 --- a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter +++ b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter @@ -276,7 +276,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -292,12 +292,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -333,17 +363,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -668,6 +722,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -676,6 +733,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -686,6 +747,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -719,12 +784,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter index 5c413241adced8..4c45232b369f02 100644 --- a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter +++ b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -596,6 +650,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -604,6 +661,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -614,6 +675,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -647,12 +712,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_pump_5f904818cc.matter b/examples/chef/devices/rootnode_pump_5f904818cc.matter index 9a30a686479625..ed9e7c58a90e11 100644 --- a/examples/chef/devices/rootnode_pump_5f904818cc.matter +++ b/examples/chef/devices/rootnode_pump_5f904818cc.matter @@ -178,7 +178,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -194,12 +194,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -235,17 +265,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -442,6 +496,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -450,6 +507,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -460,6 +521,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -493,12 +558,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_pump_a811bb33a0.matter b/examples/chef/devices/rootnode_pump_a811bb33a0.matter index 10c5bd7aa2cd59..d11ba11cc816be 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.matter +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.matter @@ -178,7 +178,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -194,12 +194,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -235,17 +265,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -442,6 +496,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -450,6 +507,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -460,6 +521,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -493,12 +558,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter index 2d046beded5e96..026a69ae346280 100644 --- a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter +++ b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -370,6 +424,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -378,6 +435,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -388,6 +449,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -421,12 +486,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter index 3285f99388b3c5..a116ea0892b644 100644 --- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter +++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter @@ -183,7 +183,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -199,12 +199,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -240,17 +270,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -619,6 +673,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -627,6 +684,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -637,6 +698,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -670,12 +735,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter index 5a8aefa22762f6..7603eca8a44a52 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter @@ -255,7 +255,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -271,12 +271,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -312,17 +342,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -432,6 +486,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -440,6 +497,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -450,6 +511,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -483,12 +548,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1157,7 +1233,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1283,11 +1360,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1393,8 +1465,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1438,10 +1509,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1460,8 +1527,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter index 28669954fab360..eab95df39549b2 100644 --- a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter +++ b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter @@ -183,7 +183,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -199,12 +199,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -240,17 +270,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -619,6 +673,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -627,6 +684,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -637,6 +698,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -670,12 +735,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter index b6898778855ad6..52446c519d4ec5 100644 --- a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter +++ b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter @@ -324,7 +324,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -340,12 +340,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -381,17 +411,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -716,6 +770,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -724,6 +781,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -734,6 +795,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -767,12 +832,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter index f91f03cc02ffad..3bafec9ed48427 100644 --- a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter +++ b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -596,6 +650,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -604,6 +661,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -614,6 +675,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -647,12 +712,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter index f7ff21337d4e96..c2b1ed117c6ff3 100644 --- a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter +++ b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -596,6 +650,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -604,6 +661,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -614,6 +675,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -647,12 +712,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1377,7 +1453,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1503,11 +1580,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1613,8 +1685,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1658,10 +1729,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1680,8 +1747,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ diff --git a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter index aaf2dca3c3fbb7..b318c7b3ed80b7 100644 --- a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter +++ b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -596,6 +650,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -604,6 +661,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -614,6 +675,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -647,12 +712,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/chef/nrfconnect/README.md b/examples/chef/nrfconnect/README.md index 8e17340c92069b..ca59a609946baf 100644 --- a/examples/chef/nrfconnect/README.md +++ b/examples/chef/nrfconnect/README.md @@ -1,5 +1,21 @@ # CHIP nRF Connect SDK Shell Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + A [chip-shell](../README.md) project for the Nordic nRF52840 and nRF5340 development kits, built using the nRF Connect SDK. diff --git a/examples/chip-tool/BUILD.gn b/examples/chip-tool/BUILD.gn index b5917f3bfaca62..94e1eebbde7508 100644 --- a/examples/chip-tool/BUILD.gn +++ b/examples/chip-tool/BUILD.gn @@ -109,6 +109,7 @@ static_library("chip-tool-utils") { "${chip_root}/src/app/tests/suites/commands/interaction_model", "${chip_root}/src/controller/data_model", "${chip_root}/src/credentials:file_attestation_trust_store", + "${chip_root}/src/credentials:test_dac_revocation_delegate", "${chip_root}/src/lib", "${chip_root}/src/lib/core:types", "${chip_root}/src/lib/support/jsontlv", diff --git a/examples/chip-tool/commands/common/CHIPCommand.cpp b/examples/chip-tool/commands/common/CHIPCommand.cpp index 7e871f8e781e14..1c3df517bd89d0 100644 --- a/examples/chip-tool/commands/common/CHIPCommand.cpp +++ b/examples/chip-tool/commands/common/CHIPCommand.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -48,7 +49,9 @@ constexpr chip::FabricId kIdentityOtherFabricId = 4; constexpr char kPAATrustStorePathVariable[] = "CHIPTOOL_PAA_TRUST_STORE_PATH"; constexpr char kCDTrustStorePathVariable[] = "CHIPTOOL_CD_TRUST_STORE_PATH"; -const chip::Credentials::AttestationTrustStore * CHIPCommand::sTrustStore = nullptr; +const chip::Credentials::AttestationTrustStore * CHIPCommand::sTrustStore = nullptr; +chip::Credentials::DeviceAttestationRevocationDelegate * CHIPCommand::sRevocationDelegate = nullptr; + chip::Credentials::GroupDataProviderImpl CHIPCommand::sGroupDataProvider{ kMaxGroupsPerFabric, kMaxGroupKeysPerFabric }; // All fabrics share the same ICD client storage. chip::app::DefaultICDClientStorage CHIPCommand::sICDClientStorage; @@ -87,6 +90,20 @@ CHIP_ERROR GetAttestationTrustStore(const char * paaTrustStorePath, const chip:: return CHIP_NO_ERROR; } +CHIP_ERROR GetAttestationRevocationDelegate(const char * revocationSetPath, + chip::Credentials::DeviceAttestationRevocationDelegate ** revocationDelegate) +{ + if (revocationSetPath == nullptr) + { + return CHIP_NO_ERROR; + } + + static chip::Credentials::TestDACRevocationDelegateImpl testDacRevocationDelegate; + ReturnErrorOnFailure(testDacRevocationDelegate.SetDeviceAttestationRevocationSetPath(revocationSetPath)); + *revocationDelegate = &testDacRevocationDelegate; + return CHIP_NO_ERROR; +} + } // namespace CHIP_ERROR CHIPCommand::MaybeSetUpStack() @@ -151,6 +168,8 @@ CHIP_ERROR CHIPCommand::MaybeSetUpStack() ReturnErrorOnFailure(GetAttestationTrustStore(mPaaTrustStorePath.ValueOr(nullptr), &sTrustStore)); + ReturnLogErrorOnFailure(GetAttestationRevocationDelegate(mDacRevocationSetPath.ValueOr(nullptr), &sRevocationDelegate)); + auto engine = chip::app::InteractionModelEngine::GetInstance(); VerifyOrReturnError(engine != nullptr, CHIP_ERROR_INCORRECT_STATE); ReturnLogErrorOnFailure(ChipToolCheckInDelegate()->Init(&sICDClientStorage, engine)); @@ -450,7 +469,7 @@ CHIP_ERROR CHIPCommand::InitializeCommissioner(CommissionerIdentity & identity, std::unique_ptr commissioner = std::make_unique(); chip::Controller::SetupParams commissionerParams; - ReturnLogErrorOnFailure(mCredIssuerCmds->SetupDeviceAttestation(commissionerParams, sTrustStore)); + ReturnLogErrorOnFailure(mCredIssuerCmds->SetupDeviceAttestation(commissionerParams, sTrustStore, sRevocationDelegate)); chip::Crypto::P256Keypair ephemeralKey; diff --git a/examples/chip-tool/commands/common/CHIPCommand.h b/examples/chip-tool/commands/common/CHIPCommand.h index 50ab851d284502..b48455ebed6821 100644 --- a/examples/chip-tool/commands/common/CHIPCommand.h +++ b/examples/chip-tool/commands/common/CHIPCommand.h @@ -86,6 +86,10 @@ class CHIPCommand : public Command AddArgument("only-allow-trusted-cd-keys", 0, 1, &mOnlyAllowTrustedCdKeys, "Only allow trusted CD verifying keys (disallow test keys). If not provided or 0 (\"false\"), untrusted CD " "verifying keys are allowed. If 1 (\"true\"), test keys are disallowed."); + AddArgument("dac-revocation-set-path", &mDacRevocationSetPath, + "Path to JSON file containing the device attestation revocation set. " + "This argument caches the path to the revocation set. Once set, this will be used by all commands in " + "interactive mode."); #if CHIP_CONFIG_TRANSPORT_TRACE_ENABLED AddArgument("trace_file", &mTraceFile); AddArgument("trace_log", 0, 1, &mTraceLog); @@ -222,11 +226,16 @@ class CHIPCommand : public Command chip::Optional mCDTrustStorePath; chip::Optional mUseMaxSizedCerts; chip::Optional mOnlyAllowTrustedCdKeys; + chip::Optional mDacRevocationSetPath; // Cached trust store so commands other than the original startup command // can spin up commissioners as needed. static const chip::Credentials::AttestationTrustStore * sTrustStore; + // Cached DAC revocation delegate, this can be set using "--dac-revocation-set-path" argument + // Once set this will be used by all commands. + static chip::Credentials::DeviceAttestationRevocationDelegate * sRevocationDelegate; + static void RunQueuedCommand(intptr_t commandArg); typedef decltype(RunQueuedCommand) MatterWorkCallback; static void RunCommandCleanup(intptr_t commandArg); diff --git a/examples/chip-tool/commands/common/CredentialIssuerCommands.h b/examples/chip-tool/commands/common/CredentialIssuerCommands.h index fd096b31835723..f8e225afec4c5e 100644 --- a/examples/chip-tool/commands/common/CredentialIssuerCommands.h +++ b/examples/chip-tool/commands/common/CredentialIssuerCommands.h @@ -57,10 +57,13 @@ class CredentialIssuerCommands * Verifier. * @param[in] trustStore A pointer to the PAA trust store to use to find valid PAA roots. * + * @param[in] revocationDelegate A pointer to the Device Attestation Revocation Delegate for checking revoked DACs and PAIs. + * * @return CHIP_ERROR CHIP_NO_ERROR on success, or corresponding error code. */ virtual CHIP_ERROR SetupDeviceAttestation(chip::Controller::SetupParams & setupParams, - const chip::Credentials::AttestationTrustStore * trustStore) = 0; + const chip::Credentials::AttestationTrustStore * trustStore, + chip::Credentials::DeviceAttestationRevocationDelegate * revocationDelegate) = 0; /** * @brief Add a list of additional non-default CD verifying keys (by certificate) diff --git a/examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h b/examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h index a23b45eae10627..495ae8d7a544d6 100644 --- a/examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h +++ b/examples/chip-tool/commands/example/ExampleCredentialIssuerCommands.h @@ -34,16 +34,18 @@ class ExampleCredentialIssuerCommands : public CredentialIssuerCommands return mOpCredsIssuer.Initialize(storage); } CHIP_ERROR SetupDeviceAttestation(chip::Controller::SetupParams & setupParams, - const chip::Credentials::AttestationTrustStore * trustStore) override + const chip::Credentials::AttestationTrustStore * trustStore, + chip::Credentials::DeviceAttestationRevocationDelegate * revocationDelegate) override { chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider()); - mDacVerifier = chip::Credentials::GetDefaultDACVerifier(trustStore); + mDacVerifier = chip::Credentials::GetDefaultDACVerifier(trustStore, revocationDelegate); setupParams.deviceAttestationVerifier = mDacVerifier; mDacVerifier->EnableCdTestKeySupport(mAllowTestCdSigningKey); return CHIP_NO_ERROR; } + chip::Controller::OperationalCredentialsDelegate * GetCredentialIssuer() override { return &mOpCredsIssuer; } void SetCredentialIssuerCATValues(chip::CATValues cats) override { mOpCredsIssuer.SetCATValuesForNextNOCRequest(cats); } CHIP_ERROR GenerateControllerNOCChain(chip::NodeId nodeId, chip::FabricId fabricId, const chip::CATValues & cats, diff --git a/examples/chip-tool/commands/pairing/Commands.h b/examples/chip-tool/commands/pairing/Commands.h index 41a35bb6bae6ad..c202178657df7b 100644 --- a/examples/chip-tool/commands/pairing/Commands.h +++ b/examples/chip-tool/commands/pairing/Commands.h @@ -181,6 +181,16 @@ class PairSoftAP : public PairingCommand {} }; +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +class PairWiFiPAF : public PairingCommand +{ +public: + PairWiFiPAF(CredentialIssuerCommands * credsIssuerConfig) : + PairingCommand("wifipaf-wifi", PairingMode::WiFiPAF, PairingNetworkType::WiFi, credsIssuerConfig) + {} +}; +#endif + class PairAlreadyDiscovered : public PairingCommand { public: @@ -243,6 +253,9 @@ void registerCommandsPairing(Commands & commands, CredentialIssuerCommands * cre make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + make_unique(credsIssuerConfig), +#endif make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index 35ce2ba1cc7aaa..245c9ed57ff82c 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -80,6 +80,11 @@ CHIP_ERROR PairingCommand::RunInternal(NodeId remoteId) case PairingMode::SoftAP: err = Pair(remoteId, PeerAddress::UDP(mRemoteAddr.address, mRemotePort, mRemoteAddr.interfaceId)); break; +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + case PairingMode::WiFiPAF: + err = Pair(remoteId, PeerAddress::WiFiPAF(remoteId)); + break; +#endif case PairingMode::AlreadyDiscovered: err = Pair(remoteId, PeerAddress::UDP(mRemoteAddr.address, mRemotePort, mRemoteAddr.interfaceId)); break; diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index 0cf4e1de2de713..9965b663ec111c 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -35,6 +35,9 @@ enum class PairingMode CodePaseOnly, Ble, SoftAP, +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + WiFiPAF, +#endif AlreadyDiscovered, AlreadyDiscoveredByIndex, AlreadyDiscoveredByIndexWithCode, @@ -127,6 +130,13 @@ class PairingCommand : public CHIPCommand, AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort); AddArgument("pase-only", 0, 1, &mPaseOnly); break; +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + case PairingMode::WiFiPAF: + AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete); + AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode.emplace()); + AddArgument("discriminator", 0, 4096, &mDiscriminator.emplace()); + break; +#endif case PairingMode::AlreadyDiscovered: AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete); AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode.emplace()); diff --git a/examples/chip-tool/commands/payload/SetupPayloadParseCommand.cpp b/examples/chip-tool/commands/payload/SetupPayloadParseCommand.cpp index 7ab62c7da5101d..de1afad1835385 100644 --- a/examples/chip-tool/commands/payload/SetupPayloadParseCommand.cpp +++ b/examples/chip-tool/commands/payload/SetupPayloadParseCommand.cpp @@ -108,6 +108,14 @@ CHIP_ERROR SetupPayloadParseCommand::Print(chip::SetupPayload payload) } humanFlags.Add("On IP network"); } + if (payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kWiFiPAF)) + { + if (!humanFlags.Empty()) + { + humanFlags.Add(", "); + } + humanFlags.Add("Wi-Fi PAF"); + } } else { diff --git a/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/decoder.py b/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/decoder.py index cd77147fff40d6..68effa7bb30dbc 100644 --- a/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/decoder.py +++ b/examples/chip-tool/py_matter_chip_tool_adapter/matter_chip_tool_adapter/decoder.py @@ -322,7 +322,7 @@ def run(self, specs, value, cluster_name: str, typename: str, array: bool): provided_field_name = provided_field_name[0].lower( ) + provided_field_name[1:] - if provided_field_name in value and provided_field_name != field_name: + if provided_field_name in value: value[field_name] = self.run( specs, value[provided_field_name], @@ -330,7 +330,8 @@ def run(self, specs, value, cluster_name: str, typename: str, array: bool): field_type, field_array ) - del value[provided_field_name] + if provided_field_name != field_name: + del value[provided_field_name] if specs.is_fabric_scoped(struct): if _FABRIC_INDEX_FIELD_CODE in value: diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter index 5c2830b39540bb..e1c580c030bc5a 100644 --- a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter +++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.matter @@ -183,7 +183,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -199,12 +199,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -240,17 +270,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -575,6 +629,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -583,6 +640,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -593,6 +654,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -626,12 +691,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter index 2606c314ff1581..b48d6984bafd07 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -437,6 +491,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -445,6 +502,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -455,6 +516,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -488,12 +553,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter index afb602e1abc18d..6c033b5dfbac0d 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -437,6 +491,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -445,6 +502,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -455,6 +516,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -488,12 +553,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter index 6ed8e87a7e75d1..7c27d4cfb63185 100644 --- a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter +++ b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter @@ -204,7 +204,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -220,12 +220,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -261,17 +291,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -468,6 +522,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -476,6 +533,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -486,6 +547,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -519,12 +584,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ 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 eae8f9991fa967..af5c74ef27da4a 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 @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -629,6 +683,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -637,6 +694,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -647,6 +708,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -680,12 +745,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/energy-management-app/esp32/main/CMakeLists.txt b/examples/energy-management-app/esp32/main/CMakeLists.txt index 15c1f99a6982aa..cce09303b58d72 100644 --- a/examples/energy-management-app/esp32/main/CMakeLists.txt +++ b/examples/energy-management-app/esp32/main/CMakeLists.txt @@ -54,7 +54,6 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/energy-evse-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/device-energy-management-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/occupancy-sensor-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/operational-credentials-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ota-requestor" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-server" diff --git a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter index b0f11a4039aa18..19cd327c7394ea 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter +++ b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** The Access Control Cluster exposes a data model view of a @@ -181,7 +235,7 @@ cluster AccessControl = 31 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -197,12 +251,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -238,17 +322,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -358,6 +466,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -366,6 +477,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -376,6 +491,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -409,12 +528,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter index e8913aeb7e11b3..f0bffe95080d01 100644 --- a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter +++ b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter @@ -276,7 +276,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -292,12 +292,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -333,17 +363,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -953,6 +1007,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -961,6 +1018,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -971,6 +1032,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1004,12 +1069,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/light-switch-app/esp32/main/CMakeLists.txt b/examples/light-switch-app/esp32/main/CMakeLists.txt index e2600438b55346..b4b6f5946eb2f9 100644 --- a/examples/light-switch-app/esp32/main/CMakeLists.txt +++ b/examples/light-switch-app/esp32/main/CMakeLists.txt @@ -46,7 +46,6 @@ idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/localization-configuration-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-format-localization-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/occupancy-sensor-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/operational-credentials-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ota-requestor" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/power-source-configuration-server" diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index 65796ceebd4063..ea78ebf1d2fa5b 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -326,7 +326,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -342,12 +342,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -383,17 +413,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -718,6 +772,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -726,6 +783,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -736,6 +797,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -769,12 +834,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -2996,7 +3072,7 @@ endpoint 2 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 2; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } } diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.zap b/examples/light-switch-app/light-switch-common/light-switch-app.zap index ad7f46df3bc97d..80a6d6dc6a7602 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.zap +++ b/examples/light-switch-app/light-switch-common/light-switch-app.zap @@ -5857,7 +5857,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -5903,4 +5903,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/light-switch-app/nrfconnect/README.md b/examples/light-switch-app/nrfconnect/README.md index ee78d91c2f7bd8..943759735f2bc2 100644 --- a/examples/light-switch-app/nrfconnect/README.md +++ b/examples/light-switch-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect Light Switch Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF Connect Light Switch Example demonstrates how to remotely control a lighting devices such as light bulbs or LEDs. The application should be used together with the @@ -199,18 +215,18 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| -| [nRF7002 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF7002-DK) | `nrf7002dk_nrf5340_cpuapp` |
nRF7002 DKnRF7002 DK
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF7002 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF7002-DK) | `nrf7002dk/nrf5340/cpuapp` |
nRF7002 DKnRF7002 DK
| ### IPv6 network support The development kits for this sample offer the following IPv6 network support for Matter: -- Matter over Thread is supported for `nrf52840dk_nrf52840` and - `nrf5340dk_nrf5340_cpuapp`. -- Matter over Wi-Fi is supported for `nrf7002dk_nrf5340_cpuapp`. +- Matter over Thread is supported for `nrf52840dk/nrf52840` and + `nrf5340dk/nrf5340/cpuapp`. +- Matter over Wi-Fi is supported for `nrf7002dk/nrf5340/cpuapp`. ### Additional requirements for testing @@ -341,9 +357,9 @@ connection to Nordic Semiconductor's kit. To enable the Matter CLI, you must compile the Light Switch Example application with the additional option **-DCONFIG_CHIP_LIB_SHELL=y**. Run the following command with _build-target_ replaced with the build target name of Nordic -Semiconductor's kit you are using (for example, `nrf52840dk_nrf52840`): +Semiconductor's kit you are using (for example, `nrf52840dk/nrf52840`): - west build -b build-target -- -DCONFIG_CHIP_LIB_SHELL=y + west build -b build-target --sysbuild -- -DCONFIG_CHIP_LIB_SHELL=y You can use the following commands to control a device that is programmed with the Light Switch Example application by using the Matter CLI: @@ -441,14 +457,15 @@ Complete the following steps to build the sample: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: - $ west build -b build-target + $ west build -b build-target --sysbuild You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -463,7 +480,7 @@ following command: To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -474,15 +491,9 @@ Support for DFU using Matter OTA is enabled by default. To enable DFU over Bluetooth LE, run the following command with _build-target_ replaced with the build target name of the Nordic Semiconductor kit you are -using (for example `nrf52840dk_nrf52840`): - - $ west build -b build-target -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y - -To completely disable support for both DFU methods, run the following command -with _build-target_ replaced with the build target name of the Nordic -Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): +using (for example `nrf52840dk/nrf52840`): - $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf + $ west build -b build-target --sysbuild -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y > **Note**: > @@ -496,7 +507,7 @@ Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. Make sure to keep the configuration consistent with changes made to the application configuration. This is necessary for the configuration to work, as @@ -513,8 +524,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -526,7 +538,7 @@ using the menuconfig utility. To open the menuconfig utility, run the following command from the example directory: - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -556,9 +568,6 @@ depending on the selected board: command-line shell. - release -- Release version of the application - can be used to enable only the necessary application functionalities to optimize its performance. -- no_dfu -- Debug version of the application without Device Firmware Upgrade - feature support - can be used only for the nRF52840 DK and nRF5340 DK, as - those platforms have DFU enabled by default. For more information, see the [Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter index 58459bccdd7a50..95d6ae8194cc56 100644 --- a/examples/light-switch-app/qpg/zap/switch.matter +++ b/examples/light-switch-app/qpg/zap/switch.matter @@ -451,7 +451,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -467,12 +467,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -508,17 +538,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -1041,6 +1095,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1049,6 +1106,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1059,6 +1120,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1092,12 +1157,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -3080,7 +3156,7 @@ endpoint 2 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 30; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } } diff --git a/examples/light-switch-app/qpg/zap/switch.zap b/examples/light-switch-app/qpg/zap/switch.zap index 5578a0ff63b5e8..4509b773fac6ee 100644 --- a/examples/light-switch-app/qpg/zap/switch.zap +++ b/examples/light-switch-app/qpg/zap/switch.zap @@ -6488,7 +6488,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6569,4 +6569,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter index 0197bf3889fdea..55f7f290e1f474 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -772,6 +826,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -780,6 +837,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -790,6 +851,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -823,12 +888,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter index d7b7fe74b541f5..1b12b77e99a9fb 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -772,6 +826,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -780,6 +837,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -790,6 +851,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -823,12 +888,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter index 3f36ce92b119da..91d870bf308d5a 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -772,6 +826,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -780,6 +837,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -790,6 +851,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -823,12 +888,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index 32c4eaa0dc80cb..923357f63d2d12 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -772,6 +826,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -780,6 +837,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -790,6 +851,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -823,12 +888,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -2673,7 +2749,7 @@ endpoint 0 { ram attribute numberOfPositions default = 2; ram attribute currentPosition; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } server cluster AdministratorCommissioning { diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 730b68027a4cb1..04abf7714a1a9c 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -3524,7 +3524,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -5932,4 +5932,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/lighting-app/nrfconnect/README.md b/examples/lighting-app/nrfconnect/README.md index b5ef3d7024a0f6..3ba3c74f56d70f 100644 --- a/examples/lighting-app/nrfconnect/README.md +++ b/examples/lighting-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect Lighting Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF Connect Lighting Example demonstrates how to remotely control a white dimmable light bulb. It uses buttons to test changing the lighting and device states and LEDs to show the state of these changes. You can use this example as @@ -153,10 +169,10 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ------------------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| -| [nRF52840 Dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) | `nrf52840dongle_nrf52840` |
nRF52840 DonglenRF52840 Dongle
| -| [nRF7002 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF7002-DK) | `nrf7002dk_nrf5340_cpuapp` |
nRF7002 DKnRF7002 DK
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF52840 Dongle](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle) | `nrf52840dongle/nrf52840` |
nRF52840 DonglenRF52840 Dongle
| +| [nRF7002 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF7002-DK) | `nrf7002dk/nrf5340/cpuapp` |
nRF7002 DKnRF7002 DK
|
@@ -165,9 +181,9 @@ The example supports building and running on the following devices: The development kits for this sample offer the following IPv6 network support for Matter: -- Matter over Thread is supported for `nrf52840dk_nrf52840` and - `nrf5340dk_nrf5340_cpuapp`. -- Matter over Wi-Fi is supported for `nrf7002dk_nrf5340_cpuapp`. +- Matter over Thread is supported for `nrf52840dk/nrf52840` and + `nrf5340dk/nrf5340/cpuapp`. +- Matter over Wi-Fi is supported for `nrf7002dk/nrf5340/cpuapp`. ## Device UI @@ -339,16 +355,17 @@ Complete the following steps to build the sample: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: ``` - $ west build -b build-target + $ west build -b build-target --sysbuild ``` You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -366,7 +383,7 @@ To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: ``` - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release ``` Remember to replace _build-target_ with the build target name of the Nordic @@ -381,7 +398,7 @@ command with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own: ``` - $ west build -b build-target -- -DOVERLAY_CONFIG=rpc.overlay + $ west build -b build-target --sysbuild -- -DOVERLAY_CONFIG=rpc.overlay ``` ### Building with Device Firmware Upgrade support @@ -390,18 +407,10 @@ Support for DFU using Matter OTA is enabled by default. To enable DFU over Bluetooth LE, run the following command with _build-target_ replaced with the build target name of the Nordic Semiconductor kit you are -using (for example `nrf52840dk_nrf52840`): - - ``` - $ west build -b build-target -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y - ``` - -To completely disable support for both DFU methods, run the following command -with _build-target_ replaced with the build target name of the Nordic -Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): +using (for example `nrf52840dk/nrf52840`): ``` - $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf + $ west build -b build-target --sysbuild -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y ``` > **Note**: @@ -419,7 +428,7 @@ Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. Make sure to keep the configuration consistent with changes made to the application configuration. This is necessary for the configuration to work, as @@ -436,8 +445,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -450,7 +460,7 @@ To open the menuconfig utility, run the following command from the example directory: ``` - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig ``` Remember to replace _build-target_ with the build target name of the Nordic @@ -484,9 +494,6 @@ depending on the selected board: the necessary application functionalities to optimize its performance. It can be used only for the nRF52840 DK and nRF5340 DK, as those platforms have DFU enabled by default. -- no_dfu -- Debug version of the application without Device Firmware Upgrade - feature support - can be used for the nRF52840 DK, nRF5340 DK and nRF52840 - Dongle. For more information, see the [Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.matter b/examples/lighting-app/nxp/zap/lighting-on-off.matter index da5e202dd6f39e..f3f3aa85fa80a7 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.matter +++ b/examples/lighting-app/nxp/zap/lighting-on-off.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -711,6 +765,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -719,6 +776,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -729,6 +790,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -762,12 +827,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter index 78c8e02efd12fe..fbc6127e636ab5 100644 --- a/examples/lighting-app/qpg/zap/light.matter +++ b/examples/lighting-app/qpg/zap/light.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -711,6 +765,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -719,6 +776,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -729,6 +790,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -762,12 +827,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter index 0974c4e01cd111..246770a4b57bd2 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -772,6 +826,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -780,6 +837,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -790,6 +851,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -823,12 +888,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter index 7f4ad51da871b3..179a3832a5e732 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter @@ -380,7 +380,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -396,12 +396,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -437,17 +467,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -1031,6 +1085,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1039,6 +1096,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1049,6 +1110,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1082,12 +1147,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter index 7c6ef7908ad7d6..f8db39db377c91 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -463,6 +517,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -471,6 +528,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -481,6 +542,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -514,12 +579,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lit-icd-app/nrfconnect/README.md b/examples/lit-icd-app/nrfconnect/README.md index 704950fdcac63e..1ff58274962fd9 100644 --- a/examples/lit-icd-app/nrfconnect/README.md +++ b/examples/lit-icd-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect LIT ICD Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF Connect LIT ICD Example allows to test the device that utilizes Long Idle Time feature from the Intermittently Connected Device Management cluster. It uses buttons to change the device states and LEDs to show the state of these @@ -115,8 +131,8 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
|
@@ -248,14 +264,15 @@ Complete the following steps to build the sample: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: - $ west build -b build-target + $ west build -b build-target --sysbuild You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -270,7 +287,7 @@ following command: To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -279,12 +296,6 @@ Semiconductor's kit you own. Support for DFU using Matter OTA is enabled by default. -To completely disable support for DFU, run the following command with -_build-target_ replaced with the build target name of the Nordic Semiconductor -kit you are using (for example `nrf52840dk_nrf52840`): - - $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf - > **Note**: > > There are two types of Device Firmware Upgrade modes: single-image DFU and @@ -297,7 +308,7 @@ kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. Make sure to keep the configuration consistent with changes made to the application configuration. This is necessary for the configuration to work, as @@ -314,8 +325,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -327,7 +339,7 @@ using the menuconfig utility. To open the menuconfig utility, run the following command from the example directory: - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -357,8 +369,6 @@ depending on the selected board: command-line shell. - release -- Release version of the application - can be used to enable only the necessary application functionalities to optimize its performance. -- no_dfu -- Debug version of the application without Device Firmware Upgrade - feature support. For more information, see the [Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index a1eb98313bcfa9..5ee4744f901fde 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -739,6 +793,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -747,6 +804,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -757,6 +818,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -790,12 +855,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -2549,7 +2625,7 @@ endpoint 0 { callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0; + ram attribute featureMap default = 1; callback attribute clusterRevision; } diff --git a/examples/lock-app/lock-common/lock-app.zap b/examples/lock-app/lock-common/lock-app.zap index 605da39d72da56..8e25d9248c1429 100644 --- a/examples/lock-app/lock-common/lock-app.zap +++ b/examples/lock-app/lock-common/lock-app.zap @@ -401,7 +401,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lock-app/nrfconnect/README.md b/examples/lock-app/nrfconnect/README.md index 654f6988c8056f..14385357bc56df 100644 --- a/examples/lock-app/nrfconnect/README.md +++ b/examples/lock-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect Lock Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF Connect Lock Example demonstrates how to remotely control a door lock device with one basic bolt. It uses buttons to test changing the lock and device states and LEDs to show the state of these changes. You can use this example as @@ -148,9 +164,9 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| -| [nRF7002 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF7002-DK) | `nrf7002dk_nrf5340_cpuapp` |
nRF7002 DKnRF7002 DK
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF7002 DK](https://www.nordicsemi.com/Products/Development-hardware/nRF7002-DK) | `nrf7002dk/nrf5340/cpuapp` |
nRF7002 DKnRF7002 DK
|
@@ -159,9 +175,9 @@ The example supports building and running on the following devices: The development kits for this sample offer the following IPv6 network support for Matter: -- Matter over Thread is supported for `nrf52840dk_nrf52840` and - `nrf5340dk_nrf5340_cpuapp`. -- Matter over Wi-Fi is supported for `nrf7002dk_nrf5340_cpuapp`. +- Matter over Thread is supported for `nrf52840dk/nrf52840` and + `nrf5340dk/nrf5340/cpuapp`. +- Matter over Wi-Fi is supported for `nrf7002dk/nrf5340/cpuapp`. ## Device UI @@ -325,14 +341,15 @@ Complete the following steps to build the sample: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: - $ west build -b build-target + $ west build -b build-target --sysbuild You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -347,7 +364,7 @@ following command: To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -358,15 +375,9 @@ Support for DFU using Matter OTA is enabled by default. To enable DFU over Bluetooth LE, run the following command with _build-target_ replaced with the build target name of the Nordic Semiconductor kit you are -using (for example `nrf52840dk_nrf52840`): - - $ west build -b build-target -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y - -To completely disable support for both DFU methods, run the following command -with _build-target_ replaced with the build target name of the Nordic -Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): +using (for example `nrf52840dk/nrf52840`): - $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf + $ west build -b build-target --sysbuild -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y > **Note**: > @@ -380,7 +391,7 @@ Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. Make sure to keep the configuration consistent with changes made to the application configuration. This is necessary for the configuration to work, as @@ -397,8 +408,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -410,7 +422,7 @@ using the menuconfig utility. To open the menuconfig utility, run the following command from the example directory: - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -440,9 +452,6 @@ depending on the selected board: command-line shell. - release -- Release version of the application - can be used to enable only the necessary application functionalities to optimize its performance. -- no_dfu -- Debug version of the application without Device Firmware Upgrade - feature support - can be used only for the nRF52840 DK and nRF5340 DK, as - those platforms have DFU enabled by default. For more information, see the [Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) diff --git a/examples/lock-app/nxp/zap/lock-app.matter b/examples/lock-app/nxp/zap/lock-app.matter index 047f200ffb6f4d..f44c1531169ae0 100644 --- a/examples/lock-app/nxp/zap/lock-app.matter +++ b/examples/lock-app/nxp/zap/lock-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -283,6 +337,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -291,6 +348,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -301,6 +362,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -334,12 +399,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter index 4a067071261767..18ef74944ebc63 100644 --- a/examples/lock-app/qpg/zap/lock.matter +++ b/examples/lock-app/qpg/zap/lock.matter @@ -183,7 +183,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -199,12 +199,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -240,17 +270,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -514,6 +568,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -522,6 +579,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -532,6 +593,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -565,12 +630,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/log-source-app/log-source-common/log-source-app.matter b/examples/log-source-app/log-source-common/log-source-app.matter index b4ae99ffdb58bb..829e40f870c1a3 100644 --- a/examples/log-source-app/log-source-common/log-source-app.matter +++ b/examples/log-source-app/log-source-common/log-source-app.matter @@ -23,7 +23,7 @@ struct TestGlobalStruct { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -39,12 +39,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -80,17 +110,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster is used to manage global aspects of the Commissioning flow. */ @@ -103,6 +157,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -111,6 +168,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -121,6 +182,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -154,12 +219,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter index 3d03cf5fffcdca..bdfe6910c5cffd 100644 --- a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter +++ b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -327,6 +381,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -335,6 +392,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -345,6 +406,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -378,12 +443,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/network-manager-app/linux/BUILD.gn b/examples/network-manager-app/linux/BUILD.gn index 1dee694c38616e..ea973edfbfd15c 100644 --- a/examples/network-manager-app/linux/BUILD.gn +++ b/examples/network-manager-app/linux/BUILD.gn @@ -15,7 +15,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -executable("network-manager-app") { +executable("matter-network-manager-app") { sources = [ "include/CHIPProjectAppConfig.h", "main.cpp", @@ -32,7 +32,7 @@ executable("network-manager-app") { } group("linux") { - deps = [ ":network-manager-app" ] + deps = [ ":matter-network-manager-app" ] } group("default") { diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.matter b/examples/network-manager-app/network-manager-common/network-manager-app.matter index dd37ffc02a635c..f8600afd71dc8c 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.matter +++ b/examples/network-manager-app/network-manager-common/network-manager-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -283,6 +337,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -291,6 +348,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -301,6 +362,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -334,12 +399,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1193,10 +1269,11 @@ cluster GroupKeyManagement = 63 { } /** Functionality to retrieve operational information about a managed Wi-Fi network. */ -cluster WiFiNetworkManagement = 1105 { +provisional cluster WiFiNetworkManagement = 1105 { revision 1; - readonly attribute nullable octet_string<32> ssid = 1; + readonly attribute nullable octet_string<32> ssid = 0; + readonly attribute access(read: manage) nullable int64u passphraseSurrogate = 1; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1209,11 +1286,11 @@ cluster WiFiNetworkManagement = 1105 { } /** Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. */ - command access(invoke: administer) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0; + command access(invoke: manage) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0; } /** Manages the names and credentials of Thread networks visible to the user. */ -cluster ThreadNetworkDirectory = 1107 { +provisional cluster ThreadNetworkDirectory = 1107 { revision 1; struct ThreadNetworkStruct { @@ -1254,7 +1331,7 @@ cluster ThreadNetworkDirectory = 1107 { /** Removes an entry from the ThreadNetworks list. */ timed command access(invoke: manage) RemoveNetwork(RemoveNetworkRequest): DefaultSuccess = 1; /** Retrieves a Thread Operational Dataset from the ThreadNetworks list. */ - timed command GetOperationalDataset(GetOperationalDatasetRequest): OperationalDatasetResponse = 2; + command GetOperationalDataset(GetOperationalDatasetRequest): OperationalDatasetResponse = 2; } endpoint 0 { @@ -1525,6 +1602,7 @@ endpoint 1 { server cluster WiFiNetworkManagement { callback attribute ssid; + callback attribute passphraseSurrogate; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.zap b/examples/network-manager-app/network-manager-common/network-manager-app.zap index ec8316ce2ad3c0..64113c969dd774 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.zap +++ b/examples/network-manager-app/network-manager-common/network-manager-app.zap @@ -3238,7 +3238,7 @@ "attributes": [ { "name": "SSID", - "code": 1, + "code": 0, "mfgCode": null, "side": "server", "type": "octet_string", @@ -3252,6 +3252,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "PassphraseSurrogate", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, diff --git a/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter b/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter index 4f298e5d5ab176..4385f8b6d252df 100644 --- a/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter +++ b/examples/ota-provider-app/ota-provider-common/ota-provider-app.matter @@ -56,7 +56,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -72,12 +72,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -113,17 +143,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** The Access Control Cluster exposes a data model view of a @@ -131,7 +185,7 @@ cluster AccessControl = 31 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -147,12 +201,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -188,17 +272,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -445,6 +553,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -453,6 +564,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -463,6 +578,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -496,12 +615,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ 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 dfc59294f9c43a..4afe132a484702 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 @@ -255,7 +255,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -271,12 +271,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -312,17 +342,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -647,6 +701,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -655,6 +712,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -665,6 +726,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -698,12 +763,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 9c1a05687d3c6a..665714e076ed91 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -627,7 +627,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -643,12 +643,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -684,17 +714,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ @@ -1370,6 +1424,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1378,6 +1435,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1388,6 +1449,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1421,12 +1486,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** This cluster is used to manage global aspects of the Commissioning flow. */ @@ -1439,6 +1515,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1447,6 +1526,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1457,6 +1540,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1490,12 +1577,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -2387,8 +2485,12 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct KeepActiveRequest { + int32u stayActiveDuration = 0; + } + /** The server SHALL attempt to keep the devices specified active for StayActiveDuration milliseconds when they are next active. */ - command KeepActive(): DefaultSuccess = 128; + command KeepActive(KeepActiveRequest): DefaultSuccess = 128; } /** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. @@ -4825,7 +4927,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -4951,11 +5054,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5061,8 +5159,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5106,10 +5203,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5128,8 +5221,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring and controlling the functionality of a thermostat. */ @@ -5186,7 +5277,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5312,11 +5404,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5422,8 +5509,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5467,10 +5553,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5489,8 +5571,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring the user interface of a thermostat (which may be remote from the thermostat). */ @@ -8573,7 +8653,7 @@ endpoint 0 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } server cluster AdministratorCommissioning { diff --git a/examples/placeholder/linux/apps/app1/config.zap b/examples/placeholder/linux/apps/app1/config.zap index 090e4f74c60881..e16b695e63f9e4 100644 --- a/examples/placeholder/linux/apps/app1/config.zap +++ b/examples/placeholder/linux/apps/app1/config.zap @@ -4890,7 +4890,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -5028,7 +5028,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -15129,4 +15129,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index a48b8accff55c5..d1fd025cef5bff 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -627,7 +627,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -643,12 +643,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -684,17 +714,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ @@ -1327,6 +1381,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1335,6 +1392,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1345,6 +1406,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1378,12 +1443,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** This cluster is used to manage global aspects of the Commissioning flow. */ @@ -1396,6 +1472,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1404,6 +1483,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1414,6 +1497,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1447,12 +1534,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -2344,8 +2442,12 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct KeepActiveRequest { + int32u stayActiveDuration = 0; + } + /** The server SHALL attempt to keep the devices specified active for StayActiveDuration milliseconds when they are next active. */ - command KeepActive(): DefaultSuccess = 128; + command KeepActive(KeepActiveRequest): DefaultSuccess = 128; } /** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. @@ -4782,7 +4884,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -4908,11 +5011,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5018,8 +5116,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5063,10 +5160,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5085,8 +5178,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring and controlling the functionality of a thermostat. */ @@ -5143,7 +5234,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5269,11 +5361,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5379,8 +5466,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5424,10 +5510,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5446,8 +5528,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring the user interface of a thermostat (which may be remote from the thermostat). */ @@ -8531,7 +8611,7 @@ endpoint 0 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; } server cluster AdministratorCommissioning { diff --git a/examples/placeholder/linux/apps/app2/config.zap b/examples/placeholder/linux/apps/app2/config.zap index bcd64d2189d645..56e97fa89a0ab1 100644 --- a/examples/placeholder/linux/apps/app2/config.zap +++ b/examples/placeholder/linux/apps/app2/config.zap @@ -4906,7 +4906,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -5044,7 +5044,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -14889,4 +14889,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/platform/esp32/external_platform/ESP32_custom/BUILD.gn b/examples/platform/esp32/external_platform/ESP32_custom/BUILD.gn index d8d2f92b542ac7..93b00ef8f81617 100644 --- a/examples/platform/esp32/external_platform/ESP32_custom/BUILD.gn +++ b/examples/platform/esp32/external_platform/ESP32_custom/BUILD.gn @@ -29,6 +29,7 @@ declare_args() { chip_bt_bluedroid_enabled = true chip_max_discovered_ip_addresses = 5 chip_enable_route_hook = false + chip_enable_thread_border_router = false } buildconfig_header("custom_buildconfig") { diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index 6a6deae1473084..307b3428126db2 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -367,12 +367,15 @@ int ChipLinuxAppInit(int argc, char * const argv[], OptionSet * customOptions, #if CONFIG_NETWORK_LAYER_BLE RendezvousInformationFlags rendezvousFlags = RendezvousInformationFlag::kBLE; #else // CONFIG_NETWORK_LAYER_BLE - RendezvousInformationFlag rendezvousFlags = RendezvousInformationFlag::kOnNetwork; + RendezvousInformationFlags rendezvousFlags = RendezvousInformationFlag::kOnNetwork; #endif // CONFIG_NETWORK_LAYER_BLE #ifdef CONFIG_RENDEZVOUS_MODE rendezvousFlags = static_cast(CONFIG_RENDEZVOUS_MODE); #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + rendezvousFlags.Set(RendezvousInformationFlag::kWiFiPAF); +#endif err = Platform::MemoryInit(); SuccessOrExit(err); @@ -471,6 +474,20 @@ int ChipLinuxAppInit(int argc, char * const argv[], OptionSet * customOptions, } } #endif // CHIP_DEVICE_CONFIG_ENABLE_WPA +#if CHIP_DEVICE_CONFIG_ENABLE_WPA && CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + ChipLogProgress(NotSpecified, "WiFi-PAF: initialzing"); + if (LinuxDeviceOptions::GetInstance().mWiFi) + { + if (EnsureWiFiIsStarted()) + { + ChipLogProgress(NotSpecified, "Wi-Fi Management started"); + DeviceLayer::ConnectivityManager::WiFiPAFAdvertiseParam args; + args.enable = LinuxDeviceOptions::GetInstance().mWiFiPAF; + args.ExtCmds = LinuxDeviceOptions::GetInstance().mWiFiPAFExtCmds; + DeviceLayer::ConnectivityMgr().SetWiFiPAFAdvertisingEnabled(args); + } + } +#endif #if CHIP_ENABLE_OPENTHREAD if (LinuxDeviceOptions::GetInstance().mThread) diff --git a/examples/platform/linux/BUILD.gn b/examples/platform/linux/BUILD.gn index a63175b51200eb..410b1a189245d2 100644 --- a/examples/platform/linux/BUILD.gn +++ b/examples/platform/linux/BUILD.gn @@ -54,6 +54,10 @@ source_set("energy-reporting-test-event-trigger") { sources = [ "${chip_root}/src/app/clusters/electrical-energy-measurement-server/EnergyReportingTestEventTriggerHandler.h" ] } +source_set("water-heater-management-test-event-trigger") { + sources = [ "${chip_root}/src/app/clusters/water-heater-management-server/WaterHeaterManagementTestEventTriggerHandler.h" ] +} + source_set("device-energy-management-test-event-trigger") { sources = [ "${chip_root}/src/app/clusters/device-energy-management-server/DeviceEnergyManagementTestEventTriggerHandler.h" ] } @@ -85,6 +89,7 @@ source_set("app-main") { ":energy-evse-test-event-trigger", ":energy-reporting-test-event-trigger", ":smco-test-event-trigger", + ":water-heater-management-test-event-trigger", "${chip_root}/src/controller:controller", "${chip_root}/src/controller:gen_check_chip_controller_headers", "${chip_root}/src/lib", diff --git a/examples/platform/linux/Options.cpp b/examples/platform/linux/Options.cpp index 9d6edc8bc43846..9b83d126c1f495 100644 --- a/examples/platform/linux/Options.cpp +++ b/examples/platform/linux/Options.cpp @@ -106,6 +106,9 @@ enum #if CHIP_WITH_NLFAULTINJECTION kDeviceOption_FaultInjection, #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + kDeviceOption_WiFi_PAF, +#endif }; constexpr unsigned kAppUsageLength = 64; @@ -117,6 +120,9 @@ OptionDef sDeviceOptionDefs[] = { #if CHIP_DEVICE_CONFIG_ENABLE_WIFI { "wifi", kNoArgument, kDeviceOption_WiFi }, { "wifi-supports-5g", kNoArgument, kDeviceOption_WiFiSupports5g }, +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + { "wifipaf", kArgumentRequired, kDeviceOption_WiFi_PAF }, +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF #endif // CHIP_DEVICE_CONFIG_ENABLE_WPA #if CHIP_ENABLE_OPENTHREAD { "thread", kNoArgument, kDeviceOption_Thread }, @@ -189,6 +195,12 @@ const char * sDeviceOptionHelp = " --wifi-supports-5g\n" " Indicate that local Wi-Fi hardware should report 5GHz support.\n" #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + "\n" + " --wifipaf freq_list=,... \n" + " Enable Wi-Fi PAF via wpa_supplicant.\n" + " Give an empty string if not setting freq_list: \"\"\n" +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFIPAFs #if CHIP_ENABLE_OPENTHREAD "\n" " --thread\n" @@ -588,6 +600,13 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier, } break; } +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + case kDeviceOption_WiFi_PAF: { + LinuxDeviceOptions::GetInstance().mWiFiPAF = true; + LinuxDeviceOptions::GetInstance().mWiFiPAFExtCmds = aValue; + break; + } #endif default: PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName); diff --git a/examples/platform/linux/Options.h b/examples/platform/linux/Options.h index 51e60f0ab63eca..f921bee4ced554 100644 --- a/examples/platform/linux/Options.h +++ b/examples/platform/linux/Options.h @@ -49,6 +49,10 @@ struct LinuxDeviceOptions bool wifiSupports5g = false; bool mWiFi = false; bool mThread = false; +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + bool mWiFiPAF = false; + const char * mWiFiPAFExtCmds = nullptr; +#endif #if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE || CHIP_DEVICE_ENABLE_PORT_PARAMS uint16_t securedDevicePort = CHIP_PORT; uint16_t unsecuredCommissionerPort = CHIP_UDC_PORT; diff --git a/examples/pump-app/nrfconnect/README.md b/examples/pump-app/nrfconnect/README.md index 50e8a1b0e6d0a0..16fbc2f0143c2c 100644 --- a/examples/pump-app/nrfconnect/README.md +++ b/examples/pump-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect Pump Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF Connect Pump Example demonstrates how to remotely control a pump device with basic start/stop functionality. It uses buttons to test changing the pump state and device states and LEDs to show the state of these changes. This @@ -139,8 +155,8 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
|
@@ -283,14 +299,15 @@ Complete the following steps to build the sample: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: - $ west build -b build-target + $ west build -b build-target --sysbuild You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -305,7 +322,7 @@ following command: To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -316,15 +333,9 @@ Support for DFU using Matter OTA is enabled by default. To enable DFU over Bluetooth LE, run the following command with _build-target_ replaced with the build target name of the Nordic Semiconductor kit you are -using (for example `nrf52840dk_nrf52840`): - - $ west build -b build-target -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y - -To completely disable support for both DFU methods, run the following command -with _build-target_ replaced with the build target name of the Nordic -Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): +using (for example `nrf52840dk/nrf52840`): - $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf + $ west build -b build-target --sysbuild -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y > **Note**: > @@ -341,7 +352,7 @@ Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. Make sure to keep the configuration consistent with changes made to the application configuration. This is necessary for the configuration to work, as @@ -358,8 +369,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -371,7 +383,7 @@ using the menuconfig utility. To open the menuconfig utility, run the following command from the example directory: - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -401,9 +413,6 @@ depending on the selected board: command-line shell. - release -- Release version of the application - can be used to enable only the necessary application functionalities to optimize its performance. -- no_dfu -- Debug version of the application without Device Firmware Upgrade - feature support - can be used only for the nRF52840 DK and nRF5340 DK, as - those platforms have DFU enabled by default. For more information, see the [Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) diff --git a/examples/pump-app/pump-common/pump-app.matter b/examples/pump-app/pump-common/pump-app.matter index 8fe8106230ba4a..d766b7d9c61ff1 100644 --- a/examples/pump-app/pump-common/pump-app.matter +++ b/examples/pump-app/pump-common/pump-app.matter @@ -324,7 +324,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -340,12 +340,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -381,17 +411,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -655,6 +709,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -663,6 +720,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -673,6 +734,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -706,12 +771,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/pump-app/silabs/data_model/pump-thread-app.matter b/examples/pump-app/silabs/data_model/pump-thread-app.matter index 5284799e2c4bdb..cbc0ea3c2d65fc 100644 --- a/examples/pump-app/silabs/data_model/pump-thread-app.matter +++ b/examples/pump-app/silabs/data_model/pump-thread-app.matter @@ -324,7 +324,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -340,12 +340,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -381,17 +411,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -655,6 +709,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -663,6 +720,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -673,6 +734,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -706,12 +771,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/pump-app/silabs/data_model/pump-wifi-app.matter b/examples/pump-app/silabs/data_model/pump-wifi-app.matter index 5284799e2c4bdb..cbc0ea3c2d65fc 100644 --- a/examples/pump-app/silabs/data_model/pump-wifi-app.matter +++ b/examples/pump-app/silabs/data_model/pump-wifi-app.matter @@ -324,7 +324,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -340,12 +340,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -381,17 +411,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -655,6 +709,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -663,6 +720,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -673,6 +734,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -706,12 +771,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/pump-controller-app/nrfconnect/README.md b/examples/pump-controller-app/nrfconnect/README.md index 948aa20f54d0d8..64f37c4bb6a7aa 100644 --- a/examples/pump-controller-app/nrfconnect/README.md +++ b/examples/pump-controller-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect Pump Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF Connect Pump Controller Example demonstrates how to implement a pump controller client device with basic start/stop functionality. It uses buttons to test changing the pump state and device states and LEDs to show the state of @@ -140,8 +156,8 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
|
@@ -283,14 +299,15 @@ Complete the following steps to build the sample: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: - $ west build -b build-target + $ west build -b build-target --sysbuild You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -305,7 +322,7 @@ following command: To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -316,15 +333,9 @@ Support for DFU using Matter OTA is enabled by default. To enable DFU over Bluetooth LE, run the following command with _build-target_ replaced with the build target name of the Nordic Semiconductor kit you are -using (for example `nrf52840dk_nrf52840`): - - $ west build -b build-target -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y - -To completely disable support for both DFU methods, run the following command -with _build-target_ replaced with the build target name of the Nordic -Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): +using (for example `nrf52840dk/nrf52840`): - $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf + $ west build -b build-target --sysbuild -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y > **Note**: > @@ -341,7 +352,7 @@ Semiconductor kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. Make sure to keep the configuration consistent with changes made to the application configuration. This is necessary for the configuration to work, as @@ -358,8 +369,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -371,7 +383,7 @@ using the menuconfig utility. To open the menuconfig utility, run the following command from the example directory: - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -401,9 +413,6 @@ depending on the selected board: command-line shell. - release -- Release version of the application - can be used to enable only the necessary application functionalities to optimize its performance. -- no_dfu -- Debug version of the application without Device Firmware Upgrade - feature support - can be used only for the nRF52840 DK and nRF5340 DK, as - those platforms have DFU enabled by default. For more information, see the [Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) diff --git a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter index b7a8759d59b2ba..be131b84c3a933 100644 --- a/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter +++ b/examples/pump-controller-app/pump-controller-common/pump-controller-app.matter @@ -199,7 +199,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -215,12 +215,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -256,17 +286,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -530,6 +584,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -538,6 +595,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -548,6 +609,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -581,12 +646,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter index d79448d76f5c6e..eea5506b1c60db 100644 --- a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter +++ b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter @@ -56,7 +56,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -72,12 +72,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -113,17 +143,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -320,6 +374,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -328,6 +385,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -338,6 +399,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -371,12 +436,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/rvc-app/linux/BUILD.gn b/examples/rvc-app/linux/BUILD.gn index 2db48c20b27357..0adb4e9c9ae8e9 100644 --- a/examples/rvc-app/linux/BUILD.gn +++ b/examples/rvc-app/linux/BUILD.gn @@ -27,6 +27,7 @@ executable("chip-rvc-app") { "${chip_root}/examples/rvc-app/rvc-common/src/rvc-device.cpp", "${chip_root}/examples/rvc-app/rvc-common/src/rvc-mode-delegates.cpp", "${chip_root}/examples/rvc-app/rvc-common/src/rvc-operational-state-delegate.cpp", + "${chip_root}/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp", "RvcAppCommandDelegate.cpp", "include/CHIPProjectAppConfig.h", "main.cpp", diff --git a/examples/rvc-app/rvc-common/include/rvc-device.h b/examples/rvc-app/rvc-common/include/rvc-device.h index f6a33a6199dd23..092ded91f76272 100644 --- a/examples/rvc-app/rvc-common/include/rvc-device.h +++ b/examples/rvc-app/rvc-common/include/rvc-device.h @@ -2,8 +2,11 @@ #include "rvc-mode-delegates.h" #include "rvc-operational-state-delegate.h" +#include "rvc-service-area-delegate.h" #include #include +#include +#include #include @@ -23,6 +26,9 @@ class RvcDevice RvcOperationalState::RvcOperationalStateDelegate mOperationalStateDelegate; RvcOperationalState::Instance mOperationalStateInstance; + ServiceArea::RvcServiceAreaDelegate mServiceAreaDelegate; + ServiceArea::Instance mServiceAreaInstance; + bool mDocked = false; bool mCharging = false; @@ -37,7 +43,8 @@ class RvcDevice explicit RvcDevice(EndpointId aRvcClustersEndpoint) : mRunModeDelegate(), mRunModeInstance(&mRunModeDelegate, aRvcClustersEndpoint, RvcRunMode::Id, 0), mCleanModeDelegate(), mCleanModeInstance(&mCleanModeDelegate, aRvcClustersEndpoint, RvcCleanMode::Id, 0), mOperationalStateDelegate(), - mOperationalStateInstance(&mOperationalStateDelegate, aRvcClustersEndpoint) + mOperationalStateInstance(&mOperationalStateDelegate, aRvcClustersEndpoint), mServiceAreaDelegate(), + mServiceAreaInstance(&mServiceAreaDelegate, aRvcClustersEndpoint, BitMask(0)) { // set the current-mode at start-up mRunModeInstance.UpdateCurrentMode(RvcRunMode::ModeIdle); diff --git a/examples/rvc-app/rvc-common/include/rvc-service-area-delegate.h b/examples/rvc-app/rvc-common/include/rvc-service-area-delegate.h new file mode 100644 index 00000000000000..e170d2ffeb35ce --- /dev/null +++ b/examples/rvc-app/rvc-common/include/rvc-service-area-delegate.h @@ -0,0 +1,124 @@ +/* + * + * 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 + +namespace chip { +namespace app { +namespace Clusters { + +class RvcDevice; + +namespace ServiceArea { + +class RvcServiceAreaDelegate : public Delegate +{ +private: + // containers for array attributes. + std::vector mSupportedLocations; + std::vector mSupportedMaps; + std::vector mSelectedLocations; + std::vector mProgressList; + +public: + CHIP_ERROR Init() override; + + // command support + bool IsSetSelectedLocationsAllowed(MutableCharSpan statusText) override; + + bool IsValidSelectLocationsSet(const ServiceArea::Commands::SelectLocations::DecodableType & req, + ServiceArea::SelectLocationsStatus & locationStatus, MutableCharSpan statusText) override; + + bool HandleSkipCurrentLocation(MutableCharSpan skipStatusText) override; + + //************************************************************************* + // Supported Locations accessors + + bool IsSupportedLocationsChangeAllowed() override; + + uint32_t GetNumberOfSupportedLocations() override; + + bool GetSupportedLocationByIndex(uint32_t listIndex, ServiceArea::LocationStructureWrapper & supportedLocation) override; + + bool GetSupportedLocationById(uint32_t aLocationId, uint32_t & listIndex, + ServiceArea::LocationStructureWrapper & supportedLocation) override; + + bool AddSupportedLocation(const ServiceArea::LocationStructureWrapper & newLocation, uint32_t & listIndex) override; + + bool ModifySupportedLocation(uint32_t listIndex, const ServiceArea::LocationStructureWrapper & modifiedLocation) override; + + bool ClearSupportedLocations() override; + + //************************************************************************* + // Supported Maps accessors + + bool IsSupportedMapChangeAllowed() override; + + uint32_t GetNumberOfSupportedMaps() override; + + bool GetSupportedMapByIndex(uint32_t listIndex, ServiceArea::MapStructureWrapper & supportedMap) override; + + bool GetSupportedMapById(uint8_t aMapId, uint32_t & listIndex, ServiceArea::MapStructureWrapper & supportedMap) override; + + bool AddSupportedMap(const ServiceArea::MapStructureWrapper & newMap, uint32_t & listIndex) override; + + bool ModifySupportedMap(uint32_t listIndex, const ServiceArea::MapStructureWrapper & newMap) override; + + bool ClearSupportedMaps() override; + + //************************************************************************* + // Selected Locations accessors + + uint32_t GetNumberOfSelectedLocations() override; + + bool GetSelectedLocationByIndex(uint32_t listIndex, uint32_t & selectedLocation) override; + + // IsSelectedLocation() no override + + bool AddSelectedLocation(uint32_t aLocationId, uint32_t & listIndex) override; + + bool ClearSelectedLocations() override; + + //************************************************************************* + // Progress accessors + + uint32_t GetNumberOfProgressElements() override; + + bool GetProgressElementByIndex(uint32_t listIndex, ServiceArea::Structs::ProgressStruct::Type & aProgressElement) override; + + bool GetProgressElementById(uint32_t aLocationId, uint32_t & listIndex, + ServiceArea::Structs::ProgressStruct::Type & aProgressElement) override; + + bool AddProgressElement(const ServiceArea::Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) override; + + bool ModifyProgressElement(uint32_t listIndex, + const ServiceArea::Structs::ProgressStruct::Type & modifiedProgressElement) override; + + bool ClearProgress() override; +}; + +} // namespace ServiceArea + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/rvc-app/rvc-common/rvc-app.matter b/examples/rvc-app/rvc-common/rvc-app.matter index 3887f9c2abcbe2..53f280721d84de 100644 --- a/examples/rvc-app/rvc-common/rvc-app.matter +++ b/examples/rvc-app/rvc-common/rvc-app.matter @@ -106,7 +106,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -122,12 +122,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -163,17 +193,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -283,6 +337,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -291,6 +348,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -301,6 +362,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -334,12 +399,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1132,6 +1208,296 @@ cluster RvcOperationalState = 97 { command GoHome(): OperationalCommandResponse = 128; } +/** The Service Area cluster provides an interface for controlling the locations where a device should operate, and for querying the current location. */ +provisional cluster ServiceArea = 336 { + revision 1; // NOTE: Default/not specifically set + + enum AreaTypeTag : enum8 { + kAisle = 0; + kAttic = 1; + kBackDoor = 2; + kBackYard = 3; + kBalcony = 4; + kBallroom = 5; + kBathroom = 6; + kBedroom = 7; + kBorder = 8; + kBoxroom = 9; + kBreakfastRoom = 10; + kCarport = 11; + kCellar = 12; + kCloakroom = 13; + kCloset = 14; + kConservatory = 15; + kCorridor = 16; + kCraftRoom = 17; + kCupboard = 18; + kDeck = 19; + kDen = 20; + kDining = 21; + kDrawingRoom = 22; + kDressingRoom = 23; + kDriveway = 24; + kElevator = 25; + kEnsuite = 26; + kEntrance = 27; + kEntryway = 28; + kFamilyRoom = 29; + kFoyer = 30; + kFrontDoor = 31; + kFrontYard = 32; + kGameRoom = 33; + kGarage = 34; + kGarageDoor = 35; + kGarden = 36; + kGardenDoor = 37; + kGuestBathroom = 38; + kGuestBedroom = 39; + kGuestRestroom = 40; + kGuestRoom = 41; + kGym = 42; + kHallway = 43; + kHearthRoom = 44; + kKidsRoom = 45; + kKidsBedroom = 46; + kKitchen = 47; + kLarder = 48; + kLaundryRoom = 49; + kLawn = 50; + kLibrary = 51; + kLivingRoom = 52; + kLounge = 53; + kMediaTVRoom = 54; + kMudRoom = 55; + kMusicRoom = 56; + kNursery = 57; + kOffice = 58; + kOutdoorKitchen = 59; + kOutside = 60; + kPantry = 61; + kParkingLot = 62; + kParlor = 63; + kPatio = 64; + kPlayRoom = 65; + kPoolRoom = 66; + kPorch = 67; + kPrimaryBathroom = 68; + kPrimaryBedroom = 69; + kRamp = 70; + kReceptionRoom = 71; + kRecreationRoom = 72; + kRestroom = 73; + kRoof = 74; + kSauna = 75; + kScullery = 76; + kSewingRoom = 77; + kShed = 78; + kSideDoor = 79; + kSideYard = 80; + kSittingRoom = 81; + kSnug = 82; + kSpa = 83; + kStaircase = 84; + kSteamRoom = 85; + kStorageRoom = 86; + kStudio = 87; + kStudy = 88; + kSunRoom = 89; + kSwimmingPool = 90; + kTerrace = 91; + kUtilityRoom = 92; + kWard = 93; + kWorkshop = 94; + } + + enum FloorSurfaceTag : enum8 { + kCarpet = 0; + kCeramic = 1; + kConcrete = 2; + kCork = 3; + kDeepCarpet = 4; + kDirt = 5; + kEngineeredWood = 6; + kGlass = 7; + kGrass = 8; + kHardwood = 9; + kLaminate = 10; + kLinoleum = 11; + kMat = 12; + kMetal = 13; + kPlastic = 14; + kPolishedConcrete = 15; + kRubber = 16; + kRug = 17; + kSand = 18; + kStone = 19; + kTatami = 20; + kTerrazzo = 21; + kTile = 22; + kVinyl = 23; + } + + enum LandmarkTag : enum8 { + kAirConditioner = 0; + kAirPurifier = 1; + kBackDoor = 2; + kBarStool = 3; + kBathMat = 4; + kBathtub = 5; + kBed = 6; + kBookshelf = 7; + kChair = 8; + kChristmasTree = 9; + kCoatRack = 10; + kCoffeeTable = 11; + kCookingRange = 12; + kCouch = 13; + kCountertop = 14; + kCradle = 15; + kCrib = 16; + kDesk = 17; + kDiningTable = 18; + kDishwasher = 19; + kDoor = 20; + kDresser = 21; + kLaundryDryer = 22; + kFan = 23; + kFireplace = 24; + kFreezer = 25; + kFrontDoor = 26; + kHighChair = 27; + kKitchenIsland = 28; + kLamp = 29; + kLitterBox = 30; + kMirror = 31; + kNightstand = 32; + kOven = 33; + kPetBed = 34; + kPetBowl = 35; + kPetCrate = 36; + kRefrigerator = 37; + kScratchingPost = 38; + kShoeRack = 39; + kShower = 40; + kSideDoor = 41; + kSink = 42; + kSofa = 43; + kStove = 44; + kTable = 45; + kToilet = 46; + kTrashCan = 47; + kLaundryWasher = 48; + kWindow = 49; + kWineCooler = 50; + } + + enum OperationalStatusEnum : enum8 { + kPending = 0; + kOperating = 1; + kSkipped = 2; + kCompleted = 3; + } + + enum PositionTag : enum8 { + kLeft = 0; + kRight = 1; + kTop = 2; + kBottom = 3; + kMiddle = 4; + kRow = 5; + kColumn = 6; + kUnder = 7; + kNextTo = 8; + kAround = 9; + kOn = 10; + kAbove = 11; + kFrontOf = 12; + kBehind = 13; + } + + enum SelectLocationsStatus : enum8 { + kSuccess = 0; + kUnsupportedLocation = 1; + kDuplicatedLocations = 2; + kInvalidInMode = 3; + kInvalidSet = 4; + } + + enum SkipCurrentLocationStatus : enum8 { + kSuccess = 0; + kInvalidLocationList = 1; + kInvalidInMode = 2; + } + + bitmap Feature : bitmap32 { + kListOrder = 0x1; + kSelectWhileRunning = 0x2; + } + + struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; + } + + struct LocationInfoStruct { + nullable LocationDescriptorStruct locationInfo = 0; + nullable LandmarkTag landmarkTag = 1; + nullable PositionTag positionTag = 2; + nullable FloorSurfaceTag surfaceTag = 3; + } + + struct LocationStruct { + int32u locationID = 0; + nullable int8u mapID = 1; + LocationInfoStruct locationInfo = 2; + } + + struct MapStruct { + int8u mapID = 0; + char_string<64> name = 1; + } + + struct ProgressStruct { + int32u locationID = 0; + OperationalStatusEnum status = 1; + optional nullable elapsed_s totalOperationalTime = 2; + optional nullable elapsed_s estimatedTime = 3; + } + + readonly attribute LocationStruct supportedLocations[] = 0; + readonly attribute nullable MapStruct supportedMaps[] = 1; + readonly attribute nullable int32u selectedLocations[] = 2; + readonly attribute optional nullable int32u currentLocation = 3; + readonly attribute optional nullable epoch_s estimatedEndTime = 4; + readonly attribute optional nullable ProgressStruct progress[] = 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 SelectLocationsRequest { + nullable int32u newLocations[] = 0; + } + + response struct SelectLocationsResponse = 1 { + SelectLocationsStatus status = 0; + optional char_string<256> statusText = 1; + } + + response struct SkipCurrentLocationResponse = 3 { + SkipCurrentLocationStatus status = 0; + optional char_string<256> statusText = 1; + } + + /** Command used to select a set of device locations, where the device is to operate */ + command SelectLocations(SelectLocationsRequest): SelectLocationsResponse = 0; + /** This command is used to skip the current location where the device operates. */ + command SkipCurrentLocation(): SkipCurrentLocationResponse = 2; +} + endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -1387,6 +1753,26 @@ endpoint 1 { handle command OperationalCommandResponse; handle command GoHome; } + + server cluster ServiceArea { + callback attribute supportedLocations; + callback attribute supportedMaps; + callback attribute selectedLocations; + callback attribute currentLocation; + callback attribute estimatedEndTime; + callback attribute progress; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command SelectLocations; + handle command SelectLocationsResponse; + handle command SkipCurrentLocation; + handle command SkipCurrentLocationResponse; + } } diff --git a/examples/rvc-app/rvc-common/rvc-app.zap b/examples/rvc-app/rvc-common/rvc-app.zap index 7afc8b7d3b819b..cb3ea7cc0d24c4 100644 --- a/examples/rvc-app/rvc-common/rvc-app.zap +++ b/examples/rvc-app/rvc-common/rvc-app.zap @@ -2877,6 +2877,242 @@ "included": 1 } ] + }, + { + "name": "Service Area", + "code": 336, + "mfgCode": null, + "define": "SERVICE_AREA_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "SelectLocations", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SelectLocationsResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SkipCurrent", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SkipCurrentResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SupportedLocations", + "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": "SupportedMaps", + "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": "SelectedLocations", + "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": "CurrentLocation", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EstimatedEndTime", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "epoch_s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Progress", + "code": 5, + "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": "EventList", + "code": 65530, + "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": "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 + } + ] } ] } diff --git a/examples/rvc-app/rvc-common/src/rvc-device.cpp b/examples/rvc-app/rvc-common/src/rvc-device.cpp index 63da53c0e0ee53..e018e0929301c7 100644 --- a/examples/rvc-app/rvc-common/src/rvc-device.cpp +++ b/examples/rvc-app/rvc-common/src/rvc-device.cpp @@ -6,6 +6,7 @@ using namespace chip::app::Clusters; void RvcDevice::Init() { + mServiceAreaInstance.Init(); mRunModeInstance.Init(); mCleanModeInstance.Init(); mOperationalStateInstance.Init(); diff --git a/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp b/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp new file mode 100644 index 00000000000000..4c66b35b43fe60 --- /dev/null +++ b/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp @@ -0,0 +1,412 @@ +/* + * + * 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 + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ServiceArea; + +CHIP_ERROR RvcServiceAreaDelegate::Init() +{ + // hardcoded fill of SUPPORTED MAPS for prototyping + uint8_t supportedMapId_XX = 3; + uint8_t supportedMapId_YY = 245; + + GetInstance()->AddSupportedMap(supportedMapId_XX, "My Map XX"_span); + GetInstance()->AddSupportedMap(supportedMapId_YY, "My Map YY"_span); + + // hardcoded fill of SUPPORTED LOCATIONS for prototyping + uint32_t supportedLocationId_A = 7; + uint32_t supportedLocationId_B = 1234567; + uint32_t supportedLocationId_C = 10050; + uint32_t supportedLocationId_D = 0x88888888; + + // Location A has name, floor number, uses map XX + GetInstance()->AddSupportedLocation( + supportedLocationId_A, DataModel::Nullable(supportedMapId_XX), "My Location A"_span, + DataModel::Nullable(4), DataModel::Nullable(), + DataModel::Nullable(), DataModel::Nullable(), + DataModel::Nullable()); + + // Location B has name, uses map XX + GetInstance()->AddSupportedLocation( + supportedLocationId_B, DataModel::Nullable(supportedMapId_XX), "My Location B"_span, + DataModel::Nullable(), DataModel::Nullable(), + DataModel::Nullable(), DataModel::Nullable(), + DataModel::Nullable()); + + // Location C has full SemData, no name, Map YY + GetInstance()->AddSupportedLocation(supportedLocationId_C, DataModel::Nullable(supportedMapId_YY), CharSpan(), + DataModel::Nullable(-1), + DataModel::Nullable(ServiceArea::AreaTypeTag::kPlayRoom), + DataModel::Nullable(ServiceArea::LandmarkTag::kBackDoor), + DataModel::Nullable(ServiceArea::PositionTag::kNextTo), + DataModel::Nullable(ServiceArea::FloorSurfaceTag::kConcrete)); + + // Location D has null values for all HomeLocationStruct fields, Map YY + GetInstance()->AddSupportedLocation(supportedLocationId_D, DataModel::Nullable(supportedMapId_YY), + "My Location D"_span, DataModel::Nullable(), + DataModel::Nullable(), + DataModel::Nullable(ServiceArea::LandmarkTag::kCouch), + DataModel::Nullable(ServiceArea::PositionTag::kNextTo), + DataModel::Nullable(ServiceArea::FloorSurfaceTag::kHardwood)); + + GetInstance()->SetCurrentLocation(supportedLocationId_C); + + return CHIP_NO_ERROR; +} + +//************************************************************************* +// command support + +bool RvcServiceAreaDelegate::IsSetSelectedLocationsAllowed(MutableCharSpan statusText) +{ + // TODO IMPLEMENT + return true; +}; + +bool RvcServiceAreaDelegate::IsValidSelectLocationsSet(const Commands::SelectLocations::DecodableType & req, + SelectLocationsStatus & locationStatus, MutableCharSpan statusText) +{ + // TODO IMPLEMENT + return true; +}; + +bool RvcServiceAreaDelegate::HandleSkipCurrentLocation(MutableCharSpan skipStatusText) +{ + // TODO IMPLEMENT + return true; +}; + +//************************************************************************* +// Supported Locations accessors + +bool RvcServiceAreaDelegate::IsSupportedLocationsChangeAllowed() +{ + // TODO IMPLEMENT + return true; +} + +uint32_t RvcServiceAreaDelegate::GetNumberOfSupportedLocations() +{ + return static_cast(mSupportedLocations.size()); +} + +bool RvcServiceAreaDelegate::GetSupportedLocationByIndex(uint32_t listIndex, LocationStructureWrapper & aSupportedLocation) +{ + if (listIndex < mSupportedLocations.size()) + { + aSupportedLocation = mSupportedLocations[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaDelegate::GetSupportedLocationById(uint32_t aLocationId, uint32_t & listIndex, + LocationStructureWrapper & aSupportedLocation) +{ + // We do not need to reimplement this method as it's already done by the SDK. + // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation + // since we have direct access to the list. + listIndex = 0; + + while (listIndex < mSupportedLocations.size()) + { + if (mSupportedLocations[listIndex].locationID == aLocationId) + { + aSupportedLocation = mSupportedLocations[listIndex]; + return true; + } + + ++listIndex; + } + + return false; +}; + +bool RvcServiceAreaDelegate::AddSupportedLocation(const LocationStructureWrapper & newLocation, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate location IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mSupportedLocations.size() < kMaxNumSupportedLocations) + { + // not sorting list, number of locations normally expected to be small, max 255 + mSupportedLocations.push_back(newLocation); + listIndex = static_cast(mSupportedMaps.size()) - 1; // new element is last in list + return true; + } + + ChipLogError(Zcl, "AddSupportedLocation %u - supported locations list is already at maximum size %u", newLocation.locationID, + static_cast(kMaxNumSupportedLocations)); + + return false; +} + +bool RvcServiceAreaDelegate::ModifySupportedLocation(uint32_t listIndex, const LocationStructureWrapper & modifiedLocation) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate location IDs, list size not exceeded, + // etc. + + // Double-check that locationID's match. + if (modifiedLocation.locationID != mSupportedLocations[listIndex].locationID) + { + ChipLogError(Zcl, "ModifySupportedLocation - locationID's do not match, new locationID %u, existing locationID %u", + modifiedLocation.locationID, mSupportedLocations[listIndex].locationID); + return false; + } + + // checks passed, update the attribute + mSupportedLocations[listIndex] = modifiedLocation; + return true; +} + +bool RvcServiceAreaDelegate::ClearSupportedLocations() +{ + if (!mSupportedLocations.empty()) + { + mSupportedLocations.clear(); + return true; + } + + return false; +} + +//************************************************************************* +// Supported Maps accessors + +bool RvcServiceAreaDelegate::IsSupportedMapChangeAllowed() +{ + // TODO IMPLEMENT + return true; +} + +uint32_t RvcServiceAreaDelegate::GetNumberOfSupportedMaps() +{ + return static_cast(mSupportedMaps.size()); +} + +bool RvcServiceAreaDelegate::GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap) +{ + if (listIndex < mSupportedMaps.size()) + { + aSupportedMap = mSupportedMaps[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaDelegate::GetSupportedMapById(uint8_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap) +{ + // We do not need to reimplement this method as it's already done by the SDK. + // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation + // since we have direct access to the list. + listIndex = 0; + + while (listIndex < mSupportedMaps.size()) + { + if (mSupportedMaps[listIndex].mapID == aMapId) + { + aSupportedMap = mSupportedMaps[listIndex]; + return true; + } + + ++listIndex; + } + + return false; +}; + +bool RvcServiceAreaDelegate::AddSupportedMap(const MapStructureWrapper & newMap, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate location IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mSupportedMaps.size() < kMaxNumSupportedMaps) + { + // not sorting list, number of locations normally expected to be small, max 255 + mSupportedMaps.push_back(newMap); + listIndex = static_cast(mSupportedMaps.size()) - 1; // new element is last in list + return true; + } + ChipLogError(Zcl, "AddSupportedMap %u - supported maps list is already at maximum size %u", newMap.mapID, + static_cast(kMaxNumSupportedMaps)); + + return false; +} + +bool RvcServiceAreaDelegate::ModifySupportedMap(uint32_t listIndex, const MapStructureWrapper & modifiedMap) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate location IDs, list size not exceeded, + // etc. + + // Double-check that mapID's match. + if (modifiedMap.mapID != mSupportedMaps[listIndex].mapID) + { + ChipLogError(Zcl, "ModifySupportedMap - mapID's do not match, new mapID %u, existing mapID %u", modifiedMap.mapID, + mSupportedMaps[listIndex].mapID); + return false; + } + + // save modified map + mSupportedMaps[listIndex] = modifiedMap; + return true; +} + +bool RvcServiceAreaDelegate::ClearSupportedMaps() +{ + if (!mSupportedMaps.empty()) + { + mSupportedMaps.clear(); + return true; + } + + return false; +} + +//************************************************************************* +// Selected Locations accessors + +uint32_t RvcServiceAreaDelegate::GetNumberOfSelectedLocations() +{ + return static_cast(mSelectedLocations.size()); +} + +bool RvcServiceAreaDelegate::GetSelectedLocationByIndex(uint32_t listIndex, uint32_t & aSelectedLocation) +{ + if (listIndex < mSelectedLocations.size()) + { + aSelectedLocation = mSelectedLocations[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaDelegate::AddSelectedLocation(uint32_t aLocationId, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate location IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mSelectedLocations.size() < kMaxNumSelectedLocations) + { + // not sorting list, number of locations normally expected to be small, max 255 + mSelectedLocations.push_back(aLocationId); + listIndex = static_cast(mSelectedLocations.size()) - 1; // new element is last in list + return true; + } + ChipLogError(Zcl, "AddSelectedLocation %u - selected locations list is already at maximum size %u", aLocationId, + static_cast(kMaxNumSelectedLocations)); + + return false; +} + +bool RvcServiceAreaDelegate::ClearSelectedLocations() +{ + if (!mSelectedLocations.empty()) + { + mSelectedLocations.clear(); + return true; + } + + return false; +} + +//************************************************************************* +// Progress List accessors + +uint32_t RvcServiceAreaDelegate::GetNumberOfProgressElements() +{ + return static_cast(mProgressList.size()); +} + +bool RvcServiceAreaDelegate::GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement) +{ + if (listIndex < mProgressList.size()) + { + aProgressElement = mProgressList[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaDelegate::GetProgressElementById(uint32_t aLocationId, uint32_t & listIndex, + Structs::ProgressStruct::Type & aProgressElement) +{ + // We do not need to reimplement this method as it's already done by the SDK. + // We are reimplementing this method, still using linear search, but with some optimization on the SDK implementation + // since we have direct access to the list. + listIndex = 0; + + while (listIndex < mProgressList.size()) + { + if (mProgressList[listIndex].locationID == aLocationId) + { + aProgressElement = mProgressList[listIndex]; + return true; + } + + ++listIndex; + } + + return false; +}; + +bool RvcServiceAreaDelegate::AddProgressElement(const Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate location IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mProgressList.size() < kMaxNumProgressElements) + { + // not sorting list, number of locations normally expected to be small, max 255 + mProgressList.push_back(newProgressElement); + listIndex = static_cast(mProgressList.size()) - 1; // new element is last in list + return true; + } + ChipLogError(Zcl, "AddProgressElement %u -progress list is already at maximum size %u", newProgressElement.locationID, + static_cast(kMaxNumProgressElements)); + + return false; +} + +bool RvcServiceAreaDelegate::ModifyProgressElement(uint32_t listIndex, + const Structs::ProgressStruct::Type & modifiedProgressElement) +{ + // TODO IMPLEMENT + return false; +} + +bool RvcServiceAreaDelegate::ClearProgress() +{ + if (!mProgressList.empty()) + { + mProgressList.clear(); + return true; + } + + return false; +} diff --git a/examples/shell/nrfconnect/README.md b/examples/shell/nrfconnect/README.md index f0abf5e312462c..551e0d67c052a1 100644 --- a/examples/shell/nrfconnect/README.md +++ b/examples/shell/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect SDK Shell Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + A [Matter shell](../README.md) project for the Nordic nRF52840 and nRF5340 development kits, built using the nRF Connect SDK. diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter index 84c9d0e8eb2831..ab4f6f7b2e6ee8 100644 --- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter +++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter @@ -183,7 +183,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -199,12 +199,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -240,17 +270,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -834,6 +888,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -842,6 +899,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -852,6 +913,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -885,12 +950,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter index e34c00dfd2e2eb..7b0f7ee75df290 100644 --- a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter +++ b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter @@ -56,7 +56,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -72,12 +72,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -113,17 +143,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -474,6 +528,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -482,6 +539,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -492,6 +553,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -525,12 +590,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/thermostat/linux/BUILD.gn b/examples/thermostat/linux/BUILD.gn index 89d24bff8a0835..71c0eccfcfae50 100644 --- a/examples/thermostat/linux/BUILD.gn +++ b/examples/thermostat/linux/BUILD.gn @@ -20,6 +20,8 @@ executable("thermostat-app") { "include/low-power/LowPowerManager.cpp", "include/low-power/LowPowerManager.h", "main.cpp", + "thermostat-delegate-impl.cpp", + "thermostat-manager.cpp", ] deps = [ @@ -28,6 +30,8 @@ executable("thermostat-app") { "${chip_root}/src/lib", ] + include_dirs = [ "include" ] + cflags = [ "-Wconversion" ] output_dir = root_out_dir diff --git a/examples/thermostat/linux/include/thermostat-delegate-impl.h b/examples/thermostat/linux/include/thermostat-delegate-impl.h new file mode 100644 index 00000000000000..c4daef5fde1d6a --- /dev/null +++ b/examples/thermostat/linux/include/thermostat-delegate-impl.h @@ -0,0 +1,100 @@ +/* + * + * 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 app { +namespace Clusters { +namespace Thermostat { + +/** + * The ThermostatDelegate class serves as the instance delegate for storing Presets related information and providing it to the + * Thermostat server code. It also manages the presets attribute and provides methods to write to presets, edit presets, maintain a + * pending presets list and either commit the presets when requested or discard the changes. It also provides APIs to get and set + * the attribute values. + * + */ + +static constexpr uint8_t kMaxNumberOfPresetTypes = 6; + +// TODO: #34556 Support multiple presets of each type. +// We will support only one preset of each preset type. +static constexpr uint8_t kMaxNumberOfPresetsOfEachType = 1; + +class ThermostatDelegate : public Delegate +{ +public: + static inline ThermostatDelegate & GetInstance() { return sInstance; } + + CHIP_ERROR GetPresetTypeAtIndex(size_t index, Structs::PresetTypeStruct::Type & presetType) override; + + uint8_t GetNumberOfPresets() override; + + CHIP_ERROR GetPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) override; + + CHIP_ERROR GetActivePresetHandle(MutableByteSpan & activePresetHandle) override; + + CHIP_ERROR SetActivePresetHandle(const DataModel::Nullable & newActivePresetHandle) override; + + CHIP_ERROR AppendToPendingPresetList(const Structs::PresetStruct::Type & preset) override; + + CHIP_ERROR GetPendingPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) override; + + CHIP_ERROR ApplyPendingPresets() override; + + void ClearPendingPresetList() override; + +private: + static ThermostatDelegate sInstance; + + ThermostatDelegate(); + ~ThermostatDelegate() = default; + + ThermostatDelegate(const ThermostatDelegate &) = delete; + ThermostatDelegate & operator=(const ThermostatDelegate &) = delete; + + /** + * @brief Initializes the preset types array with all preset types corresponding to PresetScenarioEnum. + */ + void InitializePresetTypes(); + + /** + * @brief Initializes the presets array with some sample presets for testing. + */ + void InitializePresets(); + + uint8_t mNumberOfPresets; + + Structs::PresetTypeStruct::Type mPresetTypes[kMaxNumberOfPresetTypes]; + PresetStructWithOwnedMembers mPresets[kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType]; + PresetStructWithOwnedMembers mPendingPresets[kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType]; + + uint8_t mNextFreeIndexInPendingPresetsList; + uint8_t mNextFreeIndexInPresetsList; + + uint8_t mActivePresetHandleData[kPresetHandleSize]; + size_t mActivePresetHandleDataSize; +}; + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/thermostat/linux/include/thermostat-manager.h b/examples/thermostat/linux/include/thermostat-manager.h new file mode 100644 index 00000000000000..274f66c66917cf --- /dev/null +++ b/examples/thermostat/linux/include/thermostat-manager.h @@ -0,0 +1,73 @@ +/* + * + * 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 + +class ThermostatManager +{ +public: + CHIP_ERROR Init(); + + /// @brief Callback called when any attribute changed on the device + void AttributeChangeHandler(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t * value, uint16_t size); + + chip::app::Clusters::Thermostat::SystemModeEnum GetSystemMode(); + chip::app::Clusters::Thermostat::ThermostatRunningModeEnum GetRunningMode(); + int16_t GetCurrentTemperature(); + int16_t GetCurrentHeatingSetPoint(); + int16_t GetCurrentCoolingSetPoint(); + uint8_t GetNumberOfPresets(); + CHIP_ERROR SetSystemMode(chip::app::Clusters::Thermostat::SystemModeEnum systemMode); + CHIP_ERROR SetRunningMode(chip::app::Clusters::Thermostat::ThermostatRunningModeEnum runningMode); + CHIP_ERROR SetCurrentTemperature(int16_t temperature); + CHIP_ERROR SetCurrentHeatingSetPoint(int16_t heatingSetpoint); + CHIP_ERROR SetCurrentCoolingSetPoint(int16_t coolingSetpoint); + +private: + friend ThermostatManager & ThermostatMgr(); + + chip::app::Clusters::Thermostat::SystemModeEnum mSystemMode; + chip::app::Clusters::Thermostat::ThermostatRunningModeEnum mRunningMode; + int16_t mLocalTemperature; + int16_t mOccupiedCoolingSetpoint; + int16_t mOccupiedHeatingSetpoint; + uint8_t mOccupiedSetback; + + static ThermostatManager sThermostatMgr; + + /// @brief attribute handler for the thermostat endpoint + void ThermostatEndpointAttributeChangeHandler(chip::ClusterId clusterId, chip::AttributeId attributeId, uint8_t * value, + uint16_t size); + void ThermostatClusterAttributeChangeHandler(chip::AttributeId attributeId, uint8_t * value, uint16_t size); + void LocalTemperatureMeasurementEndpointAttributeChangeHandler(chip::ClusterId clusterId, chip::AttributeId attributeId, + uint8_t * value, uint16_t size); + void LocalTemperatureMeasurementClusterAttributeChangeHandler(chip::AttributeId attributeId, uint8_t * value, uint16_t size); + + /// @brief Main method that evaluates the current thermostat state and updates attributes + void EvalThermostatState(); + void UpdateRunningModeForHeating(); + void UpdateRunningModeForCooling(); +}; + +inline ThermostatManager & ThermostatMgr() +{ + return ThermostatManager::sThermostatMgr; +} diff --git a/examples/thermostat/linux/main.cpp b/examples/thermostat/linux/main.cpp index b9f82696e8ce79..2279f02bef3963 100644 --- a/examples/thermostat/linux/main.cpp +++ b/examples/thermostat/linux/main.cpp @@ -22,6 +22,8 @@ #include #include +#include "thermostat-manager.h" + using namespace chip; using namespace chip::app; // using namespace chip::app::Clusters; @@ -74,7 +76,19 @@ void ApplicationShutdown() {} int main(int argc, char * argv[]) { - VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0); + if (ChipLinuxAppInit(argc, argv) != 0) + { + return -1; + } + ChipLogProgress(Zcl, "Starting Thermostat Manager"); + CHIP_ERROR err = ThermostatManager().Init(); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to initialize thermostat manager: %" CHIP_ERROR_FORMAT, err.Format()); + chip::DeviceLayer::PlatformMgr().Shutdown(); + return -1; + } ChipLinuxAppMainLoop(); return 0; } diff --git a/examples/thermostat/linux/thermostat-delegate-impl.cpp b/examples/thermostat/linux/thermostat-delegate-impl.cpp new file mode 100644 index 00000000000000..491e44a311c3e8 --- /dev/null +++ b/examples/thermostat/linux/thermostat-delegate-impl.cpp @@ -0,0 +1,234 @@ +/* + * + * 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/thermostat-delegate-impl.h" + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters::Thermostat; +using namespace chip::app::Clusters::Thermostat::Structs; + +ThermostatDelegate ThermostatDelegate::sInstance; + +namespace { + +/** + * @brief Checks if the presets are matching i.e the presetHandles are the same. + * + * @param[in] preset The preset to check. + * @param[in] presetToMatch The preset to match with. + * + * @return true If the presets match, false otherwise. If both preset handles are null, returns false + */ +bool PresetHandlesExistAndMatch(const PresetStructWithOwnedMembers & preset, const PresetStructWithOwnedMembers & presetToMatch) +{ + return !preset.GetPresetHandle().IsNull() && !presetToMatch.GetPresetHandle().IsNull() && + preset.GetPresetHandle().Value().data_equal(presetToMatch.GetPresetHandle().Value()); +} + +} // anonymous namespace + +ThermostatDelegate::ThermostatDelegate() +{ + mNumberOfPresets = kMaxNumberOfPresetTypes * kMaxNumberOfPresetsOfEachType; + mNextFreeIndexInPresetsList = 0; + mNextFreeIndexInPendingPresetsList = 0; + + InitializePresetTypes(); + InitializePresets(); + + memset(mActivePresetHandleData, 0, sizeof(mActivePresetHandleData)); + mActivePresetHandleDataSize = 0; +} + +void ThermostatDelegate::InitializePresetTypes() +{ + PresetScenarioEnum presetScenarioEnumArray[kMaxNumberOfPresetTypes] = { + PresetScenarioEnum::kOccupied, PresetScenarioEnum::kUnoccupied, PresetScenarioEnum::kSleep, + PresetScenarioEnum::kWake, PresetScenarioEnum::kVacation, PresetScenarioEnum::kGoingToSleep + }; + static_assert(ArraySize(presetScenarioEnumArray) <= ArraySize(mPresetTypes)); + + uint8_t index = 0; + for (PresetScenarioEnum presetScenario : presetScenarioEnumArray) + { + mPresetTypes[index].presetScenario = presetScenario; + mPresetTypes[index].numberOfPresets = kMaxNumberOfPresetsOfEachType; + mPresetTypes[index].presetTypeFeatures = + (presetScenario == PresetScenarioEnum::kOccupied || presetScenario == PresetScenarioEnum::kUnoccupied) + ? PresetTypeFeaturesBitmap::kAutomatic + : PresetTypeFeaturesBitmap::kSupportsNames; + index++; + } +} + +void ThermostatDelegate::InitializePresets() +{ + // Initialize the presets with 2 built in presets - occupied and unoccupied. + PresetScenarioEnum presetScenarioEnumArray[2] = { PresetScenarioEnum::kOccupied, PresetScenarioEnum::kUnoccupied }; + static_assert(ArraySize(presetScenarioEnumArray) <= ArraySize(mPresets)); + + uint8_t index = 0; + for (PresetScenarioEnum presetScenario : presetScenarioEnumArray) + { + mPresets[index].SetPresetScenario(presetScenario); + + // Set the preset handle to the preset scenario value as a unique id. + const uint8_t handle[] = { static_cast(presetScenario) }; + mPresets[index].SetPresetHandle(DataModel::MakeNullable(ByteSpan(handle))); + mPresets[index].SetName(NullOptional); + int16_t coolingSetpointValue = static_cast(2500 + (index * 100)); + mPresets[index].SetCoolingSetpoint(MakeOptional(coolingSetpointValue)); + + int16_t heatingSetpointValue = static_cast(2100 - (index * 100)); + mPresets[index].SetHeatingSetpoint(MakeOptional(heatingSetpointValue)); + mPresets[index].SetBuiltIn(DataModel::MakeNullable(true)); + index++; + } + + // Set the value of the next free index in the presets list. + mNextFreeIndexInPresetsList = index; +} + +CHIP_ERROR ThermostatDelegate::GetPresetTypeAtIndex(size_t index, PresetTypeStruct::Type & presetType) +{ + if (index < ArraySize(mPresetTypes)) + { + presetType = mPresetTypes[index]; + return CHIP_NO_ERROR; + } + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} + +uint8_t ThermostatDelegate::GetNumberOfPresets() +{ + return mNumberOfPresets; +} + +CHIP_ERROR ThermostatDelegate::GetPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) +{ + if (index < mNextFreeIndexInPresetsList) + { + preset = mPresets[index]; + return CHIP_NO_ERROR; + } + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} + +CHIP_ERROR ThermostatDelegate::GetActivePresetHandle(MutableByteSpan & activePresetHandle) +{ + return CopySpanToMutableSpan(ByteSpan(mActivePresetHandleData, mActivePresetHandleDataSize), activePresetHandle); +} + +CHIP_ERROR ThermostatDelegate::SetActivePresetHandle(const DataModel::Nullable & newActivePresetHandle) +{ + if (!newActivePresetHandle.IsNull()) + { + size_t newActivePresetHandleSize = newActivePresetHandle.Value().size(); + if (newActivePresetHandleSize > sizeof(mActivePresetHandleData)) + { + ChipLogError(NotSpecified, + "Failed to set ActivePresetHandle. newActivePresetHandle size %u is larger than preset handle size %u", + static_cast(newActivePresetHandleSize), static_cast(kPresetHandleSize)); + return CHIP_ERROR_NO_MEMORY; + } + memcpy(mActivePresetHandleData, newActivePresetHandle.Value().data(), newActivePresetHandleSize); + mActivePresetHandleDataSize = newActivePresetHandleSize; + ChipLogDetail(NotSpecified, "Set ActivePresetHandle to "); + ChipLogByteSpan(NotSpecified, newActivePresetHandle.Value()); + } + else + { + memset(mActivePresetHandleData, 0, sizeof(mActivePresetHandleData)); + mActivePresetHandleDataSize = 0; + ChipLogDetail(NotSpecified, "Clear ActivePresetHandle"); + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR ThermostatDelegate::AppendToPendingPresetList(const PresetStruct::Type & preset) +{ + if (mNextFreeIndexInPendingPresetsList < ArraySize(mPendingPresets)) + { + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetPresetScenario(preset.presetScenario); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetPresetHandle(preset.presetHandle); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetName(preset.name); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetCoolingSetpoint(preset.coolingSetpoint); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetHeatingSetpoint(preset.heatingSetpoint); + mPendingPresets[mNextFreeIndexInPendingPresetsList].SetBuiltIn(preset.builtIn); + mNextFreeIndexInPendingPresetsList++; + return CHIP_NO_ERROR; + } + return CHIP_ERROR_WRITE_FAILED; +} + +CHIP_ERROR ThermostatDelegate::GetPendingPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) +{ + if (index < mNextFreeIndexInPendingPresetsList) + { + preset = mPendingPresets[index]; + return CHIP_NO_ERROR; + } + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} + +CHIP_ERROR ThermostatDelegate::ApplyPendingPresets() +{ + + // TODO: #34546 - Need to support deletion of presets that are removed from Presets. + for (uint8_t indexInPendingPresets = 0; indexInPendingPresets < mNextFreeIndexInPendingPresetsList; indexInPendingPresets++) + { + const PresetStructWithOwnedMembers & pendingPreset = mPendingPresets[indexInPendingPresets]; + + bool found = false; + for (uint8_t indexInPresets = 0; indexInPresets < mNextFreeIndexInPresetsList; indexInPresets++) + { + if (PresetHandlesExistAndMatch(mPresets[indexInPresets], pendingPreset)) + { + found = true; + + // Replace the preset with the pending preset + mPresets[indexInPresets] = pendingPreset; + } + } + + // If pending preset was not found in the Presets list, append to the Presets list. + if (!found) + { + + mPresets[mNextFreeIndexInPresetsList] = pendingPreset; + + // TODO: #34556 Since we support only one preset of each type, using the octet string containing the preset scenario + // suffices as the unique preset handle. Need to fix this to actually provide unique handles once multiple presets of + // each type are supported. + const uint8_t handle[] = { static_cast(pendingPreset.GetPresetScenario()) }; + mPresets[mNextFreeIndexInPresetsList].SetPresetHandle(DataModel::MakeNullable(ByteSpan(handle))); + mNextFreeIndexInPresetsList++; + } + } + return CHIP_NO_ERROR; +} + +void ThermostatDelegate::ClearPendingPresetList() +{ + mNextFreeIndexInPendingPresetsList = 0; +} diff --git a/examples/thermostat/linux/thermostat-manager.cpp b/examples/thermostat/linux/thermostat-manager.cpp new file mode 100644 index 00000000000000..e96f04a78d49e9 --- /dev/null +++ b/examples/thermostat/linux/thermostat-manager.cpp @@ -0,0 +1,515 @@ +/* + * + * 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. + */ + +/********************************************************** + * Includes + *********************************************************/ + +#include "include/thermostat-manager.h" +#include "include/thermostat-delegate-impl.h" + +#include +#include +#include +#include + +/********************************************************** + * Defines and Constants + *********************************************************/ + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::Controller; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::Thermostat; +using namespace chip::app::Clusters::Thermostat::Structs; +using namespace chip::app::Clusters::Thermostat::Attributes; +using namespace chip::app::Clusters::TemperatureMeasurement; +using namespace chip::app::Clusters::TemperatureMeasurement::Attributes; +using namespace Protocols::InteractionModel; + +using namespace chip::DeviceLayer; + +static constexpr EndpointId kThermostatEndpoint = 1; + +static constexpr uint16_t kMaxIntervalCeilingSeconds = 3600; + +static const char * SystemModeString(SystemModeEnum systemMode); +static const char * RunningModeString(ThermostatRunningModeEnum runningMode); + +/********************************************************** + * Variable declarations + *********************************************************/ + +ThermostatManager ThermostatManager::sThermostatMgr; + +namespace { + +CHIP_ERROR ChipErrorFromStatusCode(Status status) +{ + StatusIB statusIB(status); + return statusIB.ToChipError(); +} + +template +static void OnAttributeChangeReported(const ConcreteDataAttributePath & path, const DecodableAttributeType & value); + +template <> +void OnAttributeChangeReported(const ConcreteDataAttributePath & path, + const MeasuredValue::TypeInfo::DecodableType & value) +{ + ClusterId clusterId = path.mClusterId; + if (clusterId != TemperatureMeasurement::Id) + { + ChipLogError(AppServer, + "Attribute change reported for TemperatureMeasurement cluster on incorrect cluster id " ChipLogFormatMEI, + ChipLogValueMEI(clusterId)); + return; + } + + AttributeId attributeId = path.mAttributeId; + if (attributeId != MeasuredValue::Id) + { + ChipLogError(AppServer, + "Attribute change reported for TemperatureMeasurement cluster for incorrect attribute" ChipLogFormatMEI, + ChipLogValueMEI(attributeId)); + return; + } + + if (!value.IsNull()) + { + ChipLogDetail(AppServer, "Attribute change reported for TemperatureMeasurement cluster - MeasuredValue is %d", + value.Value()); + } +} + +static void OnError(const ConcreteDataAttributePath * path, ChipError err) +{ + ChipLogError(AppServer, + "Subscribing to cluster Id " ChipLogFormatMEI " and attribute Id " ChipLogFormatMEI + " failed with error %" CHIP_ERROR_FORMAT, + ChipLogValueMEI(path->mClusterId), ChipLogValueMEI(path->mAttributeId), err.Format()); +} + +static void OnSubscriptionEstablished(const ReadClient & client, unsigned int value) +{ + ChipLogDetail(AppServer, "OnSubscriptionEstablished with subscription Id: %d", value); +} + +template +void SubscribeToAttribute(ClusterId clusterId, AttributeId attributeId, const EmberBindingTableEntry & binding, + OperationalDeviceProxy * peer_device) +{ + VerifyOrReturn(peer_device->GetSecureSession().HasValue(), + ChipLogError(AppServer, "SubscribeToAttribute failed. Secure session is null")); + + SubscribeAttribute( + peer_device->GetExchangeManager(), peer_device->GetSecureSession().Value(), binding.remote, clusterId, attributeId, + &OnAttributeChangeReported, &OnError, 0, kMaxIntervalCeilingSeconds, &OnSubscriptionEstablished, + nullptr, true /* fabricFiltered */, false /* keepExistingSubscription */); +} + +static void ThermostatBoundDeviceChangedHandler(const EmberBindingTableEntry & binding, OperationalDeviceProxy * peer_device, + void * context) +{ + VerifyOrReturn(binding.clusterId.has_value(), ChipLogError(AppServer, "Cluster Id is null")); + ClusterId clusterId = binding.clusterId.value(); + + switch (clusterId) + { + case TemperatureMeasurement::Id: + + // Subscribe to the MeasuredValue attribute + SubscribeToAttribute(clusterId, MeasuredValue::Id, binding, peer_device); + break; + default: + ChipLogError(AppServer, "Unsupported Cluster Id"); + break; + } +} + +void NotifyBoundClusterChangedForAllClusters() +{ + BindingManager::GetInstance().NotifyBoundClusterChanged(kThermostatEndpoint, TemperatureMeasurement::Id, nullptr); +} + +static void OnPlatformChipDeviceEvent(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) +{ + if (event->Type == DeviceLayer::DeviceEventType::kBindingsChangedViaCluster) + { + NotifyBoundClusterChangedForAllClusters(); + } +} + +void InitBindingManager(intptr_t context) +{ + auto & server = Server::GetInstance(); + CHIP_ERROR error = BindingManager::GetInstance().Init( + { &server.GetFabricTable(), server.GetCASESessionManager(), &server.GetPersistentStorage() }); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to init binding manager"); + } + + BindingManager::GetInstance().RegisterBoundDeviceChangedHandler(ThermostatBoundDeviceChangedHandler); + NotifyBoundClusterChangedForAllClusters(); +} + +} // anonymous namespace + +CHIP_ERROR ThermostatManager::Init() +{ + // Init binding manager + + DeviceLayer::PlatformMgr().AddEventHandler(OnPlatformChipDeviceEvent, reinterpret_cast(this)); + DeviceLayer::PlatformMgr().ScheduleWork(InitBindingManager); + + mLocalTemperature = GetCurrentTemperature(); + mSystemMode = GetSystemMode(); + mRunningMode = GetRunningMode(); + mOccupiedCoolingSetpoint = GetCurrentCoolingSetPoint(); + mOccupiedHeatingSetpoint = GetCurrentHeatingSetPoint(); + // TODO: Gotta expose this properly on attribute + mOccupiedSetback = 5; // 0.5 C + + ChipLogError(AppServer, + "Initialized a thermostat with \n " + "mSystemMode: %u (%s) \n mRunningMode: %u (%s) \n mLocalTemperature: %d \n mOccupiedHeatingSetpoint: %d \n " + "mOccupiedCoolingSetpoint: %d" + "NumberOfPresets: %d", + to_underlying(mSystemMode), SystemModeString(mSystemMode), to_underlying(mRunningMode), + RunningModeString(mRunningMode), mLocalTemperature, mOccupiedHeatingSetpoint, mOccupiedCoolingSetpoint, + GetNumberOfPresets()); + + // TODO: Should this be called later? + EvalThermostatState(); + + return CHIP_NO_ERROR; +} + +void ThermostatManager::AttributeChangeHandler(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, uint8_t * value, + uint16_t size) +{ + switch (endpointId) + { + case kThermostatEndpoint: + ThermostatEndpointAttributeChangeHandler(clusterId, attributeId, value, size); + break; + + default: + ChipLogError(AppServer, "Attribute change reported for Thermostat on incorrect endpoint. Ignoring."); + break; + } +} + +void ThermostatManager::ThermostatEndpointAttributeChangeHandler(ClusterId clusterId, AttributeId attributeId, uint8_t * value, + uint16_t size) +{ + switch (clusterId) + { + case Thermostat::Id: + ThermostatClusterAttributeChangeHandler(attributeId, value, size); + break; + + default: + ChipLogError(AppServer, + "Attribute change reported for Thermostat on incorrect cluster for the thermostat endpoint. Ignoring."); + break; + } +} + +void ThermostatManager::ThermostatClusterAttributeChangeHandler(AttributeId attributeId, uint8_t * value, uint16_t size) +{ + switch (attributeId) + { + case LocalTemperature::Id: { + memcpy(&mLocalTemperature, value, size); + ChipLogError(AppServer, "Local temperature changed to %d", mLocalTemperature); + EvalThermostatState(); + } + break; + + case OccupiedCoolingSetpoint::Id: { + memcpy(&mOccupiedCoolingSetpoint, value, size); + ChipLogError(AppServer, "Cooling temperature changed to %d", mOccupiedCoolingSetpoint); + EvalThermostatState(); + } + break; + + case OccupiedHeatingSetpoint::Id: { + memcpy(&mOccupiedHeatingSetpoint, value, size); + ChipLogError(AppServer, "Heating temperature changed to %d", mOccupiedHeatingSetpoint); + EvalThermostatState(); + } + break; + + case SystemMode::Id: { + mSystemMode = static_cast(*value); + ChipLogError(AppServer, "System mode changed to %u (%s)", *value, SystemModeString(mSystemMode)); + EvalThermostatState(); + } + break; + + case ThermostatRunningMode::Id: { + mRunningMode = static_cast(*value); + ChipLogError(AppServer, "Running mode changed to %u (%s)", *value, RunningModeString(mRunningMode)); + } + break; + + default: { + ChipLogError(AppServer, "Unhandled thermostat attribute %x", attributeId); + return; + } + break; + } +} + +SystemModeEnum ThermostatManager::GetSystemMode() +{ + SystemModeEnum systemMode; + SystemMode::Get(kThermostatEndpoint, &systemMode); + return systemMode; +} + +ThermostatRunningModeEnum ThermostatManager::GetRunningMode() +{ + ThermostatRunningModeEnum runningMode; + ThermostatRunningMode::Get(kThermostatEndpoint, &runningMode); + return runningMode; +} + +int16_t ThermostatManager::GetCurrentTemperature() +{ + DataModel::Nullable currentTemperature; + currentTemperature.SetNull(); + LocalTemperature::Get(kThermostatEndpoint, currentTemperature); + return currentTemperature.ValueOr(0); +} + +int16_t ThermostatManager::GetCurrentHeatingSetPoint() +{ + int16_t heatingSetpoint; + OccupiedHeatingSetpoint::Get(kThermostatEndpoint, &heatingSetpoint); + return heatingSetpoint; +} + +int16_t ThermostatManager::GetCurrentCoolingSetPoint() +{ + int16_t coolingSetpoint; + OccupiedCoolingSetpoint::Get(kThermostatEndpoint, &coolingSetpoint); + return coolingSetpoint; +} + +uint8_t ThermostatManager::GetNumberOfPresets() +{ + return ThermostatDelegate::GetInstance().GetNumberOfPresets(); +} + +CHIP_ERROR ThermostatManager::SetSystemMode(SystemModeEnum systemMode) +{ + uint8_t systemModeValue = to_underlying(systemMode); + if (mSystemMode == systemMode) + { + ChipLogDetail(AppServer, "Already in system mode: %u (%s)", systemModeValue, SystemModeString(systemMode)); + return CHIP_NO_ERROR; + } + + ChipLogError(AppServer, "Setting system mode: %u (%s)", systemModeValue, SystemModeString(systemMode)); + return ChipErrorFromStatusCode(SystemMode::Set(kThermostatEndpoint, systemMode)); +} + +CHIP_ERROR ThermostatManager::SetRunningMode(ThermostatRunningModeEnum runningMode) +{ + uint8_t runningModeValue = to_underlying(runningMode); + if (mRunningMode == runningMode) + { + ChipLogDetail(AppServer, "Already in running mode: %u (%s)", runningModeValue, RunningModeString(runningMode)); + return CHIP_NO_ERROR; + } + + ChipLogError(AppServer, "Setting running mode: %u (%s)", runningModeValue, RunningModeString(runningMode)); + return ChipErrorFromStatusCode(ThermostatRunningMode::Set(kThermostatEndpoint, runningMode)); +} + +CHIP_ERROR ThermostatManager::SetCurrentTemperature(int16_t temperature) +{ + return ChipErrorFromStatusCode(LocalTemperature::Set(kThermostatEndpoint, temperature)); +} + +CHIP_ERROR ThermostatManager::SetCurrentHeatingSetPoint(int16_t heatingSetpoint) +{ + return ChipErrorFromStatusCode(OccupiedHeatingSetpoint::Set(kThermostatEndpoint, heatingSetpoint)); +} + +CHIP_ERROR ThermostatManager::SetCurrentCoolingSetPoint(int16_t coolingSetpoint) +{ + return ChipErrorFromStatusCode(OccupiedCoolingSetpoint::Set(kThermostatEndpoint, coolingSetpoint)); +} + +void ThermostatManager::EvalThermostatState() +{ + ChipLogError(AppServer, + "Eval Thermostat Running Mode \n " + "mSystemMode: %u (%s) \n mRunningMode: %u (%s) \n mLocalTemperature: %d \n mOccupiedHeatingSetpoint: %d \n " + "mOccupiedCoolingSetpoint: %d", + to_underlying(mSystemMode), SystemModeString(mSystemMode), to_underlying(mRunningMode), + RunningModeString(mRunningMode), mLocalTemperature, mOccupiedHeatingSetpoint, mOccupiedCoolingSetpoint); + + switch (mSystemMode) + { + case SystemModeEnum::kOff: { + SetRunningMode(ThermostatRunningModeEnum::kOff); + break; + } + case SystemModeEnum::kHeat: { + UpdateRunningModeForHeating(); + break; + } + case SystemModeEnum::kCool: { + UpdateRunningModeForCooling(); + break; + } + case SystemModeEnum::kAuto: { + UpdateRunningModeForHeating(); + UpdateRunningModeForCooling(); + break; + } + default: + break; + } +} + +void ThermostatManager::UpdateRunningModeForHeating() +{ + const int16_t heatingOnThreshold = mOccupiedHeatingSetpoint - static_cast(mOccupiedSetback * 10); + const int16_t heatingOffThreshold = mOccupiedHeatingSetpoint + static_cast(mOccupiedSetback * 10); + + if (mRunningMode == ThermostatRunningModeEnum::kHeat) + { + if (mLocalTemperature >= heatingOffThreshold) + { + ChipLogDetail(AppServer, "Eval Heat - Turning off"); + SetRunningMode(ThermostatRunningModeEnum::kOff); + } + else + { + ChipLogDetail(AppServer, "Eval Heat - Keep Heating"); + } + } + else + { + if (mLocalTemperature <= heatingOnThreshold) + { + ChipLogDetail(AppServer, "Eval Heat - Turn on"); + SetRunningMode(ThermostatRunningModeEnum::kHeat); + } + else + { + ChipLogDetail(AppServer, "Eval Heat - Nothing to do"); + } + } +} + +void ThermostatManager::UpdateRunningModeForCooling() +{ + const int16_t coolingOffThreshold = mOccupiedCoolingSetpoint - static_cast(mOccupiedSetback * 10); + const int16_t coolingOnThreshold = mOccupiedCoolingSetpoint + static_cast(mOccupiedSetback * 10); + + if (mRunningMode == ThermostatRunningModeEnum::kCool) + { + if (mLocalTemperature <= coolingOffThreshold) + { + ChipLogDetail(AppServer, "Eval Cool - Turning off"); + SetRunningMode(ThermostatRunningModeEnum::kOff); + } + else + { + ChipLogDetail(AppServer, "Eval Cool - Keep Cooling"); + } + } + else + { + if (mLocalTemperature >= coolingOnThreshold) + { + ChipLogDetail(AppServer, "Eval Cool - Turn on"); + SetRunningMode(ThermostatRunningModeEnum::kCool); + } + else + { + ChipLogDetail(AppServer, "Eval Cool - Nothing to do"); + } + } +} + +static const char * SystemModeString(SystemModeEnum systemMode) +{ + switch (systemMode) + { + case SystemModeEnum::kOff: + return "Off"; + case SystemModeEnum::kAuto: + return "Auto"; + case SystemModeEnum::kCool: + return "Cool"; + case SystemModeEnum::kHeat: + return "Heat"; + default: + return "Unknown"; + } +} + +static const char * RunningModeString(ThermostatRunningModeEnum runningMode) +{ + switch (runningMode) + { + case ThermostatRunningModeEnum::kOff: + return "Off"; + case ThermostatRunningModeEnum::kCool: + return "Cool"; + case ThermostatRunningModeEnum::kHeat: + return "Heat"; + default: + return "Unknown"; + } +} + +void MatterPostAttributeChangeCallback(const ConcreteAttributePath & attributePath, uint8_t type, uint16_t size, uint8_t * value) +{ + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + ChipLogProgress(AppServer, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + ChipLogProgress(AppServer, + "Attribute ID changed: " ChipLogFormatMEI " Endpoint: %d ClusterId: " ChipLogFormatMEI + " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), attributePath.mEndpointId, ChipLogValueMEI(clusterId), type, *value, size); + + ThermostatMgr().AttributeChangeHandler(attributePath.mEndpointId, clusterId, attributeId, value, size); +} + +void emberAfThermostatClusterInitCallback(EndpointId endpoint) +{ + // Register the delegate for the Thermostat + auto & delegate = ThermostatDelegate::GetInstance(); + + // Set the default delegate for endpoint kThermostatEndpoint. + VerifyOrDie(endpoint == kThermostatEndpoint); + SetDefaultDelegate(endpoint, &delegate); +} diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter index 00917f2d9a593e..94696ef33210a7 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter @@ -254,7 +254,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -270,12 +270,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -311,17 +341,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -931,6 +985,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -939,6 +996,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -949,6 +1010,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -982,12 +1047,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1968,7 +2044,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -2094,11 +2171,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -2204,8 +2276,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2249,10 +2320,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2271,8 +2338,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } endpoint 0 { diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter index a8a65c2c4ad611..1be09ca8f753c9 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -254,7 +254,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -270,12 +270,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -311,17 +341,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -931,6 +985,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -939,6 +996,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -949,6 +1010,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -982,12 +1047,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1879,7 +1955,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -2005,11 +2082,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -2115,8 +2187,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2160,10 +2231,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2182,8 +2249,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } endpoint 0 { diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter index a775e536ac841e..8de2bcd4126529 100644 --- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter +++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter @@ -254,7 +254,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -270,12 +270,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -311,17 +341,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -611,6 +665,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -619,6 +676,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -629,6 +690,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -662,12 +727,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1576,7 +1652,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1702,11 +1779,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1812,8 +1884,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1857,10 +1928,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1879,8 +1946,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring the user interface of a thermostat (which may be remote from the thermostat). */ diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter index 2312df8c61fdc1..3552c9b8ce25f0 100644 --- a/examples/thermostat/thermostat-common/thermostat.matter +++ b/examples/thermostat/thermostat-common/thermostat.matter @@ -254,7 +254,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -270,12 +270,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -311,17 +341,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -672,6 +726,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -680,6 +737,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -690,6 +751,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -723,12 +788,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -1756,7 +1832,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1882,11 +1959,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1992,8 +2064,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2037,10 +2108,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2059,8 +2126,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring the user interface of a thermostat (which may be remote from the thermostat). */ @@ -2505,13 +2570,22 @@ endpoint 1 { ram attribute minSetpointDeadBand default = 0x19; ram attribute controlSequenceOfOperation default = 0x04; persist attribute systemMode default = 0x01; + callback attribute presetTypes; + ram attribute numberOfPresets default = 0; + ram attribute activePresetHandle; + callback attribute presets; + ram attribute presetsSchedulesEditable; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; - ram attribute featureMap default = 0x23; + ram attribute featureMap default = 0x123; ram attribute clusterRevision default = 6; handle command SetpointRaiseLower; + handle command SetActivePresetRequest; + handle command StartPresetsSchedulesEditRequest; + handle command CancelPresetsSchedulesEditRequest; + handle command CommitPresetsSchedulesRequest; } server cluster ThermostatUserInterfaceConfiguration { diff --git a/examples/thermostat/thermostat-common/thermostat.zap b/examples/thermostat/thermostat-common/thermostat.zap index 288a84a921636c..483b79d7d434f5 100644 --- a/examples/thermostat/thermostat-common/thermostat.zap +++ b/examples/thermostat/thermostat-common/thermostat.zap @@ -4659,6 +4659,38 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "SetActivePresetRequest", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StartPresetsSchedulesEditRequest", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CancelPresetsSchedulesEditRequest", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommitPresetsSchedulesRequest", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -4886,6 +4918,86 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "PresetTypes", + "code": 72, + "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": "NumberOfPresets", + "code": 74, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActivePresetHandle", + "code": 78, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Presets", + "code": 80, + "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": "PresetsSchedulesEditable", + "code": 82, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -4944,7 +5056,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x23", + "defaultValue": "0x123", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index 5f9fa9c0ab2b1a..8f4f6a1b37b697 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -295,7 +295,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -311,12 +311,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -352,17 +382,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -635,6 +689,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -643,6 +700,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -653,6 +714,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -686,12 +751,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** This cluster is used to manage global aspects of the Commissioning flow. */ @@ -704,6 +780,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -712,6 +791,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -722,6 +805,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -755,12 +842,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter index 910beaa7eedf7b..ec75977eba422d 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter @@ -455,7 +455,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -471,12 +471,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -512,17 +542,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -719,6 +773,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -727,6 +784,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -737,6 +798,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -770,12 +835,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter index 95aa68635b91ed..64f2e1ef40660a 100644 --- a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter +++ b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter @@ -276,7 +276,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -292,12 +292,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -333,17 +363,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -875,6 +929,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -883,6 +940,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -893,6 +954,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -926,12 +991,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/window-app/common/window-app.matter b/examples/window-app/common/window-app.matter index d0b9d9a24608a8..7e86a64c7fa2d3 100644 --- a/examples/window-app/common/window-app.matter +++ b/examples/window-app/common/window-app.matter @@ -183,7 +183,7 @@ cluster Descriptor = 29 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -199,12 +199,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -240,17 +270,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides attributes and events for determining basic information about Nodes, which supports both @@ -860,6 +914,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -868,6 +925,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -878,6 +939,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -911,12 +976,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ diff --git a/examples/window-app/nrfconnect/README.md b/examples/window-app/nrfconnect/README.md index b61f05dddfb15e..964af0c265cb7e 100644 --- a/examples/window-app/nrfconnect/README.md +++ b/examples/window-app/nrfconnect/README.md @@ -1,5 +1,21 @@ # Matter nRF Connect Window Covering Example Application +> **Note:** This example is intended only to perform smoke tests of a Matter +> solution integrated with nRF Connect SDK platform. The example quality is not +> production ready and it may contain minor bugs or use not optimal +> configuration. It is not recommended to use this example as a basis for +> creating a market ready product. +> +> For the production ready and optimized Matter samples, see +> [nRF Connect SDK samples](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/samples/matter.html). +> The Matter samples in nRF Connect SDK use various additional software +> components and provide multiple optional features that improve the developer +> and user experience. To read more about it, see +> [Matter support in nRF Connect SDK](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/protocols/matter/index.html#ug-matter) +> page. Using Matter samples from nRF Connect SDK allows you to get a full +> Nordic technical support via [DevZone](https://devzone.nordicsemi.com/) +> portal. + The nRF Connect Window Covering Example demonstrates how to remotely control a window shutter device. It uses buttons to test changing cover position and device states and LEDs to show the state of these changes. You can use this @@ -131,8 +147,8 @@ The example supports building and running on the following devices: | Hardware platform | Build target | Platform image | | ----------------------------------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk_nrf52840` |
nRF52840 DKnRF52840 DK
| -| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk_nrf5340_cpuapp` |
nRF5340 DKnRF5340 DK
| +| [nRF52840 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK) | `nrf52840dk/nrf52840` |
nRF52840 DKnRF52840 DK
| +| [nRF5340 DK](https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK) | `nrf5340dk/nrf5340/cpuapp` |
nRF5340 DKnRF5340 DK
|
@@ -299,14 +315,15 @@ Complete the following steps to build the sample: 2. Run the following command to build the example, with _build-target_ replaced with the build target name of the Nordic Semiconductor's kit you own, for - example `nrf52840dk_nrf52840`: + example `nrf52840dk/nrf52840`: - $ west build -b build-target + $ west build -b build-target --sysbuild You only need to specify the build target on the first build. See [Requirements](#requirements) for the build target names of compatible kits. -The output `zephyr.hex` file will be available in the `build/zephyr/` directory. +The output `zephyr.hex` file will be available in the `build/nrfconnect/zephyr/` +directory. ### Removing build artifacts @@ -321,7 +338,7 @@ following command: To build the example with release configuration that disables the diagnostic features like logs and command-line interface, run the following command: - $ west build -b build-target -- -DCONF_FILE=prj_release.conf + $ west build -b build-target --sysbuild -- -DFILE_SUFFIX=release Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -332,18 +349,12 @@ Support for DFU using Matter OTA is enabled by default. To enable DFU over Bluetooth LE, run the following command with _build-target_ replaced with the build target name of the Nordic Semiconductor kit you are -using (for example `nrf52840dk_nrf52840`): +using (for example `nrf52840dk/nrf52840`): ``` - $ west build -b build-target -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y + $ west build -b build-target --sysbuild -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y ``` -To completely disable support for DFU, run the following command with -_build-target_ replaced with the build target name of the Nordic Semiconductor -kit you are using (for example `nrf52840dk_nrf52840`): - - $ west build -b build-target -- -DCONF_FILE=prj_no_dfu.conf - > **Note**: > > There are two types of Device Firmware Upgrade modes: single-image DFU and @@ -356,7 +367,7 @@ kit you are using (for example `nrf52840dk_nrf52840`): #### Changing bootloader configuration To change the default MCUboot configuration, edit the `prj.conf` file located in -the `child_image/mcuboot` directory. +the `sysbuild/mcuboot` directory. Make sure to keep the configuration consistent with changes made to the application configuration. This is necessary for the configuration to work, as @@ -373,8 +384,9 @@ purposes. You can change these settings by defining This example uses this option to define using an external flash. To modify the flash settings of your board (that is, your _build-target_, for -example `nrf52840dk_nrf52840`), edit the `pm_static_dfu.yml` file located in the -`configuration/build-target/` directory. +example `nrf52840dk/nrf52840`), edit the `pm_static_.yml` file +(for example `pm_static_nrf52840dk_nrf52840.yml`), located in the main +application directory.
@@ -386,7 +398,7 @@ using the menuconfig utility. To open the menuconfig utility, run the following command from the example directory: - $ west build -b build-target -t menuconfig + $ west build -b build-target --sysbuild -t menuconfig Remember to replace _build-target_ with the build target name of the Nordic Semiconductor's kit you own. @@ -416,9 +428,6 @@ depending on the selected board: command-line shell. - release — Release version of the application - can be used to enable only the necessary application functionalities to optimize its performance. -- no_dfu — Debug version of the application without Device Firmware - Upgrade feature support - can be used only for the nRF52840 DK and nRF5340 - DK, as those platforms have DFU enabled by default. For more information, see the [Configuring nRF Connect SDK examples](../../../docs/guides/nrfconnect_examples_configuration.md) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index ba77442b28dc23..9f538399a5cf06 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -66 : [Telink] Update Docker image (Zephyr update) +67 : [ESP32] Update esp-idf to v5.3 diff --git a/integrations/docker/images/stage-2/chip-build-esp32/Dockerfile b/integrations/docker/images/stage-2/chip-build-esp32/Dockerfile index 2e41b6b3466e27..b50189201598e1 100644 --- a/integrations/docker/images/stage-2/chip-build-esp32/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-esp32/Dockerfile @@ -12,7 +12,7 @@ RUN set -x \ && : # last line RUN set -x \ - && git clone --recursive -b v5.1.2 --depth 1 --shallow-submodule https://github.com/espressif/esp-idf.git /tmp/esp-idf \ + && git clone --recursive -b v5.3 --depth 1 --shallow-submodule https://github.com/espressif/esp-idf.git /tmp/esp-idf \ && : # last line FROM ghcr.io/project-chip/chip-build:${VERSION} diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 50695772fff354..4ea5a9aae0f836 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -256,6 +256,9 @@ def OutputNames(self): elif self == HostApp.LIT_ICD: yield 'lit-icd-app' yield 'lit-icd-app.map' + elif self == HostApp.NETWORK_MANAGER: + yield 'matter-network-manager-app' + yield 'matter-network-manager-app.map' elif self == HostApp.ENERGY_MANAGEMENT: yield 'chip-energy-management-app' yield 'chip-energy-management-app.map' diff --git a/scripts/helpers/restyle-diff.sh b/scripts/helpers/restyle-diff.sh index 21c01011a7c60c..5cc9ffa6b081fc 100755 --- a/scripts/helpers/restyle-diff.sh +++ b/scripts/helpers/restyle-diff.sh @@ -21,9 +21,10 @@ # you've written is kosher to CI # # Usage: -# restyle-diff.sh [ref] +# restyle-diff.sh [-d] [ref] # # if unspecified, ref defaults to upstream/master (or master) +# -d sets container's log level to DEBUG, if unspecified the default log level will remain (info level) # here=${0%/*} @@ -33,20 +34,55 @@ set -e CHIP_ROOT=$(cd "$here/../.." && pwd) cd "$CHIP_ROOT" -restyle-paths() { - if hash restyle-path 2>/dev/null; then - echo "$@" | xargs restyle-path +docker_run() { + if [ -t 0 ]; then + exec docker run --tty "$@" + else - url=https://github.com/restyled-io/restyler/raw/main/bin/restyle-path - echo "$@" | xargs sh <(curl --location --proto "=https" --tlsv1.2 "$url" -sSf) + exec docker run "$@" + fi } -ref="$1" +restyle-paths() { + + image=restyled/restyler:edge + + for path in "$@"; do + ( + docker_run --tty --interactive --rm \ + --env LOG_LEVEL \ + --env LOG_DESTINATION \ + --env LOG_FORMAT \ + --env LOG_COLOR \ + --env HOST_DIRECTORY="$PWD" \ + --env UNRESTRICTED=1 \ + --volume "$PWD":/code \ + --volume /tmp:/tmp \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + --entrypoint restyle-path \ + "$image" "$path" + ) + done +} + +while [[ $# -gt 0 ]]; do + case "$1" in + -d) + export LOG_LEVEL="DEBUG" + shift + ;; + *) + ref="$1" + shift + ;; + esac +done + if [[ -z "$ref" ]]; then ref="master" git remote | grep -qxF upstream && ref="upstream/master" fi -declare -a paths=("$(git diff --ignore-submodules --name-only --merge-base "$ref")") +mapfile -t paths < <(git diff --ignore-submodules --name-only --merge-base "$ref") restyle-paths "${paths[@]}" diff --git a/scripts/py_matter_idl/matter_idl/test_idl_generator.py b/scripts/py_matter_idl/matter_idl/test_idl_generator.py index 9f40b111bff96f..b030f8b8387a88 100755 --- a/scripts/py_matter_idl/matter_idl/test_idl_generator.py +++ b/scripts/py_matter_idl/matter_idl/test_idl_generator.py @@ -55,8 +55,8 @@ def ReadMatterIdl(repo_path: str) -> str: return stream.read() -def ParseMatterIdl(repo_path: str, skip_meta: bool) -> Idl: - return CreateParser(skip_meta=skip_meta).parse(ReadMatterIdl(repo_path)) +def ParseMatterIdl(repo_path: str, skip_meta: bool, merge_globals: bool) -> Idl: + return CreateParser(skip_meta=skip_meta, merge_globals=merge_globals).parse(ReadMatterIdl(repo_path)) def RenderAsIdlTxt(idl: Idl) -> str: @@ -106,8 +106,10 @@ def test_client_clusters(self): # Files MUST be identical except the header comments which are different original = SkipLeadingComments(ReadMatterIdl(path), also_strip=[ " // NOTE: Default/not specifically set"]) + # Do not merge globals because ZAP generated matter files do not contain + # the merge global data (will not render global reference comments). generated = SkipLeadingComments(RenderAsIdlTxt( - ParseMatterIdl(path, skip_meta=False))) + ParseMatterIdl(path, skip_meta=False, merge_globals=False))) self.assertTextEqual(original, generated) @@ -126,9 +128,9 @@ def test_app_rendering(self): ] for path in test_paths: - idl = ParseMatterIdl(path, skip_meta=True) + idl = ParseMatterIdl(path, skip_meta=True, merge_globals=True) txt = RenderAsIdlTxt(idl) - idl2 = CreateParser(skip_meta=True).parse(txt) + idl2 = CreateParser(skip_meta=True, merge_globals=True).parse(txt) # checks that data types and content is the same self.assertEqual(idl, idl2) diff --git a/scripts/py_matter_idl/matter_idl/test_zapxml.py b/scripts/py_matter_idl/matter_idl/test_zapxml.py index 6e6cd3d8761ca9..5ea15e27e8f9c2 100755 --- a/scripts/py_matter_idl/matter_idl/test_zapxml.py +++ b/scripts/py_matter_idl/matter_idl/test_zapxml.py @@ -234,6 +234,36 @@ def testFabricScopedAndSensitive(self): qualities=StructQuality.FABRIC_SCOPED)], )])) + def testGlobalEnum(self): + idl = XmlToIdl(''' + + + + + + + + + + + ''') + e1 = Enum( + name='One', + base_type="ENUM8", + entries=[ + ConstantEntry(name="Three", code=3), + ] + ) + e2 = Enum( + name='Two', + base_type="ENUM8", + entries=[ + ConstantEntry(name="Big", code=100), + ConstantEntry(name="Bigger", code=2000), + ] + ) + self.assertEqual(idl, Idl(global_enums=[e1, e2])) + def testEnum(self): idl = XmlToIdl(''' @@ -308,6 +338,28 @@ def testFeatures(self): Cluster(name='TestFeatures', code=20, bitmaps=[bitmap]) ])), + def testGlobalStruct(self): + idl = XmlToIdl(''' + + + + + + + + ''') + struct = Struct( + name='SomeStruct', + qualities=StructQuality.FABRIC_SCOPED, + fields=[ + Field(data_type=DataType(name='int16u'), + code=0, name='FirstMember'), + Field(data_type=DataType(name='int32u'), + code=1, name='SecondMember') + ] + ) + self.assertEqual(idl, Idl(global_structs=[struct])) + def testStruct(self): idl = XmlToIdl(''' diff --git a/scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py b/scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py index 866ce71f914214..cc5ccd9483091d 100644 --- a/scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py +++ b/scripts/py_matter_idl/matter_idl/zapxml/handlers/handlers.py @@ -225,7 +225,7 @@ def FinalizeProcessing(self, idl: Idl): # - inside a cluster if a code exists # - inside top level if no codes were associated if not self._cluster_codes: - LOGGER.error('Struct %s has no cluster codes' % self._struct.name) + idl.global_structs.append(self._struct) return for code in self._cluster_codes: @@ -270,9 +270,9 @@ def GetNextProcessor(self, name, attrs): def FinalizeProcessing(self, idl: Idl): if not self._cluster_codes: - LOGGER.error("Found enum without a cluster code: %s" % - (self._enum.name)) + idl.global_enums.append(self._enum) return + found = set() for c in idl.clusters: if c.code in self._cluster_codes: @@ -313,14 +313,11 @@ def GetNextProcessor(self, name, attrs): return BaseHandler(self.context) def FinalizeProcessing(self, idl: Idl): - # We have two choices of adding an enum: + # We have two choices of adding a bitmap: # - inside a cluster if a code exists # - inside top level if a code does not exist if not self._cluster_codes: - # Log only instead of critical, as not our XML is well formed. - # For example at the time of writing this, SwitchFeature in switch-cluster.xml - # did not have a code associated with it. - LOGGER.error("Bitmap %r has no cluster codes" % self._bitmap) + idl.global_bitmaps.append(self._bitmap) return for code in self._cluster_codes: diff --git a/scripts/py_matter_yamltests/matter_yamltests/definitions.py b/scripts/py_matter_yamltests/matter_yamltests/definitions.py index 1e4b3635200bb8..bc77e913dd4cbc 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/definitions.py +++ b/scripts/py_matter_yamltests/matter_yamltests/definitions.py @@ -88,6 +88,10 @@ def __init__(self, sources: List[ParseSource]): self.__responses_by_id[code][struct.code] = struct self.__responses_by_name[name][struct.name] = struct.code + self.__global_bitmaps: dict[str, Bitmap] = {b.name: b for b in idl.global_bitmaps} + self.__global_enums: dict[str, Bitmap] = {e.name: e for e in idl.global_enums} + self.__global_structs: dict[str, Bitmap] = {s.name: s for s in idl.global_structs} + def get_cluster_names(self) -> List[str]: return [name for name, _ in self.__clusters_by_name.items()] @@ -257,9 +261,26 @@ def __get_targets_by_cluster_name(self, cluster_name: str, target_type: _ItemTyp _ItemType.Struct: self.__structs_by_name, } + global_target_mapping = { + _ItemType.Request: None, + _ItemType.Response: None, + _ItemType.Attribute: None, + _ItemType.Event: None, + _ItemType.Bitmap: self.__global_bitmaps, + _ItemType.Enum: self.__global_enums, + _ItemType.Struct: self.__global_structs, + } + # The idl parser remove spaces cluster_name = cluster_name.replace(' ', '') - return target_mapping[target_type].get(cluster_name) + global_target = global_target_mapping[target_type] + target = target_mapping[target_type].get(cluster_name) + + if target is None: + return global_target + if global_target is None: + return target + return target | global_target def SpecDefinitionsFromPaths(paths: str, pseudo_clusters: Optional[PseudoClusters] = PseudoClusters([])): diff --git a/scripts/py_matter_yamltests/test_spec_definitions.py b/scripts/py_matter_yamltests/test_spec_definitions.py index a1cce4833ac075..4dd776bf520bcb 100644 --- a/scripts/py_matter_yamltests/test_spec_definitions.py +++ b/scripts/py_matter_yamltests/test_spec_definitions.py @@ -102,6 +102,10 @@ source_bitmap = ''' + + + + @@ -126,6 +130,10 @@ source_enum = ''' + + + + @@ -150,6 +158,10 @@ source_struct = ''' + + + + @@ -310,10 +322,16 @@ def test_get_bitmap_by_name(self): [ParseSource(source=io.StringIO(source_bitmap), name='source_bitmap')]) self.assertIsNone(definitions.get_bitmap_by_name( 'WrongName', 'TestBitmap')) + self.assertIsNone(definitions.get_bitmap_by_name( + 'TestWrong', 'TestBitmap')) self.assertIsNone(definitions.get_bitmap_by_name( 'Test', 'TestWrongBitmap')) self.assertIsInstance(definitions.get_bitmap_by_name( 'Test', 'TestBitmap'), Bitmap) + self.assertIsInstance(definitions.get_bitmap_by_name( + 'Test', 'TestGlobalBitmap'), Bitmap) + self.assertIsInstance(definitions.get_bitmap_by_name( + 'TestWrong', 'TestGlobalBitmap'), Bitmap) self.assertIsNone(definitions.get_bitmap_by_name('test', 'TestBitmap')) self.assertIsNone(definitions.get_bitmap_by_name('Test', 'testbitmap')) @@ -322,10 +340,16 @@ def test_get_enum_by_name(self): [ParseSource(source=io.StringIO(source_enum), name='source_enum')]) self.assertIsNone(definitions.get_enum_by_name( 'WrongName', 'TestEnum')) + self.assertIsNone(definitions.get_enum_by_name( + 'TestWrong', 'TestEnum')) self.assertIsNone(definitions.get_enum_by_name( 'Test', 'TestWrongEnum')) self.assertIsInstance( definitions.get_enum_by_name('Test', 'TestEnum'), Enum) + self.assertIsInstance( + definitions.get_enum_by_name('Test', 'TestGlobalEnum'), Enum) + self.assertIsInstance( + definitions.get_enum_by_name('TestWrong', 'TestGlobalEnum'), Enum) self.assertIsNone(definitions.get_enum_by_name('test', 'TestEnum')) self.assertIsNone(definitions.get_enum_by_name('Test', 'testenum')) @@ -334,10 +358,16 @@ def test_get_struct_by_name(self): [ParseSource(source=io.StringIO(source_struct), name='source_struct')]) self.assertIsNone(definitions.get_struct_by_name( 'WrongName', 'TestStruct')) + self.assertIsNone(definitions.get_struct_by_name( + 'TestWrong', 'TestStruct')) self.assertIsNone(definitions.get_struct_by_name( 'Test', 'TestWrongStruct')) self.assertIsInstance(definitions.get_struct_by_name( 'Test', 'TestStruct'), Struct) + self.assertIsInstance(definitions.get_struct_by_name( + 'Test', 'TestGlobalStruct'), Struct) + self.assertIsInstance(definitions.get_struct_by_name( + 'TestWrong', 'TestGlobalStruct'), Struct) self.assertIsNone(definitions.get_struct_by_name('test', 'TestStruct')) self.assertIsNone(definitions.get_struct_by_name('Test', 'teststruct')) @@ -365,16 +395,22 @@ def test_get_type_by_name(self): [ParseSource(source=io.StringIO(source_bitmap), name='source_bitmap')]) self.assertIsInstance(definitions.get_type_by_name( 'Test', 'TestBitmap'), Bitmap) + self.assertIsInstance(definitions.get_type_by_name( + 'Test', 'TestGlobalBitmap'), Bitmap) definitions = SpecDefinitions( [ParseSource(source=io.StringIO(source_enum), name='source_enum')]) self.assertIsInstance( definitions.get_type_by_name('Test', 'TestEnum'), Enum) + self.assertIsInstance( + definitions.get_type_by_name('Test', 'TestGlobalEnum'), Enum) definitions = SpecDefinitions( [ParseSource(source=io.StringIO(source_struct), name='source_struct')]) self.assertIsInstance(definitions.get_type_by_name( 'Test', 'TestStruct'), Struct) + self.assertIsInstance(definitions.get_type_by_name( + 'Test', 'TestGlobalStruct'), Struct) def test_struct_is_fabric_scoped(self): definitions = SpecDefinitions( diff --git a/scripts/tests/chiptest/__init__.py b/scripts/tests/chiptest/__init__.py index a250bab52e9de4..29aa9d47dce42d 100644 --- a/scripts/tests/chiptest/__init__.py +++ b/scripts/tests/chiptest/__init__.py @@ -157,6 +157,7 @@ def _GetInDevelopmentTests() -> Set[str]: # TestEventTriggersEnabled is true, which it's not in CI. "Test_TC_SMOKECO_2_6.yaml", # chip-repl does not support local timeout (07/20/2023) and test assumes # TestEventTriggersEnabled is true, which it's not in CI. + "TestFabricSyncBridgedNode.yaml", # [TODO] fabric-bridge-app lacks some feature so this test currently fails } @@ -276,6 +277,8 @@ def target_for_name(name: str): return TestTarget.TV if name.startswith("DL_") or name.startswith("Test_TC_DRLK_"): return TestTarget.LOCK + if name.startswith("TestFabricSync"): + return TestTarget.FABRIC_SYNC if name.startswith("OTA_"): return TestTarget.OTA if name.startswith("Test_TC_BRBINFO_") or name.startswith("Test_TC_ACT_"): @@ -286,6 +289,8 @@ def target_for_name(name: str): return TestTarget.MWO if name.startswith("Test_TC_RVCRUNM_") or name.startswith("Test_TC_RVCCLEANM_") or name.startswith("Test_TC_RVCOPSTATE_"): return TestTarget.RVC + if name.startswith("Test_TC_THNETDIR_") or name.startswith("Test_TC_WIFINM_"): + return TestTarget.NETWORK_MANAGER return TestTarget.ALL_CLUSTERS diff --git a/scripts/tests/chiptest/linux.py b/scripts/tests/chiptest/linux.py index 3dbd851be26b47..bf3e140981d3a7 100644 --- a/scripts/tests/chiptest/linux.py +++ b/scripts/tests/chiptest/linux.py @@ -178,12 +178,14 @@ def PathsWithNetworkNamespaces(paths: ApplicationPaths) -> ApplicationPaths: chip_tool='ip netns exec tool'.split() + paths.chip_tool, all_clusters_app='ip netns exec app'.split() + paths.all_clusters_app, lock_app='ip netns exec app'.split() + paths.lock_app, + fabric_bridge_app='ip netns exec app'.split() + paths.fabric_bridge_app, ota_provider_app='ip netns exec app'.split() + paths.ota_provider_app, ota_requestor_app='ip netns exec app'.split() + paths.ota_requestor_app, tv_app='ip netns exec app'.split() + paths.tv_app, lit_icd_app='ip netns exec app'.split() + paths.lit_icd_app, microwave_oven_app='ip netns exec app'.split() + paths.microwave_oven_app, rvc_app='ip netns exec app'.split() + paths.rvc_app, + network_manager_app='ip netns exec app'.split() + paths.network_manager_app, bridge_app='ip netns exec app'.split() + paths.bridge_app, chip_repl_yaml_tester_cmd='ip netns exec tool'.split() + paths.chip_repl_yaml_tester_cmd, chip_tool_with_python_cmd='ip netns exec tool'.split() + paths.chip_tool_with_python_cmd, diff --git a/scripts/tests/chiptest/test_definition.py b/scripts/tests/chiptest/test_definition.py index 970c098f1354bb..484f247f70b1b2 100644 --- a/scripts/tests/chiptest/test_definition.py +++ b/scripts/tests/chiptest/test_definition.py @@ -175,8 +175,10 @@ class TestTarget(Enum): OTA = auto() BRIDGE = auto() LIT_ICD = auto() + FABRIC_SYNC = auto() MWO = auto() RVC = auto() + NETWORK_MANAGER = auto() @dataclass @@ -184,6 +186,7 @@ class ApplicationPaths: chip_tool: typing.List[str] all_clusters_app: typing.List[str] lock_app: typing.List[str] + fabric_bridge_app: typing.List[str] ota_provider_app: typing.List[str] ota_requestor_app: typing.List[str] tv_app: typing.List[str] @@ -193,10 +196,14 @@ class ApplicationPaths: chip_repl_yaml_tester_cmd: typing.List[str] chip_tool_with_python_cmd: typing.List[str] rvc_app: typing.List[str] + network_manager_app: typing.List[str] def items(self): - return [self.chip_tool, self.all_clusters_app, self.lock_app, self.ota_provider_app, self.ota_requestor_app, - self.tv_app, self.bridge_app, self.lit_icd_app, self.microwave_oven_app, self.chip_repl_yaml_tester_cmd, self.chip_tool_with_python_cmd, self.rvc_app] + return [self.chip_tool, self.all_clusters_app, self.lock_app, + self.fabric_bridge_app, self.ota_provider_app, self.ota_requestor_app, + self.tv_app, self.bridge_app, self.lit_icd_app, + self.microwave_oven_app, self.chip_repl_yaml_tester_cmd, + self.chip_tool_with_python_cmd, self.rvc_app, self.network_manager_app] @dataclass @@ -299,6 +306,8 @@ def Run(self, runner, apps_register, paths: ApplicationPaths, pics_file: str, target_app = paths.tv_app elif self.target == TestTarget.LOCK: target_app = paths.lock_app + elif self.target == TestTarget.FABRIC_SYNC: + target_app = paths.fabric_bridge_app elif self.target == TestTarget.OTA: target_app = paths.ota_requestor_app elif self.target == TestTarget.BRIDGE: @@ -309,6 +318,8 @@ def Run(self, runner, apps_register, paths: ApplicationPaths, pics_file: str, target_app = paths.microwave_oven_app elif self.target == TestTarget.RVC: target_app = paths.rvc_app + elif self.target == TestTarget.NETWORK_MANAGER: + target_app = paths.network_manager_app else: raise Exception("Unknown test target - " "don't know which application to run") diff --git a/scripts/tests/run_test_suite.py b/scripts/tests/run_test_suite.py index c22b4abff92f09..41b7b540a6dd50 100755 --- a/scripts/tests/run_test_suite.py +++ b/scripts/tests/run_test_suite.py @@ -239,6 +239,9 @@ def cmd_list(context): @click.option( '--lock-app', help='what lock app to use') +@click.option( + '--fabric-bridge-app', + help='what fabric bridge app to use') @click.option( '--ota-provider-app', help='what ota provider app to use') @@ -260,6 +263,9 @@ def cmd_list(context): @click.option( '--rvc-app', help='what rvc app to use') +@click.option( + '--network-manager-app', + help='what network-manager app to use') @click.option( '--chip-repl-yaml-tester', help='what python script to use for running yaml tests using chip-repl as controller') @@ -291,7 +297,8 @@ def cmd_list(context): help='Number of tests that are expected to fail in each iteration. Overall test will pass if the number of failures matches this. Nonzero values require --keep-going') @click.pass_context def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, ota_requestor_app, - tv_app, bridge_app, lit_icd_app, microwave_oven_app, rvc_app, chip_repl_yaml_tester, chip_tool_with_python, pics_file, keep_going, test_timeout_seconds, expected_failures): + fabric_bridge_app, tv_app, bridge_app, lit_icd_app, microwave_oven_app, rvc_app, network_manager_app, chip_repl_yaml_tester, + chip_tool_with_python, pics_file, keep_going, test_timeout_seconds, expected_failures): if expected_failures != 0 and not keep_going: logging.exception(f"'--expected-failures {expected_failures}' used without '--keep-going'") sys.exit(2) @@ -306,6 +313,9 @@ def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, o if lock_app is None: lock_app = paths_finder.get('chip-lock-app') + if fabric_bridge_app is None: + fabric_bridge_app = paths_finder.get('fabric-bridge-app') + if ota_provider_app is None: ota_provider_app = paths_finder.get('chip-ota-provider-app') @@ -327,6 +337,9 @@ def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, o if rvc_app is None: rvc_app = paths_finder.get('chip-rvc-app') + if network_manager_app is None: + network_manager_app = paths_finder.get('matter-network-manager-app') + if chip_repl_yaml_tester is None: chip_repl_yaml_tester = paths_finder.get('yamltest_with_chip_repl_tester.py') @@ -341,6 +354,7 @@ def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, o chip_tool=[context.obj.chip_tool], all_clusters_app=[all_clusters_app], lock_app=[lock_app], + fabric_bridge_app=[fabric_bridge_app], ota_provider_app=[ota_provider_app], ota_requestor_app=[ota_requestor_app], tv_app=[tv_app], @@ -348,6 +362,7 @@ def cmd_run(context, iterations, all_clusters_app, lock_app, ota_provider_app, o lit_icd_app=[lit_icd_app], microwave_oven_app=[microwave_oven_app], rvc_app=[rvc_app], + network_manager_app=[network_manager_app], chip_repl_yaml_tester_cmd=['python3'] + [chip_repl_yaml_tester], chip_tool_with_python_cmd=['python3'] + [chip_tool_with_python], ) diff --git a/scripts/tools/check_includes_config.py b/scripts/tools/check_includes_config.py index d897c86e32cfe8..8790faf1666b08 100644 --- a/scripts/tools/check_includes_config.py +++ b/scripts/tools/check_includes_config.py @@ -139,6 +139,7 @@ 'src/credentials/attestation_verifier/FileAttestationTrustStore.h': {'vector'}, 'src/credentials/attestation_verifier/FileAttestationTrustStore.cpp': {'string'}, + 'src/credentials/attestation_verifier/TestDACRevocationDelegateImpl.cpp': {'fstream'}, 'src/setup_payload/AdditionalDataPayload.h': {'string'}, 'src/setup_payload/AdditionalDataPayloadParser.cpp': {'vector', 'string'}, diff --git a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/access.h b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/access.h index 282335c5b25384..9b4ddb220986ad 100644 --- a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/access.h +++ b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/access.h @@ -33,9 +33,6 @@ /* Cluster: Level Control, Attribute: StartUpCurrentLevel, Privilege: view */ \ 0x0000001F, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ 0x0000001F, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ - /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ /* Cluster: Basic Information, Attribute: NodeLabel, Privilege: view */ \ /* Cluster: Basic Information, Attribute: Location, Privilege: view */ \ /* Cluster: Basic Information, Attribute: LocalConfigDisabled, Privilege: view */ \ @@ -79,9 +76,6 @@ /* Cluster: Level Control, Attribute: StartUpCurrentLevel, Privilege: view */ \ 0x00000000, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ 0x00000001, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ - /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ /* Cluster: Basic Information, Attribute: NodeLabel, Privilege: view */ \ /* Cluster: Basic Information, Attribute: Location, Privilege: view */ \ /* Cluster: Basic Information, Attribute: LocalConfigDisabled, Privilege: view */ \ @@ -125,9 +119,6 @@ /* Cluster: Level Control, Attribute: StartUpCurrentLevel, Privilege: view */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ - /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ /* Cluster: Basic Information, Attribute: NodeLabel, Privilege: view */ \ /* Cluster: Basic Information, Attribute: Location, Privilege: view */ \ /* Cluster: Basic Information, Attribute: LocalConfigDisabled, Privilege: view */ \ @@ -517,18 +508,24 @@ #define GENERATED_ACCESS_READ_EVENT__CLUSTER { \ 0x0000001F, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ 0x0000001F, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ + 0x0000001F, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ + 0x0000001F, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } // Parallel array data (cluster, *event*, privilege) for read event #define GENERATED_ACCESS_READ_EVENT__EVENT { \ 0x00000000, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ 0x00000001, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ + 0x00000002, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ + 0x00000003, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } // Parallel array data (cluster, event, *privilege*) for read event #define GENERATED_ACCESS_READ_EVENT__PRIVILEGE { \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ + chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ + chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } //////////////////////////////////////////////////////////////////////////////// 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 f2c082b1d0d4a1..c60950077fb372 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 @@ -355,7 +355,7 @@ } // This is an array of EmberAfAttributeMetadata structures. -#define GENERATED_ATTRIBUTE_COUNT 1056 +#define GENERATED_ATTRIBUTE_COUNT 1055 #define GENERATED_ATTRIBUTES \ { \ \ @@ -1400,8 +1400,7 @@ { ZAP_EMPTY_DEFAULT(), 0x00000051, 0, ZAP_TYPE(ARRAY), \ ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(WRITABLE) }, /* Schedules */ \ { ZAP_EMPTY_DEFAULT(), 0x00000052, 1, ZAP_TYPE(BOOLEAN), 0 }, /* PresetsSchedulesEditable */ \ - { ZAP_SIMPLE_DEFAULT(0), 0x00000053, 1, ZAP_TYPE(BITMAP8), 0 }, /* TemperatureSetpointHoldPolicy */ \ - { ZAP_EMPTY_DEFAULT(), 0x00000054, 4, ZAP_TYPE(EPOCH_S), \ + { ZAP_SIMPLE_DEFAULT(0), 0x00000053, 4, ZAP_TYPE(EPOCH_S), \ ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* SetpointHoldExpiryTimestamp */ \ { ZAP_SIMPLE_DEFAULT(0x0023), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ { ZAP_SIMPLE_DEFAULT(6), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ @@ -3749,8 +3748,8 @@ /* Endpoint: 1, Cluster: Thermostat (server) */ \ .clusterId = 0x00000201, \ .attributes = ZAP_ATTRIBUTE_INDEX(616), \ - .attributeCount = 28, \ - .clusterSize = 74, \ + .attributeCount = 27, \ + .clusterSize = 73, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ .functions = chipFuncArrayThermostatServer, \ .acceptedCommandList = ZAP_GENERATED_COMMANDS_INDEX( 241 ), \ @@ -3761,7 +3760,7 @@ { \ /* Endpoint: 1, Cluster: Fan Control (server) */ \ .clusterId = 0x00000202, \ - .attributes = ZAP_ATTRIBUTE_INDEX(644), \ + .attributes = ZAP_ATTRIBUTE_INDEX(643), \ .attributeCount = 14, \ .clusterSize = 18, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ @@ -3774,7 +3773,7 @@ { \ /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ .clusterId = 0x00000204, \ - .attributes = ZAP_ATTRIBUTE_INDEX(658), \ + .attributes = ZAP_ATTRIBUTE_INDEX(657), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ @@ -3787,7 +3786,7 @@ { \ /* Endpoint: 1, Cluster: Color Control (server) */ \ .clusterId = 0x00000300, \ - .attributes = ZAP_ATTRIBUTE_INDEX(663), \ + .attributes = ZAP_ATTRIBUTE_INDEX(662), \ .attributeCount = 54, \ .clusterSize = 345, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -3800,7 +3799,7 @@ { \ /* Endpoint: 1, Cluster: Ballast Configuration (server) */ \ .clusterId = 0x00000301, \ - .attributes = ZAP_ATTRIBUTE_INDEX(717), \ + .attributes = ZAP_ATTRIBUTE_INDEX(716), \ .attributeCount = 16, \ .clusterSize = 58, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3813,7 +3812,7 @@ { \ /* Endpoint: 1, Cluster: Illuminance Measurement (server) */ \ .clusterId = 0x00000400, \ - .attributes = ZAP_ATTRIBUTE_INDEX(733), \ + .attributes = ZAP_ATTRIBUTE_INDEX(732), \ .attributeCount = 7, \ .clusterSize = 15, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3826,7 +3825,7 @@ { \ /* Endpoint: 1, Cluster: Temperature Measurement (server) */ \ .clusterId = 0x00000402, \ - .attributes = ZAP_ATTRIBUTE_INDEX(740), \ + .attributes = ZAP_ATTRIBUTE_INDEX(739), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3839,7 +3838,7 @@ { \ /* Endpoint: 1, Cluster: Pressure Measurement (server) */ \ .clusterId = 0x00000403, \ - .attributes = ZAP_ATTRIBUTE_INDEX(746), \ + .attributes = ZAP_ATTRIBUTE_INDEX(745), \ .attributeCount = 5, \ .clusterSize = 12, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3852,7 +3851,7 @@ { \ /* Endpoint: 1, Cluster: Flow Measurement (server) */ \ .clusterId = 0x00000404, \ - .attributes = ZAP_ATTRIBUTE_INDEX(751), \ + .attributes = ZAP_ATTRIBUTE_INDEX(750), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3865,7 +3864,7 @@ { \ /* Endpoint: 1, Cluster: Relative Humidity Measurement (server) */ \ .clusterId = 0x00000405, \ - .attributes = ZAP_ATTRIBUTE_INDEX(757), \ + .attributes = ZAP_ATTRIBUTE_INDEX(756), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3878,7 +3877,7 @@ { \ /* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \ .clusterId = 0x00000406, \ - .attributes = ZAP_ATTRIBUTE_INDEX(763), \ + .attributes = ZAP_ATTRIBUTE_INDEX(762), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -3891,7 +3890,7 @@ { \ /* Endpoint: 1, Cluster: Carbon Monoxide Concentration Measurement (server) */ \ .clusterId = 0x0000040C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(768), \ + .attributes = ZAP_ATTRIBUTE_INDEX(767), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3904,7 +3903,7 @@ { \ /* Endpoint: 1, Cluster: Carbon Dioxide Concentration Measurement (server) */ \ .clusterId = 0x0000040D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(781), \ + .attributes = ZAP_ATTRIBUTE_INDEX(780), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3917,7 +3916,7 @@ { \ /* Endpoint: 1, Cluster: Nitrogen Dioxide Concentration Measurement (server) */ \ .clusterId = 0x00000413, \ - .attributes = ZAP_ATTRIBUTE_INDEX(794), \ + .attributes = ZAP_ATTRIBUTE_INDEX(793), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3930,7 +3929,7 @@ { \ /* Endpoint: 1, Cluster: Ozone Concentration Measurement (server) */ \ .clusterId = 0x00000415, \ - .attributes = ZAP_ATTRIBUTE_INDEX(807), \ + .attributes = ZAP_ATTRIBUTE_INDEX(806), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3943,7 +3942,7 @@ { \ /* Endpoint: 1, Cluster: PM2.5 Concentration Measurement (server) */ \ .clusterId = 0x0000042A, \ - .attributes = ZAP_ATTRIBUTE_INDEX(820), \ + .attributes = ZAP_ATTRIBUTE_INDEX(819), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3956,7 +3955,7 @@ { \ /* Endpoint: 1, Cluster: Formaldehyde Concentration Measurement (server) */ \ .clusterId = 0x0000042B, \ - .attributes = ZAP_ATTRIBUTE_INDEX(833), \ + .attributes = ZAP_ATTRIBUTE_INDEX(832), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3969,7 +3968,7 @@ { \ /* Endpoint: 1, Cluster: PM1 Concentration Measurement (server) */ \ .clusterId = 0x0000042C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(846), \ + .attributes = ZAP_ATTRIBUTE_INDEX(845), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3982,7 +3981,7 @@ { \ /* Endpoint: 1, Cluster: PM10 Concentration Measurement (server) */ \ .clusterId = 0x0000042D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(859), \ + .attributes = ZAP_ATTRIBUTE_INDEX(858), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3995,7 +3994,7 @@ { \ /* Endpoint: 1, Cluster: Total Volatile Organic Compounds Concentration Measurement (server) */ \ .clusterId = 0x0000042E, \ - .attributes = ZAP_ATTRIBUTE_INDEX(872), \ + .attributes = ZAP_ATTRIBUTE_INDEX(871), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4008,7 +4007,7 @@ { \ /* Endpoint: 1, Cluster: Radon Concentration Measurement (server) */ \ .clusterId = 0x0000042F, \ - .attributes = ZAP_ATTRIBUTE_INDEX(885), \ + .attributes = ZAP_ATTRIBUTE_INDEX(884), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4021,7 +4020,7 @@ { \ /* Endpoint: 1, Cluster: Wake on LAN (server) */ \ .clusterId = 0x00000503, \ - .attributes = ZAP_ATTRIBUTE_INDEX(898), \ + .attributes = ZAP_ATTRIBUTE_INDEX(897), \ .attributeCount = 3, \ .clusterSize = 19, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4034,7 +4033,7 @@ { \ /* Endpoint: 1, Cluster: Low Power (server) */ \ .clusterId = 0x00000508, \ - .attributes = ZAP_ATTRIBUTE_INDEX(901), \ + .attributes = ZAP_ATTRIBUTE_INDEX(900), \ .attributeCount = 2, \ .clusterSize = 6, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4047,7 +4046,7 @@ { \ /* Endpoint: 1, Cluster: Electrical Measurement (server) */ \ .clusterId = 0x00000B04, \ - .attributes = ZAP_ATTRIBUTE_INDEX(903), \ + .attributes = ZAP_ATTRIBUTE_INDEX(902), \ .attributeCount = 13, \ .clusterSize = 32, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4060,7 +4059,7 @@ { \ /* Endpoint: 1, Cluster: Unit Testing (server) */ \ .clusterId = 0xFFF1FC05, \ - .attributes = ZAP_ATTRIBUTE_INDEX(916), \ + .attributes = ZAP_ATTRIBUTE_INDEX(915), \ .attributeCount = 84, \ .clusterSize = 2290, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4073,7 +4072,7 @@ { \ /* Endpoint: 2, Cluster: Identify (server) */ \ .clusterId = 0x00000003, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1000), \ + .attributes = ZAP_ATTRIBUTE_INDEX(999), \ .attributeCount = 4, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(ATTRIBUTE_CHANGED_FUNCTION), \ @@ -4086,7 +4085,7 @@ { \ /* Endpoint: 2, Cluster: Groups (server) */ \ .clusterId = 0x00000004, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1004), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1003), \ .attributeCount = 3, \ .clusterSize = 7, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -4099,7 +4098,7 @@ { \ /* Endpoint: 2, Cluster: On/Off (server) */ \ .clusterId = 0x00000006, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1007), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1006), \ .attributeCount = 7, \ .clusterSize = 13, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -4112,7 +4111,7 @@ { \ /* Endpoint: 2, Cluster: Descriptor (server) */ \ .clusterId = 0x0000001D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1014), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1013), \ .attributeCount = 7, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4125,7 +4124,7 @@ { \ /* Endpoint: 2, Cluster: Power Source (server) */ \ .clusterId = 0x0000002F, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1021), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1020), \ .attributeCount = 9, \ .clusterSize = 72, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4138,7 +4137,7 @@ { \ /* Endpoint: 2, Cluster: Scenes Management (server) */ \ .clusterId = 0x00000062, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1030), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1029), \ .attributeCount = 5, \ .clusterSize = 16, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -4151,7 +4150,7 @@ { \ /* Endpoint: 2, Cluster: Occupancy Sensing (server) */ \ .clusterId = 0x00000406, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1035), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1034), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -4164,7 +4163,7 @@ { \ /* Endpoint: 65534, Cluster: Descriptor (server) */ \ .clusterId = 0x0000001D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1040), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1039), \ .attributeCount = 6, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4177,7 +4176,7 @@ { \ /* Endpoint: 65534, Cluster: Network Commissioning (server) */ \ .clusterId = 0x00000031, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1046), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1045), \ .attributeCount = 10, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4196,7 +4195,7 @@ // This is an array of EmberAfEndpointType structures. #define GENERATED_ENDPOINT_TYPES \ { \ - { ZAP_CLUSTER_INDEX(0), 29, 349 }, { ZAP_CLUSTER_INDEX(29), 74, 3523 }, { ZAP_CLUSTER_INDEX(103), 7, 126 }, \ + { ZAP_CLUSTER_INDEX(0), 29, 349 }, { ZAP_CLUSTER_INDEX(29), 74, 3522 }, { ZAP_CLUSTER_INDEX(103), 7, 126 }, \ { ZAP_CLUSTER_INDEX(110), 2, 0 }, \ } @@ -4209,7 +4208,7 @@ static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, #define ATTRIBUTE_SINGLETONS_SIZE (36) // Total size of attribute storage -#define ATTRIBUTE_MAX_SIZE (3998) +#define ATTRIBUTE_MAX_SIZE (3997) // Number of fixed endpoints #define FIXED_ENDPOINT_COUNT (4) diff --git a/scripts/tools/zap/tests/outputs/lighting-app/app-templates/access.h b/scripts/tools/zap/tests/outputs/lighting-app/app-templates/access.h index 5bb357928377a2..45b93e99bae3c8 100644 --- a/scripts/tools/zap/tests/outputs/lighting-app/app-templates/access.h +++ b/scripts/tools/zap/tests/outputs/lighting-app/app-templates/access.h @@ -33,9 +33,6 @@ /* Cluster: Level Control, Attribute: StartUpCurrentLevel, Privilege: view */ \ 0x0000001F, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ 0x0000001F, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ - /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ /* Cluster: Basic Information, Attribute: NodeLabel, Privilege: view */ \ /* Cluster: Basic Information, Attribute: Location, Privilege: view */ \ /* Cluster: Basic Information, Attribute: LocalConfigDisabled, Privilege: view */ \ @@ -59,9 +56,6 @@ /* Cluster: Level Control, Attribute: StartUpCurrentLevel, Privilege: view */ \ 0x00000000, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ 0x00000001, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ - /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ /* Cluster: Basic Information, Attribute: NodeLabel, Privilege: view */ \ /* Cluster: Basic Information, Attribute: Location, Privilege: view */ \ /* Cluster: Basic Information, Attribute: LocalConfigDisabled, Privilege: view */ \ @@ -85,9 +79,6 @@ /* Cluster: Level Control, Attribute: StartUpCurrentLevel, Privilege: view */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Attribute: ACL, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Attribute: Extension, Privilege: administer */ \ - /* Cluster: Access Control, Attribute: SubjectsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: TargetsPerAccessControlEntry, Privilege: view */ \ - /* Cluster: Access Control, Attribute: AccessControlEntriesPerFabric, Privilege: view */ \ /* Cluster: Basic Information, Attribute: NodeLabel, Privilege: view */ \ /* Cluster: Basic Information, Attribute: Location, Privilege: view */ \ /* Cluster: Basic Information, Attribute: LocalConfigDisabled, Privilege: view */ \ @@ -301,18 +292,24 @@ #define GENERATED_ACCESS_READ_EVENT__CLUSTER { \ 0x0000001F, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ 0x0000001F, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ + 0x0000001F, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ + 0x0000001F, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } // Parallel array data (cluster, *event*, privilege) for read event #define GENERATED_ACCESS_READ_EVENT__EVENT { \ 0x00000000, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ 0x00000001, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ + 0x00000002, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ + 0x00000003, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } // Parallel array data (cluster, event, *privilege*) for read event #define GENERATED_ACCESS_READ_EVENT__PRIVILEGE { \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessControlEntryChanged, Privilege: administer */ \ chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessControlExtensionChanged, Privilege: administer */ \ + chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: AccessRestrictionEntryChanged, Privilege: administer */ \ + chip::Access::Privilege::kAdminister, /* Cluster: Access Control, Event: FabricRestrictionReviewUpdate, Privilege: administer */ \ } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 7a439a4141ce49..ce65fe42331acb 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -398,6 +398,20 @@ template("chip_data_model") { "${_app_root}/clusters/${cluster}/thread-network-diagnostics-provider.cpp", "${_app_root}/clusters/${cluster}/thread-network-diagnostics-provider.h", ] + } else if (cluster == "service-area-server") { + sources += [ + "${_app_root}/clusters/${cluster}/${cluster}.cpp", + "${_app_root}/clusters/${cluster}/${cluster}.h", + "${_app_root}/clusters/${cluster}/service-area-cluster-objects.h", + "${_app_root}/clusters/${cluster}/service-area-delegate.cpp", + "${_app_root}/clusters/${cluster}/service-area-delegate.h", + ] + } else if (cluster == "thread-border-router-management-server") { + sources += [ + "${_app_root}/clusters/${cluster}/thread-border-router-management-server.cpp", + "${_app_root}/clusters/${cluster}/thread-border-router-management-server.h", + "${_app_root}/clusters/${cluster}/thread-br-delegate.h", + ] } else if (cluster == "water-heater-management-server") { sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp", @@ -412,6 +426,14 @@ template("chip_data_model") { "${_app_root}/clusters/${cluster}/DefaultThreadNetworkDirectoryStorage.h", "${_app_root}/clusters/${cluster}/ThreadNetworkDirectoryStorage.h", ] + } else if (cluster == "thermostat-server") { + sources += [ + "${_app_root}/clusters/${cluster}/${cluster}.cpp", + "${_app_root}/clusters/${cluster}/${cluster}.h", + "${_app_root}/clusters/${cluster}/PresetStructWithOwnedMembers.cpp", + "${_app_root}/clusters/${cluster}/PresetStructWithOwnedMembers.h", + "${_app_root}/clusters/${cluster}/thermostat-delegate.h", + ] } else { sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp" ] } diff --git a/src/app/clusters/basic-information/basic-information.cpp b/src/app/clusters/basic-information/basic-information.cpp index b550026b5f1cd7..bd45a1035164b5 100644 --- a/src/app/clusters/basic-information/basic-information.cpp +++ b/src/app/clusters/basic-information/basic-information.cpp @@ -342,7 +342,7 @@ CHIP_ERROR BasicAttrAccess::Write(const ConcreteDataAttributePath & aPath, Attri switch (aPath.mAttributeId) { - case Location::Id: { + case Attributes::Location::Id: { CHIP_ERROR err = WriteLocation(aDecoder); return err; diff --git a/src/app/clusters/level-control/level-control.cpp b/src/app/clusters/level-control/level-control.cpp index 738a7b10ed0ffb..00d8a2e496518f 100644 --- a/src/app/clusters/level-control/level-control.cpp +++ b/src/app/clusters/level-control/level-control.cpp @@ -369,7 +369,7 @@ static void reallyUpdateCoupledColorTemp(EndpointId endpoint) /* * @brief * This function is used to update the current level attribute - * while respecting it's defined quiet reporting quality: + * while respecting its defined quiet reporting quality: * The attribute will be reported: * - At most once per second, or * - At the start of the movement/transition, or @@ -386,8 +386,7 @@ static Status SetCurrentLevelQuietReport(EndpointId endpoint, EmberAfLevelContro DataModel::Nullable newValue, bool isStartOrEndOfTransition) { AttributeDirtyState dirtyState; - MarkAttributeDirty markDirty = MarkAttributeDirty::kNo; - auto now = System::SystemClock().GetMonotonicTimestamp(); + auto now = System::SystemClock().GetMonotonicTimestamp(); if (isStartOrEndOfTransition) { @@ -406,9 +405,10 @@ static Status SetCurrentLevelQuietReport(EndpointId endpoint, EmberAfLevelContro dirtyState = state->quietCurrentLevel.SetValue(newValue, now, predicate); } + MarkAttributeDirty markDirty = MarkAttributeDirty::kNo; if (dirtyState == AttributeDirtyState::kMustReport) { - markDirty = MarkAttributeDirty::kIfChanged; + markDirty = MarkAttributeDirty::kYes; } return Attributes::CurrentLevel::Set(endpoint, state->quietCurrentLevel.value(), markDirty); } @@ -542,7 +542,7 @@ static void writeRemainingTime(EndpointId endpoint, uint16_t remainingTimeMs) // - kMarkDirtyOnIncrement : When the value increases. if (state->quietRemainingTime.SetValue(remainingTimeDs, now) == AttributeDirtyState::kMustReport) { - markDirty = MarkAttributeDirty::kIfChanged; + markDirty = MarkAttributeDirty::kYes; } Attributes::RemainingTime::Set(endpoint, state->quietRemainingTime.value().ValueOr(0), markDirty); diff --git a/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp b/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp index 50056387e3c359..4a3ba4103a0b0d 100644 --- a/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp +++ b/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.cpp @@ -1,6 +1,6 @@ /** * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2024 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +16,158 @@ */ #include "occupancy-sensor-server.h" +#include "occupancy-hal.h" -#include +#include +#include +#include +#include +#include +#include -#include "occupancy-hal.h" +using chip::Protocols::InteractionModel::Status; + +namespace chip { +namespace app { +namespace Clusters { +namespace OccupancySensing { + +namespace { +Structs::HoldTimeLimitsStruct::Type + sHoldTimeLimitsStructs[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT]; + +uint16_t sHoldTime[MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT]; +} // namespace + +CHIP_ERROR OccupancySensingAttrAccess::Init() +{ + VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); + return CHIP_NO_ERROR; +} + +void OccupancySensingAttrAccess::Shutdown() +{ + unregisterAttributeAccessOverride(this); +} + +CHIP_ERROR OccupancySensingAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + VerifyOrDie(aPath.mClusterId == app::Clusters::OccupancySensing::Id); + + switch (aPath.mAttributeId) + { + case Attributes::FeatureMap::Id: + ReturnErrorOnFailure(aEncoder.Encode(mFeature)); + break; + case Attributes::HoldTime::Id: { + + uint16_t * holdTime = GetHoldTimeForEndpoint(aPath.mEndpointId); + + if (holdTime == nullptr) + { + return CHIP_ERROR_NOT_FOUND; + } + + return aEncoder.Encode(*holdTime); + } + case Attributes::HoldTimeLimits::Id: { + + Structs::HoldTimeLimitsStruct::Type * holdTimeLimitsStruct = GetHoldTimeLimitsForEndpoint(aPath.mEndpointId); + + if (holdTimeLimitsStruct == nullptr) + { + return CHIP_ERROR_NOT_FOUND; + } + + return aEncoder.Encode(*holdTimeLimitsStruct); + } + default: + return CHIP_NO_ERROR; + } + + return CHIP_NO_ERROR; +} + +bool OccupancySensingAttrAccess::HasFeature(Feature aFeature) const +{ + return mFeature.Has(aFeature); +} + +Structs::HoldTimeLimitsStruct::Type * GetHoldTimeLimitsForEndpoint(EndpointId endpoint) +{ + auto index = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::OccupancySensing::Id, + MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (index == kEmberInvalidEndpointIndex) + { + return nullptr; + } + + if (index >= ArraySize(sHoldTimeLimitsStructs)) + { + ChipLogError(NotSpecified, "Internal error: invalid/unexpected hold time limits index."); + return nullptr; + } + return &sHoldTimeLimitsStructs[index]; +} + +CHIP_ERROR SetHoldTimeLimits(EndpointId endpointId, const Structs::HoldTimeLimitsStruct::Type & holdTimeLimits) +{ + + VerifyOrReturnError(kInvalidEndpointId != endpointId, CHIP_ERROR_INVALID_ARGUMENT); + + Structs::HoldTimeLimitsStruct::Type * holdTimeLimitsForEndpoint = GetHoldTimeLimitsForEndpoint(endpointId); + VerifyOrReturnError(holdTimeLimitsForEndpoint != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + holdTimeLimitsForEndpoint->holdTimeMin = holdTimeLimits.holdTimeMin; + holdTimeLimitsForEndpoint->holdTimeMax = holdTimeLimits.holdTimeMax; + holdTimeLimitsForEndpoint->holdTimeDefault = holdTimeLimits.holdTimeDefault; + + MatterReportingAttributeChangeCallback(endpointId, OccupancySensing::Id, Attributes::HoldTimeLimits::Id); + + return CHIP_NO_ERROR; +} + +uint16_t * GetHoldTimeForEndpoint(EndpointId endpoint) +{ + auto index = emberAfGetClusterServerEndpointIndex(endpoint, app::Clusters::OccupancySensing::Id, + MATTER_DM_OCCUPANCY_SENSING_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (index == kEmberInvalidEndpointIndex) + { + return nullptr; + } + + if (index >= ArraySize(sHoldTimeLimitsStructs)) + { + ChipLogError(NotSpecified, "Internal error: invalid/unexpected hold time index."); + return nullptr; + } + return &sHoldTime[index]; +} + +CHIP_ERROR SetHoldTime(EndpointId endpointId, const uint16_t & holdTime) +{ + VerifyOrReturnError(kInvalidEndpointId != endpointId, CHIP_ERROR_INVALID_ARGUMENT); + + uint16_t * holdTimeForEndpoint = GetHoldTimeForEndpoint(endpointId); + VerifyOrReturnError(holdTimeForEndpoint != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + *holdTimeForEndpoint = holdTime; + + MatterReportingAttributeChangeCallback(endpointId, OccupancySensing::Id, Attributes::HoldTime::Id); + + return CHIP_NO_ERROR; +} + +} // namespace OccupancySensing +} // namespace Clusters +} // namespace app +} // namespace chip using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; using namespace chip::app::Clusters::OccupancySensing; //****************************************************************************** @@ -59,8 +205,6 @@ void emberAfOccupancySensingClusterServerInitCallback(EndpointId endpoint) break; } Attributes::OccupancySensorTypeBitmap::Set(endpoint, deviceTypeBitmap); - - emberAfPluginOccupancyClusterServerPostInitCallback(endpoint); } //****************************************************************************** @@ -82,8 +226,6 @@ void halOccupancyStateChangedCallback(EndpointId endpoint, HalOccupancyState occ Attributes::Occupancy::Set(endpoint, occupancyState); } -void emberAfPluginOccupancyClusterServerPostInitCallback(EndpointId endpoint) {} - HalOccupancySensorType __attribute__((weak)) halOccupancyGetSensorType(EndpointId endpoint) { return HAL_OCCUPANCY_SENSOR_TYPE_PIR; diff --git a/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.h b/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.h index 3ed762cbfb4013..f24c64f4dbfbb1 100644 --- a/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.h +++ b/src/app/clusters/occupancy-sensor-server/occupancy-sensor-server.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020-2024 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,15 +17,48 @@ #pragma once +#include +#include +#include #include #include +#include +#include -/** @brief Occupancy Cluster Server Post Init - * - * Following resolution of the Occupancy state at startup for this endpoint, - * perform any additional initialization needed; e.g., synchronize hardware - * state. - * - * @param endpoint Endpoint that is being initialized Ver.: always - */ -void emberAfPluginOccupancyClusterServerPostInitCallback(chip::EndpointId endpoint); +namespace chip { +namespace app { +namespace Clusters { +namespace OccupancySensing { + +class OccupancySensingAttrAccess : public AttributeAccessInterface +{ +public: + OccupancySensingAttrAccess(BitMask aFeature) : + app::AttributeAccessInterface(Optional::Missing(), app::Clusters::OccupancySensing::Id), mFeature(aFeature) + {} + + ~OccupancySensingAttrAccess() { Shutdown(); } + + CHIP_ERROR Init(); + void Shutdown(); + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + + bool HasFeature(Feature aFeature) const; + +private: + BitMask mFeature; +}; + +CHIP_ERROR SetHoldTimeLimits(EndpointId endpointId, const Structs::HoldTimeLimitsStruct::Type & holdTimeLimits); + +CHIP_ERROR SetHoldTime(EndpointId endpointId, const uint16_t & holdTime); + +Structs::HoldTimeLimitsStruct::Type * GetHoldTimeLimitsForEndpoint(EndpointId endpoint); + +uint16_t * GetHoldTimeForEndpoint(EndpointId endpoint); + +} // namespace OccupancySensing +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/operational-state-server/operational-state-server.cpp b/src/app/clusters/operational-state-server/operational-state-server.cpp index b6ae0d7a221253..c86de02bfab6ae 100644 --- a/src/app/clusters/operational-state-server/operational-state-server.cpp +++ b/src/app/clusters/operational-state-server/operational-state-server.cpp @@ -29,6 +29,7 @@ #include #include #include +#include using namespace chip; using namespace chip::app; @@ -43,6 +44,9 @@ Instance::Instance(Delegate * aDelegate, EndpointId aEndpointId, ClusterId aClus mDelegate(aDelegate), mEndpointId(aEndpointId), mClusterId(aClusterId) { mDelegate->SetInstance(this); + mCountdownTime.policy() + .Set(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement) + .Set(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero); } Instance::Instance(Delegate * aDelegate, EndpointId aEndpointId) : Instance(aDelegate, aEndpointId, OperationalState::Id) {} @@ -84,6 +88,7 @@ CHIP_ERROR Instance::SetCurrentPhase(const DataModel::Nullable & aPhase if (mCurrentPhase != oldPhase) { MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::CurrentPhase::Id); + UpdateCountdownTimeFromClusterLogic(); } return CHIP_NO_ERROR; } @@ -96,9 +101,11 @@ CHIP_ERROR Instance::SetOperationalState(uint8_t aOpState) return CHIP_ERROR_INVALID_ARGUMENT; } + bool countdownTimeUpdateNeeded = false; if (mOperationalError.errorStateID != to_underlying(ErrorStateEnum::kNoError)) { mOperationalError.Set(to_underlying(ErrorStateEnum::kNoError)); + countdownTimeUpdateNeeded = true; MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::OperationalError::Id); } @@ -107,6 +114,12 @@ CHIP_ERROR Instance::SetOperationalState(uint8_t aOpState) if (mOperationalState != oldState) { MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::OperationalState::Id); + countdownTimeUpdateNeeded = true; + } + + if (countdownTimeUpdateNeeded) + { + UpdateCountdownTimeFromClusterLogic(); } return CHIP_NO_ERROR; } @@ -143,6 +156,8 @@ void Instance::OnOperationalErrorDetected(const Structs::ErrorStateStruct::Type MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::OperationalError::Id); } + UpdateCountdownTimeFromClusterLogic(); + // Generate an ErrorDetected event GenericErrorEvent event(mClusterId, aError); EventNumber eventNumber; @@ -156,7 +171,7 @@ void Instance::OnOperationalErrorDetected(const Structs::ErrorStateStruct::Type void Instance::OnOperationCompletionDetected(uint8_t aCompletionErrorCode, const Optional> & aTotalOperationalTime, - const Optional> & aPausedTime) const + const Optional> & aPausedTime) { ChipLogDetail(Zcl, "OperationalStateServer: OnOperationCompletionDetected"); @@ -169,6 +184,8 @@ void Instance::OnOperationCompletionDetected(uint8_t aCompletionErrorCode, ChipLogError(Zcl, "OperationalStateServer: Failed to record OperationCompletion event: %" CHIP_ERROR_FORMAT, error.Format()); } + + UpdateCountdownTimeFromClusterLogic(); } void Instance::ReportOperationalStateListChange() @@ -179,6 +196,43 @@ void Instance::ReportOperationalStateListChange() void Instance::ReportPhaseListChange() { MatterReportingAttributeChangeCallback(ConcreteAttributePath(mEndpointId, mClusterId, Attributes::PhaseList::Id)); + UpdateCountdownTimeFromClusterLogic(); +} + +void Instance::UpdateCountdownTime(bool fromDelegate) +{ + app::DataModel::Nullable newCountdownTime = mDelegate->GetCountdownTime(); + auto now = System::SystemClock().GetMonotonicTimestamp(); + + bool markDirty = false; + + if (fromDelegate) + { + // Updates from delegate are reduce-reported to every 10s max (choice of this implementation), in addition + // to default change-from-null, change-from-zero and increment policy. + auto predicate = [](const decltype(mCountdownTime)::SufficientChangePredicateCandidate & candidate) -> bool { + if (candidate.lastDirtyValue.IsNull() || candidate.newValue.IsNull()) + { + return false; + } + + uint32_t lastDirtyValue = candidate.lastDirtyValue.Value(); + uint32_t newValue = candidate.newValue.Value(); + uint32_t kNumSecondsDeltaToReport = 10; + return (newValue < lastDirtyValue) && ((lastDirtyValue - newValue) > kNumSecondsDeltaToReport); + }; + markDirty = (mCountdownTime.SetValue(newCountdownTime, now, predicate) == AttributeDirtyState::kMustReport); + } + else + { + auto predicate = [](const decltype(mCountdownTime)::SufficientChangePredicateCandidate &) -> bool { return true; }; + markDirty = (mCountdownTime.SetValue(newCountdownTime, now, predicate) == AttributeDirtyState::kMustReport); + } + + if (markDirty) + { + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::CountdownTime::Id); + } } bool Instance::IsSupportedPhase(uint8_t aPhase) @@ -270,6 +324,7 @@ void Instance::InvokeCommand(HandlerContext & handlerContext) ChipLogDetail(Zcl, "OperationalState: Entering handling derived cluster commands"); InvokeDerivedClusterCommand(handlerContext); + break; } } @@ -294,18 +349,18 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu } return err; }); + break; } - break; case OperationalState::Attributes::OperationalState::Id: { ReturnErrorOnFailure(aEncoder.Encode(GetCurrentOperationalState())); + break; } - break; case OperationalState::Attributes::OperationalError::Id: { ReturnErrorOnFailure(aEncoder.Encode(mOperationalError)); + break; } - break; case OperationalState::Attributes::PhaseList::Id: { @@ -332,18 +387,19 @@ CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValu ReturnErrorOnFailure(encoder.Encode(phase2)); } }); + break; } - break; case OperationalState::Attributes::CurrentPhase::Id: { ReturnErrorOnFailure(aEncoder.Encode(GetCurrentPhase())); + break; } - break; case OperationalState::Attributes::CountdownTime::Id: { + // Read through to get value closest to reality. ReturnErrorOnFailure(aEncoder.Encode(mDelegate->GetCountdownTime())); + break; } - break; } return CHIP_NO_ERROR; } diff --git a/src/app/clusters/operational-state-server/operational-state-server.h b/src/app/clusters/operational-state-server/operational-state-server.h index c1640cb99e9ce7..56229c02541d60 100644 --- a/src/app/clusters/operational-state-server/operational-state-server.h +++ b/src/app/clusters/operational-state-server/operational-state-server.h @@ -22,6 +22,8 @@ #include #include #include +#include +#include namespace chip { namespace app { @@ -113,6 +115,12 @@ class Instance : public CommandHandlerInterface, public AttributeAccessInterface */ void GetCurrentOperationalError(GenericOperationalError & error) const; + /** + * @brief Whenever application delegate wants to possibly report a new updated time, + * call this method. The `GetCountdownTime()` method will be called on the delegate. + */ + void UpdateCountdownTimeFromDelegate() { UpdateCountdownTime(/* fromDelegate = */ true); } + // Event triggers /** * @brief Called when the Node detects a OperationalError has been raised. @@ -129,7 +137,7 @@ class Instance : public CommandHandlerInterface, public AttributeAccessInterface */ void OnOperationCompletionDetected(uint8_t aCompletionErrorCode, const Optional> & aTotalOperationalTime = NullOptional, - const Optional> & aPausedTime = NullOptional) const; + const Optional> & aPausedTime = NullOptional); // List change reporting /** @@ -192,6 +200,19 @@ class Instance : public CommandHandlerInterface, public AttributeAccessInterface */ virtual void InvokeDerivedClusterCommand(HandlerContext & handlerContext) { return; }; + /** + * Causes reporting/udpating of CountdownTime attribute from driver if sufficient changes have + * occurred (based on Q quality definition for operational state). Calls the Delegate::GetCountdownTime() method. + * + * @param fromDelegate true if the change notice was triggered by the delegate, false if internal to cluster logic. + */ + void UpdateCountdownTime(bool fromDelegate); + + /** + * @brief Whenever the cluster logic thinks time should be updated, call this. + */ + void UpdateCountdownTimeFromClusterLogic() { UpdateCountdownTime(/* fromDelegate=*/false); } + private: Delegate * mDelegate; @@ -202,6 +223,7 @@ class Instance : public CommandHandlerInterface, public AttributeAccessInterface app::DataModel::Nullable mCurrentPhase; uint8_t mOperationalState = 0; // assume 0 for now. GenericOperationalError mOperationalError = to_underlying(ErrorStateEnum::kNoError); + app::QuieterReportingAttribute mCountdownTime{ DataModel::NullNullable }; /** * This method is inherited from CommandHandlerInterface. @@ -262,9 +284,10 @@ class Delegate virtual ~Delegate() = default; /** - * Get the countdown time. - * NOTE: Changes to this attribute should not be reported. - * From the spec: Changes to this value SHALL NOT be reported in a subscription. + * Get the countdown time. This will get called on many edges such as + * commands to change operational state, or when the delegate deals with + * changes. Make sure it becomes null whenever it is appropriate. + * * @return The current countdown time. */ virtual app::DataModel::Nullable GetCountdownTime() = 0; diff --git a/src/app/clusters/scenes-server/scenes-server.cpp b/src/app/clusters/scenes-server/scenes-server.cpp index e657a82f4654fe..7c215c20446948 100644 --- a/src/app/clusters/scenes-server/scenes-server.cpp +++ b/src/app/clusters/scenes-server/scenes-server.cpp @@ -376,9 +376,10 @@ void AddSceneParse(CommandHandlerInterface::HandlerContext & ctx, const CommandD response.sceneID = req.sceneID; // Verify the attributes are respecting constraints - if (req.transitionTime > scenes::kScenesMaxTransitionTime || req.sceneName.size() > scenes::kSceneNameMaxLength) + if (req.transitionTime > scenes::kScenesMaxTransitionTime || req.sceneName.size() > scenes::kSceneNameMaxLength || + req.sceneID == scenes::kUndefinedSceneId) { - response.status = to_underlying(Protocols::InteractionModel::Status::InvalidCommand); + response.status = to_underlying(Protocols::InteractionModel::Status::ConstraintError); ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); return; } @@ -483,6 +484,14 @@ void ViewSceneParse(HandlerContext & ctx, const CommandData & req, GroupDataProv response.groupID = req.groupID; response.sceneID = req.sceneID; + // Verify the attributes are respecting constraints + if (req.sceneID == scenes::kUndefinedSceneId) + { + response.status = to_underlying(Protocols::InteractionModel::Status::ConstraintError); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + return; + } + // Verify Endpoint in group VerifyOrReturn(nullptr != groupProvider); if (0 != req.groupID && @@ -830,6 +839,14 @@ void ScenesServer::HandleRemoveScene(HandlerContext & ctx, const Commands::Remov response.groupID = req.groupID; response.sceneID = req.sceneID; + // Verify the attributes are respecting constraints + if (req.sceneID == scenes::kUndefinedSceneId) + { + response.status = to_underlying(Protocols::InteractionModel::Status::ConstraintError); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + return; + } + // Scene Table interface data SceneTableEntry scene(SceneStorageId(req.sceneID, req.groupID)); @@ -930,6 +947,14 @@ void ScenesServer::HandleStoreScene(HandlerContext & ctx, const Commands::StoreS response.groupID = req.groupID; response.sceneID = req.sceneID; + // Verify the attributes are respecting constraints + if (req.sceneID == scenes::kUndefinedSceneId) + { + response.status = to_underlying(Protocols::InteractionModel::Status::ConstraintError); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + return; + } + CHIP_ERROR err = StoreSceneParse(ctx.mCommandHandler.GetAccessingFabricIndex(), ctx.mRequestPath.mEndpointId, req.groupID, req.sceneID, mGroupProvider); @@ -943,6 +968,14 @@ void ScenesServer::HandleStoreScene(HandlerContext & ctx, const Commands::StoreS void ScenesServer::HandleRecallScene(HandlerContext & ctx, const Commands::RecallScene::DecodableType & req) { MATTER_TRACE_SCOPE("RecallScene", "Scenes"); + + // Verify the attributes are respecting constraints + if (req.sceneID == scenes::kUndefinedSceneId) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::ConstraintError); + return; + } + CHIP_ERROR err = RecallSceneParse(ctx.mCommandHandler.GetAccessingFabricIndex(), ctx.mRequestPath.mEndpointId, req.groupID, req.sceneID, req.transitionTime, mGroupProvider); @@ -1025,6 +1058,14 @@ void ScenesServer::HandleCopyScene(HandlerContext & ctx, const Commands::CopySce response.groupIdentifierFrom = req.groupIdentifierFrom; response.sceneIdentifierFrom = req.sceneIdentifierFrom; + // Verify the attributes are respecting constraints + if (req.sceneIdentifierFrom == scenes::kUndefinedSceneId || req.sceneIdentifierTo == scenes::kUndefinedSceneId) + { + response.status = to_underlying(Protocols::InteractionModel::Status::ResourceExhausted); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + return; + } + // Verify Endpoint in group VerifyOrReturn(nullptr != mGroupProvider); if ((0 != req.groupIdentifierFrom && diff --git a/src/app/clusters/service-area-server/service-area-cluster-objects.h b/src/app/clusters/service-area-server/service-area-cluster-objects.h new file mode 100644 index 00000000000000..e46704796f74c3 --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-cluster-objects.h @@ -0,0 +1,358 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ServiceArea { + +// These limits are defined in the spec. +inline constexpr size_t kLocationNameMaxSize = 128u; +inline constexpr size_t kMapNameMaxSize = 64u; + +/** + * This class is used to wrap the LocationStruct object and provide a more user-friendly interface for the data. + * It provides a way to store the location name in a buffer, and provides a way to compare the location name with a given string. + */ +struct LocationStructureWrapper : public chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type +{ + LocationStructureWrapper() + { + Set(0, 0, CharSpan(), DataModel::Nullable(), DataModel::Nullable(), + DataModel::Nullable(), DataModel::Nullable(), DataModel::Nullable()); + } + + /** + * @brief This is a full constructor that initializes the location object with the given values. All values are deep copied. + * @param[in] aLocationId The unique identifier of this location. + * @param[in] aMapId The identifier of the supported map associated with this location. + * @param[in] aLocationName A human readable name for this location (empty string if not used). + * @param[in] aFloorNumber The floor level of this location - use negative values for below ground. + * @param[in] aAreaTypeTag A common namespace Area tag - indicates an association of the location with an indoor or outdoor area + * of a home. + * @param[in] aLandmarkTag A common namespace Landmark tag - indicates an association of the location with a home landmark. + * @param[in] aPositionTag A common namespace Position tag - indicates the position of the location with respect to the + * landmark. + * @param[in] aSurfaceTag A common namespace Floor Surface tag - indicates an association of the location with a surface type. + * + * @note Requirements regarding what combinations of fields and values are valid are not checked by this class. + * @note If aLocationName is larger than kLocationNameMaxSize, it will be truncated. + * @note If aLocationName is an empty string and aFloorNumber and aAreaTypeTag are null, locationInfo will be set to null. + */ + LocationStructureWrapper(uint32_t aLocationId, const DataModel::Nullable & aMapId, const CharSpan & aLocationName, + const DataModel::Nullable & aFloorNumber, + const DataModel::Nullable & aAreaTypeTag, + const DataModel::Nullable & aLandmarkTag, + const DataModel::Nullable & aPositionTag, + const DataModel::Nullable & aSurfaceTag) + { + Set(aLocationId, aMapId, aLocationName, aFloorNumber, aAreaTypeTag, aLandmarkTag, aPositionTag, aSurfaceTag); + } + + /** + * @brief This is a copy constructor that initializes the location object with the values from another location object. All + * values are deep copied. + * @param[in] aOther The location object to copy. + * + * @note If the locationName is empty string and aFloorNumber and aAreaTypeTag are null, locationInfo will be set to null. + */ + LocationStructureWrapper(const LocationStructureWrapper & aOther) { *this = aOther; } + + /** + * @brief This is an assignment operator that initializes the location object with the values from another location object. All + * values are deep copied. + * @param[in] aOther The location object to copy. + * + * @note If the locationName is empty string and aFloorNumber and aAreaTypeTag are null, locationInfo will be set to null. + */ + LocationStructureWrapper & operator=(const LocationStructureWrapper & aOther) + { + if (aOther.locationInfo.locationInfo.IsNull()) + { + Set(aOther.locationID, aOther.mapID, CharSpan(), NullOptional, NullOptional, aOther.locationInfo.landmarkTag, + aOther.locationInfo.positionTag, aOther.locationInfo.surfaceTag); + } + else + { + Set(aOther.locationID, aOther.mapID, aOther.locationInfo.locationInfo.Value().locationName, + aOther.locationInfo.locationInfo.Value().floorNumber, aOther.locationInfo.locationInfo.Value().areaType, + aOther.locationInfo.landmarkTag, aOther.locationInfo.positionTag, aOther.locationInfo.surfaceTag); + } + + return *this; + } + + /** + * @brief Set all fields of the location object. All values are deep copied. + * @param[in] aLocationId The unique identifier of this location. + * @param[in] aMapId The identifier of the supported map associated with this location. + * @param[in] aLocationName A human readable name for this location (empty string if not used). + * @param[in] aFloorNumber The floor level of this location - use negative values for below ground. + * @param[in] aAreaTypeTag A common namespace Area tag - indicates an association of the location with an indoor or outdoor area + * of a home. + * @param[in] aLandmarkTag A common namespace Landmark tag - indicates an association of the location with a home landmark. + * @param[in] aPositionTag A common namespace Position tag - indicates the position of the location with respect to the + * landmark. + * @param[in] aSurfaceTag A common namespace Floor Surface tag - indicates an association of the location with a surface type. + * + * @note Requirements regarding what combinations of fields and values are valid are not checked by this class. + * @note If aLocationName is larger than kLocationNameMaxSize, it will be truncated. + * @note If aLocationName is an empty string and aFloorNumber and aAreaTypeTag are null, locationInfo will be set to null. + */ + void Set(uint32_t aLocationId, const DataModel::Nullable & aMapId, const CharSpan & aLocationName, + const DataModel::Nullable & aFloorNumber, const DataModel::Nullable & aAreaType, + const DataModel::Nullable & aLandmarkTag, const DataModel::Nullable & aPositionTag, + const DataModel::Nullable & aSurfaceTag) + { + locationID = aLocationId; + mapID = aMapId; + + // If there is at least one non-null value for locationInfo, add it to the location structure. + if ((!aLocationName.empty()) || (!aFloorNumber.IsNull()) || (!aAreaType.IsNull())) + { + // Create a home location info structure and fill it in except for the location name. This is done below. + locationInfo.locationInfo.SetNonNull(Structs::LocationDescriptorStruct::Type()); + + locationInfo.locationInfo.Value().floorNumber = aFloorNumber; + locationInfo.locationInfo.Value().areaType = aAreaType; + } + else + { + locationInfo.locationInfo.SetNull(); + } + + locationInfo.landmarkTag = aLandmarkTag; + locationInfo.positionTag = aPositionTag; + locationInfo.surfaceTag = aSurfaceTag; + + // this assumes locationInfo structure was created above, if appropriate + if (!locationInfo.locationInfo.IsNull()) + { + if (aLocationName.empty()) + { + locationInfo.locationInfo.Value().locationName = CharSpan(mLocationNameBuffer, 0); + } + else if (aLocationName.size() > sizeof(mLocationNameBuffer)) + { + // Save the truncated name that fits into available size. + memcpy(mLocationNameBuffer, aLocationName.data(), sizeof(mLocationNameBuffer)); + locationInfo.locationInfo.Value().locationName = CharSpan(mLocationNameBuffer, sizeof(mLocationNameBuffer)); + } + else + { + // Save full name. + memcpy(mLocationNameBuffer, aLocationName.data(), aLocationName.size()); + locationInfo.locationInfo.Value().locationName = CharSpan(mLocationNameBuffer, aLocationName.size()); + } + } + } + + /** + * @brief Compare the location's name with the given text. + * @param[in] aLocationName The name to compare. + * @return true if the location structure's name field matches aLocationName. + * False otherwise, including if the location structure's HomeLocation structure is null. + */ + bool IsNameEqual(const CharSpan & aLocationName) const + { + if (!locationInfo.locationInfo.IsNull()) + { + return locationInfo.locationInfo.Value().locationName.data_equal(aLocationName); + } + + return false; + } + + /** + * This is used for configuring the IsEqual method. + * If kIgnoreLocationId is set, the location IDs are ignored when checking for equality. + * If kIgnoreMapId is set, the map IDs are ignored when checking for equality. + */ + enum class IsEqualConfig : uint8_t + { + kIgnoreLocationId = 0x1, + kIgnoreMapId = 0x2, + }; + + /** + * @brief Checks if the given LocationStructureWrapper is equal to this one. + * @param aOther The location to compare with. + * @param aConfig Set if the location IDs and/or the map IDs should be ignored when checking for equality. + * @return True if both locations are equal. False otherwise. + */ + bool IsEqual(const LocationStructureWrapper & aOther, BitMask aConfig) const + { + if (!aConfig.Has(IsEqualConfig::kIgnoreLocationId) && (locationID != aOther.locationID)) + { + return false; + } + + if (!aConfig.Has(IsEqualConfig::kIgnoreMapId) && (mapID != aOther.mapID)) + { + return false; + } + + if (locationInfo.locationInfo.IsNull() != aOther.locationInfo.locationInfo.IsNull()) + { + return false; + } + + if (!locationInfo.locationInfo.IsNull()) + { + + if (!IsNameEqual(aOther.locationInfo.locationInfo.Value().locationName)) + { + return false; + } + + if (locationInfo.locationInfo.Value().floorNumber != aOther.locationInfo.locationInfo.Value().floorNumber) + { + return false; + } + + if (locationInfo.locationInfo.Value().areaType != aOther.locationInfo.locationInfo.Value().areaType) + { + return false; + } + } + + if (locationInfo.landmarkTag != aOther.locationInfo.landmarkTag) + { + return false; + } + + if (locationInfo.positionTag != aOther.locationInfo.positionTag) + { + return false; + } + + if (locationInfo.surfaceTag != aOther.locationInfo.surfaceTag) + { + return false; + } + + return true; + } + + /** + * @return The location name. + */ + CharSpan GetName() + { + if (locationInfo.locationInfo.IsNull()) + { + return { mLocationNameBuffer, 0 }; + } + + return locationInfo.locationInfo.Value().locationName; + } + +private: + char mLocationNameBuffer[kLocationNameMaxSize] = { 0 }; +}; + +/** + * This class wraps the MapStruct object and provides a more user-friendly interface for the data. + */ +struct MapStructureWrapper : public chip::app::Clusters::ServiceArea::Structs::MapStruct::Type +{ + MapStructureWrapper() { Set(0, CharSpan()); } + + /** + * @brief This is a full constructor that initializes the map object with the given values. All values are deep copied. + * @param[in] aMapId The identifier of this map. + * @param[in] aMapName A human readable name (should not be empty string). + * + * @note Requirements regarding what combinations of fields and values are 'valid' are not checked by this class. + * @note If aMapName is larger than kMapNameMaxSize, it will be truncated. + */ + MapStructureWrapper(uint8_t aMapId, const CharSpan & aMapName) { Set(aMapId, aMapName); } + + /** + * @brief This is a copy constructor that initializes the map object with the values from another map object. All values are + * deep copied. + * @param[in] aOther The map object to copy. + */ + MapStructureWrapper(const MapStructureWrapper & aOther) { *this = aOther; } + + /** + * @brief This is an assignment operator that initializes the map object with the values from another map object. All values are + * deep copied. + * @param[in] aOther The map object to copy. + */ + MapStructureWrapper & operator=(const MapStructureWrapper & aOther) + { + Set(aOther.mapID, aOther.name); + return *this; + } + + /** + * @brief Set all fields of the map object. All values are deep copied. + * @param[in] aMapId The identifier of this map. + * @param[in] aMapName A human readable name (should not be empty string). + * + * @note Requirements regarding what combinations of fields and values are 'valid' are not checked by this class. + * @note if aMapName is larger than kMapNameMaxSize, it will be truncated. + */ + void Set(uint8_t aMapId, const CharSpan & aMapName) + { + mapID = aMapId; + + if (aMapName.empty()) + { + name = CharSpan(mMapNameBuffer, 0); + } + else if (aMapName.size() > sizeof(mMapNameBuffer)) + { + // Save the truncated name that fits into available size. + memcpy(mMapNameBuffer, aMapName.data(), sizeof(mMapNameBuffer)); + name = CharSpan(mMapNameBuffer, sizeof(mMapNameBuffer)); + } + else + { + // Save full name. + memcpy(mMapNameBuffer, aMapName.data(), aMapName.size()); + name = CharSpan(mMapNameBuffer, aMapName.size()); + } + } + + /** + * @brief Compare the map's name with given text. + * @param[in] aMapName The name to compare. + * @return true if the map structure's name field matches aMapName. + */ + bool IsNameEqual(const CharSpan & aMapName) const { return name.data_equal(aMapName); } + + /** + * @return The map name. + */ + CharSpan GetName() const { return name; } + +private: + char mMapNameBuffer[kMapNameMaxSize] = { 0 }; +}; + +} // namespace ServiceArea +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/service-area-server/service-area-delegate.cpp b/src/app/clusters/service-area-server/service-area-delegate.cpp new file mode 100644 index 00000000000000..1be7d257336c94 --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-delegate.cpp @@ -0,0 +1,90 @@ +#include "service-area-delegate.h" +#include "service-area-server.h" + +using namespace chip::app::Clusters::ServiceArea; + +bool Delegate::GetSupportedLocationById(uint32_t aLocationId, uint32_t & listIndex, LocationStructureWrapper & aSupportedLocation) +{ + listIndex = 0; + + // simple linear iteration to find the location with the desired locationID. + while (GetSupportedLocationByIndex(listIndex, aSupportedLocation)) + { + if (aSupportedLocation.locationID == aLocationId) + { + return true; + } + + ++listIndex; + } + + return false; +} + +void Delegate::HandleSupportedLocationsUpdated() +{ + mInstance->ClearSelectedLocations(); + mInstance->SetCurrentLocation(DataModel::NullNullable); + mInstance->ClearProgress(); +} + +bool Delegate::GetSupportedMapById(uint8_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap) +{ + listIndex = 0; + + while (GetSupportedMapByIndex(listIndex, aSupportedMap)) + { + if (aSupportedMap.mapID == aMapId) + { + return true; + } + + ++listIndex; + } + + return false; +} + +bool Delegate::IsSelectedLocation(uint32_t aLocationId) +{ + uint32_t listIndex = 0; + uint32_t selectedLocation; + + while (GetSelectedLocationByIndex(listIndex, selectedLocation)) + { + if (selectedLocation == aLocationId) + { + return true; + } + + ++listIndex; + } + + return false; +} + +bool Delegate::GetProgressElementById(uint32_t aLocationId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement) +{ + listIndex = 0; + + // simple linear iteration to find the progress element with the desired locationID. + while (GetProgressElementByIndex(listIndex, aProgressElement)) + { + if (aProgressElement.locationID == aLocationId) + { + return true; + } + + ++listIndex; + } + + return false; +} + +bool Delegate::IsProgressElement(uint32_t aLocationId) +{ + uint32_t index; + Structs::ProgressStruct::Type progressElement; + + return GetProgressElementById(aLocationId, index, progressElement); +} diff --git a/src/app/clusters/service-area-server/service-area-delegate.h b/src/app/clusters/service-area-server/service-area-delegate.h new file mode 100644 index 00000000000000..baf50d071b3404 --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-delegate.h @@ -0,0 +1,384 @@ +/* + * + * 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 "service-area-cluster-objects.h" + +namespace chip { +namespace app { +namespace Clusters { +namespace ServiceArea { + +class Instance; + +// ***************************************************************************** +// cluster constraints + +constexpr size_t kMaxNumSupportedLocations = 255; +constexpr size_t kMaxNumSupportedMaps = 255; +constexpr size_t kMaxNumSelectedLocations = 255; +constexpr size_t kMaxNumProgressElements = 255; + +constexpr size_t kMaxSizeStatusText = 256; + +/** + * ServiceArea::Delegate Defines methods for implementing application-specific + * logic for the Service Area Cluster. + */ +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + /** + * Stop this class objects from being copied. + */ + Delegate(const Delegate &) = delete; + Delegate & operator=(const Delegate &) = delete; + + /** + * @brief This method will be called during the ServiceArea server initialization after the Instance information has been + * validated and the Instance has been registered. This can be used to initialise app logic. + */ + virtual CHIP_ERROR Init() { return CHIP_NO_ERROR; }; + + //************************************************************************* + // Command handling support + + /** + * @brief Can the selected locations be set by the client in the current operating mode? + * @param[out] statusText text describing why selected locations cannot be set (if return is false). + * @return true if the current device state allows selected locations to be set by user. + * + * @note The statusText field SHOULD indicate why the request is not allowed, given the current mode + * of the device, which may involve other clusters. + */ + virtual bool IsSetSelectedLocationsAllowed(MutableCharSpan statusText) = 0; + + /** + * Given a set of locations to be set to the SelectedLocations attribute, this method should check that + * the set of locations as a whole is valid and reachable by the device. + * If the set of locations is invalid, the locationStatus should be set to InvalidSet and + * the statusText SHALL include a vendor-defined error description. + * + * The caller of this method will ensure that there are no duplicates is the list + * and that all the locations in the set are valid supported locations. + * + * @param[in] req List of new selected locations. + * @param[out] locationStatus Success if all checks pass, error code if failure. + * @param[out] statusText text describing failure (see description above), size kMaxSizeStatusText. + * @return true if success. + * + * @note If the SelectLocations command is allowed when the device is operating and the selected locations change to none, the + * device must stop. + */ + virtual bool IsValidSelectLocationsSet(const Commands::SelectLocations::DecodableType & req, + SelectLocationsStatus & locationStatus, MutableCharSpan statusText) = 0; + + /** + * @brief The server instance ensures that the SelectedLocations and CurrentLocation attributes are not null before + * calling this method. + * @param[out] skipStatusText text describing why current location cannot be skipped. + * @return true if command is successful, false if the received skip request cannot be handled due to the current mode of the + * device. + * + * @note skipStatusText must be filled out by the function on failure. + * + * @note If the device successfully accepts the request and the ListOrder feature is set to 1: + * The server SHALL stop operating at the current location. + * The server SHALL attempt to operate at the remaining locations on the SelectedLocations attribute list, starting with + * the next entry. If the end of the SelectedLocations attribute list is reached, the server SHALL stop operating. + * + * @note If the device successfully accepts the request and the ListOrder feature is set to 0: + * The server SHALL stop operating at the current location. + * The server SHALL attempt to operate at the locations on the SelectedLocations attribute list where operating has not + * been completed, using a vendor defined order. If the server has completed operating at all locations on the SelectedLocations + * attribute list, the server SHALL stop operating. + * + * @note If the Status field is set to InvalidLocationList, the StatusText field SHALL be an empty string. + * If the Status field is not set to Success, or InvalidLocationList, the StatusText field SHALL include a vendor defined + * error description which can be used to explain the error to the user. For example, if the Status field is set to + * InvalidInMode, the StatusText field SHOULD indicate why the request is not allowed, given the current mode of the device, + * which may involve other clusters. + */ + virtual bool HandleSkipCurrentLocation(MutableCharSpan skipStatusText) + { + // device support of this command is optional + CopyCharSpanToMutableCharSpan("Skip Current Location command not supported by device"_span, skipStatusText); + return false; + } + + //************************************************************************* + // Supported Locations accessors + + /** + * @return true if the current device state allows the SupportedLocations attribute to be updated. + * + * @note The SupportedLocations attribute list changes (adding or deleting entries, + * changing their MapID fields, changing the LocationID fields, or nulling the entire list) + * SHOULD NOT be allowed while the device is operating, to reduce the impact on the clients, + * and the potential confusion for the users. + * + * @note The device implementation MAY allow supported location changes while operating if the device + * repopulates the SupportedMaps, SupportedLocations, CurrentLocation, and Progress attributes with + * data matching the constraints listed in the requirements for each attribute. + */ + virtual bool IsSupportedLocationsChangeAllowed() = 0; + + virtual uint32_t GetNumberOfSupportedLocations() = 0; + + /** + * @brief Get a supported location using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aSupportedLocation copy of the location contents, if found. + * @return true if location found, false otherwise. + */ + virtual bool GetSupportedLocationByIndex(uint32_t listIndex, LocationStructureWrapper & aSupportedLocation) = 0; + + /** + * @brief Get a supported location that matches a locationID. + * @param[in] aLocationId the locationID to search for. + * @param[out] listIndex the location's index in the list, if found. + * @param[out] aSupportedLocation copy of the location contents, if found. + * @return true if location found, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool GetSupportedLocationById(uint32_t aLocationId, uint32_t & listIndex, + LocationStructureWrapper & aSupportedLocation); + + /** + * This method is called by the server instance to add a new location to the list. + * The server instance will ensure that the newLocation is a valid, unique location. + * @param [in] newLocation new location to add. + * @param [out] listIndex filled with the list index for the new location, if successful. + * @return true if successful, false otherwise. + + * @note this function SHOULD double check that the added location won't exceed the maximum list size. + */ + virtual bool AddSupportedLocation(const LocationStructureWrapper & newLocation, uint32_t & listIndex) = 0; + + /** + * This method is called by the server instance to modify an existing location in the list. + * The server instance will ensure that the modifiedLocation is a valid, unique location. + * @param[in] listIndex The index of the location being modified. + * @param[in] modifiedLocation A location with the modified contents. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that newLocation's locationID matches the object at listIndex. + */ + virtual bool ModifySupportedLocation(uint32_t listIndex, const LocationStructureWrapper & modifiedLocation) = 0; + + /** + * @return true if supported locations was not already null, false otherwise. + */ + virtual bool ClearSupportedLocations() = 0; + + /** + * @brief Ensure that when the Supported locations is modified, the required restrictions for the SelectedLocations, + * CurrentLocation, and Progress attributes are maintained. + * + * This method will be called by the SDK whenever the adherence to the restrictions for these attributes cannot be guaranteed. + * For example, if there are deletions in the SupportedMops or SupportedLocations attributes, or if there are changes to their + * IDs. This method will no be called if the changes made to the SupportedMops or SupportedLocations attributes, ensure that the + * restrictions are adhered. For example, if there are additions or the modifications do not involve changing IDs in the + * SupportedMops or SupportedLocations attributes. + * + * The default implementation will set the SelectedLocations, CurrentLocation, and Progress attributes to null. + * + * The user is free the redefine this method as their device may have more information on what has changed and may be able to + * maintain the restrictions on these attributes by selectively editing them. + */ + virtual void HandleSupportedLocationsUpdated(); + + //************************************************************************* + // Supported Maps accessors + + /** + * @return true if the current device state allows the SupportedMaps attribute to be updated. + * + * @note The SupportedMaps attribute list changes (adding or deleting entries, + * changing their MapID fields, or nulling the entire list) + * SHOULD NOT be allowed while the device is operating, to reduce the impact on the clients, + * and the potential confusion for the users. + * + * @note The device implementation MAY allow supported maps changes while operating if the device + * repopulates the SupportedLocations, CurrentLocation, and Progress attributes with + * data matching the constraints listed in the requirements for each attribute. + */ + virtual bool IsSupportedMapChangeAllowed() = 0; + + virtual uint32_t GetNumberOfSupportedMaps() = 0; + + /** + * @brief Get a supported map using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aSupportedMap copy of the map contents, if found. + * @return true if a supported map is found, false otherwise. + */ + virtual bool GetSupportedMapByIndex(uint32_t listIndex, MapStructureWrapper & aSupportedMap) = 0; + + /** + * @brief Get a supported map that matches a mapID. + * @param[in] aMapId the mapID to search for. + * @param[out] listIndex the map's index in the list, if found. + * @param[out] aSupportedMap copy of the location contents, if found. + * @return true if a supported map is found, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool GetSupportedMapById(uint8_t aMapId, uint32_t & listIndex, MapStructureWrapper & aSupportedMap); + + /** + * This method is called by the server instance to add a new map to the list. + * The server instance will ensure that the newMap is a valid, unique map. + * @param[in] newMap The new map to add. + * @param[out] listIndex filled with the list index of the new map, if successful. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that the added map won't exceed the maximum list size + */ + virtual bool AddSupportedMap(const MapStructureWrapper & newMap, uint32_t & listIndex) = 0; + + /** + * This method is called by the server instance to modify an existing map in the list. + * The server instance will ensure that the modifiedMap is a valid, unique map. + * @param[in] listIndexThe index of the map being modified. + * @param[in] modifiedMapA map with the modified contents. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that modifiedMap's mapID matches the object at listIndex. + */ + virtual bool ModifySupportedMap(uint32_t listIndex, const MapStructureWrapper & modifiedMap) = 0; + + /** + * @return true if supported maps was not already null, false otherwise. + */ + virtual bool ClearSupportedMaps() = 0; + + //************************************************************************* + // Selected Locations accessors + + virtual uint32_t GetNumberOfSelectedLocations() = 0; + + /** + * @brief Get a selected location using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] selectedLocation the selected location value, if found. + * @return true if a selected location is found, false otherwise. + */ + virtual bool GetSelectedLocationByIndex(uint32_t listIndex, uint32_t & selectedLocation) = 0; + + /** + * @return true if the aLocationId locationID is found in the SelectedLocations list, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool IsSelectedLocation(uint32_t aLocationId); + + /** + * This method is called by the server instance to add a new selected location to the list. + * The server instance will ensure that the aLocationId references a SUPPORTED location, and is unique within selected + * locations. + * @param[in] aLocationId The new locationID to add. + * @param[out] listIndex filled with the list index of the new location, if successful. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that the added location won't exceed the maximum list size. + */ + virtual bool AddSelectedLocation(uint32_t aLocationId, uint32_t & listIndex) = 0; + + /** + * @return true if selected locations was not already null, false otherwise. + */ + virtual bool ClearSelectedLocations() = 0; + + //************************************************************************* + // Progress accessors + + virtual uint32_t GetNumberOfProgressElements() = 0; + + /** + * @brief Get a progress element using the position in the list. + * @param[in] listIndex the position in the list. + * @param[out] aProgressElement copy of the progress element contents, if found. + * @return true if a progress element is found, false otherwise. + */ + virtual bool GetProgressElementByIndex(uint32_t listIndex, Structs::ProgressStruct::Type & aProgressElement) = 0; + + /** + * @brief Get a progress element that matches a locationID. + * @param[in] aLocationId the locationID to search for. + * @param[out] listIndex the location's index in the list, if found. + * @param[out] aProgressElement copy of the progress element contents, if found. + * @return true if a progress element is found, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool GetProgressElementById(uint32_t aLocationId, uint32_t & listIndex, + Structs::ProgressStruct::Type & aProgressElement); + + /** + * @brief Is the progress element in the progress list? + * @param[in] aLocationId location id of the progress element. + * @return true if the progress element identified by Id is in the progress list. + */ + virtual bool IsProgressElement(uint32_t aLocationId); + + /** + * This method is called by the server instance to add a new progress element to the list. + * The server instance will ensure that the newProgressElement is a valid, unique progress element. + * @param[in] newProgressElement The new element to add. + * @param[out] listIndex is filled with the list index for the new element, if successful. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that the added element won't exceed the maximum list size. + */ + virtual bool AddProgressElement(const Structs::ProgressStruct::Type & newProgressElement, uint32_t & listIndex) = 0; + + /** + * This method is called by the server instance to modify an existing progress element in the list. + * The server instance will ensure that the modifiedProgressElement is a valid and unique progress element. + * @param[in] listIndex The list index of the progress element being modified. + * @param[in] modifiedProgressElement modified element's contents. + * @return true if successful, false otherwise. + * + * @note this function SHOULD double check that modifiedProgressElement's locationID matches the object at listIndex + */ + virtual bool ModifyProgressElement(uint32_t listIndex, const Structs::ProgressStruct::Type & modifiedProgressElement) = 0; + + /** + * @return true if progress list was not already null, false otherwise. + */ + virtual bool ClearProgress() = 0; + + Instance * GetInstance() { return mInstance; } + + void SetInstance(Instance * aInstance) { mInstance = aInstance; } + +private: + Instance * mInstance = nullptr; +}; + +} // namespace ServiceArea +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/service-area-server/service-area-server.cpp b/src/app/clusters/service-area-server/service-area-server.cpp new file mode 100644 index 00000000000000..97775fb24f67c0 --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-server.cpp @@ -0,0 +1,1131 @@ +/** + * + * 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. + * + */ + +#include "service-area-server.h" +#include "service-area-delegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using Status = chip::Protocols::InteractionModel::Status; + +namespace chip { +namespace app { +namespace Clusters { +namespace ServiceArea { + +// **************************************************************************** +// Service Area Server Instance + +Instance::Instance(Delegate * aDelegate, EndpointId aEndpointId, BitMask aFeature) : + AttributeAccessInterface(MakeOptional(aEndpointId), Id), CommandHandlerInterface(MakeOptional(aEndpointId), Id), + mDelegate(aDelegate), mEndpointId(aEndpointId), mClusterId(Id), mFeature(aFeature) +{ + ChipLogProgress(Zcl, "Service Area: Instance constructor"); + mDelegate->SetInstance(this); +} + +Instance::~Instance() +{ + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); + unregisterAttributeAccessOverride(this); +} + +CHIP_ERROR Instance::Init() +{ + ChipLogProgress(Zcl, "Service Area: INIT"); + + // Check if the cluster has been selected in zap + VerifyOrReturnError(emberAfContainsServer(mEndpointId, Id), CHIP_ERROR_INVALID_ARGUMENT, + ChipLogError(Zcl, "Service Area: The cluster with Id %lu was not enabled in zap.", long(Id))); + + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); + + VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); + + return mDelegate->Init(); +} + +//************************************************************************* +// core functions + +CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + ChipLogDetail(Zcl, "Service Area: Reading attribute with ID " ChipLogFormatMEI, ChipLogValueMEI(aPath.mAttributeId)); + + switch (aPath.mAttributeId) + { + + case Attributes::SupportedLocations::Id: + return ReadSupportedLocations(aEncoder); + + case Attributes::SupportedMaps::Id: + return ReadSupportedMaps(aEncoder); + + case Attributes::SelectedLocations::Id: + return ReadSelectedLocations(aEncoder); + + case Attributes::CurrentLocation::Id: + return aEncoder.Encode(GetCurrentLocation()); + + case Attributes::EstimatedEndTime::Id: + return aEncoder.Encode(GetEstimatedEndTime()); + + case Attributes::Progress::Id: + return ReadProgress(aEncoder); + + case Attributes::FeatureMap::Id: + return aEncoder.Encode(mFeature); + + default: + ChipLogProgress(Zcl, "Service Area: Unsupported attribute with ID " ChipLogFormatMEI, ChipLogValueMEI(aPath.mAttributeId)); + } + + return CHIP_NO_ERROR; +} + +void Instance::InvokeCommand(HandlerContext & handlerContext) +{ + switch (handlerContext.mRequestPath.mCommandId) + { + case Commands::SelectLocations::Id: + return CommandHandlerInterface::HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & req) { HandleSelectLocationsCmd(ctx, req); }); + + case Commands::SkipCurrentLocation::Id: + return CommandHandlerInterface::HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & req) { HandleSkipCurrentLocationCmd(ctx); }); + } +} + +//************************************************************************* +// attribute readers + +CHIP_ERROR Instance::ReadSupportedLocations(AttributeValueEncoder & aEncoder) +{ + if (mDelegate->GetNumberOfSupportedLocations() == 0) + { + return aEncoder.EncodeNull(); + } + + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + uint8_t locationIndex = 0; + LocationStructureWrapper supportedLocation; + + while (mDelegate->GetSupportedLocationByIndex(locationIndex++, supportedLocation)) + { + ReturnErrorOnFailure(encoder.Encode(supportedLocation)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR Instance::ReadSupportedMaps(AttributeValueEncoder & aEncoder) +{ + if (mDelegate->GetNumberOfSupportedMaps() == 0) + { + return aEncoder.EncodeNull(); + } + + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + uint32_t mapIndex = 0; + MapStructureWrapper supportedMap; + + while (mDelegate->GetSupportedMapByIndex(mapIndex++, supportedMap)) + { + ReturnErrorOnFailure(encoder.Encode(supportedMap)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR Instance::ReadSelectedLocations(AttributeValueEncoder & aEncoder) +{ + if (mDelegate->GetNumberOfSelectedLocations() == 0) + { + return aEncoder.EncodeNull(); + } + + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + uint32_t locationIndex = 0; + uint32_t selectedLocation; + + while (mDelegate->GetSelectedLocationByIndex(locationIndex++, selectedLocation)) + { + ReturnErrorOnFailure(encoder.Encode(selectedLocation)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR Instance::ReadProgress(AttributeValueEncoder & aEncoder) +{ + if (mDelegate->GetNumberOfProgressElements() == 0) + { + return aEncoder.EncodeNull(); + } + + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + uint32_t locationIndex = 0; + Structs::ProgressStruct::Type progressElement; + + while (mDelegate->GetProgressElementByIndex(locationIndex++, progressElement)) + { + ReturnErrorOnFailure(encoder.Encode(progressElement)); + } + return CHIP_NO_ERROR; + }); +} + +//************************************************************************* +// command handlers + +void Instance::HandleSelectLocationsCmd(HandlerContext & ctx, const Commands::SelectLocations::DecodableType & req) +{ + ChipLogDetail(Zcl, "Service Area: HandleSelectLocationsCmd"); + + // On receipt of this command the device SHALL respond with a SelectLocationsResponse command. + auto exitResponse = [ctx](SelectLocationsStatus status, CharSpan statusText) { + Commands::SelectLocationsResponse::Type response{ + .status = status, + .statusText = Optional(statusText), + }; + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + }; + + size_t numberOfLocations = 0; + // Get the number of Selected Locations in the command parameter and check that it is valid. + if (!req.newLocations.IsNull()) + { + if (CHIP_NO_ERROR != req.newLocations.Value().ComputeSize(&numberOfLocations)) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + + // If the device determines that it can't operate at all locations from the list, + // the SelectLocationsResponse command's Status field SHALL indicate InvalidSet. + if (numberOfLocations > kMaxNumSelectedLocations) + { + exitResponse(SelectLocationsStatus::kInvalidSet, "invalid number of locations"_span); + return; + } + } + + // if number of selected locations in parameter matches number in attribute - the locations *might* be the same + bool matchesCurrentSelectedLocations = (numberOfLocations == mDelegate->GetNumberOfSelectedLocations()); + + if (!req.newLocations.IsNull()) + { + // do as much parameter validation as we can + { + uint32_t ignoredIndex = 0; + uint32_t oldSelectedLocation; + uint32_t i = 0; + auto iLocationIter = req.newLocations.Value().begin(); + while (iLocationIter.Next()) + { + uint32_t aSelectedLocation = iLocationIter.GetValue(); + + // each item in this list SHALL match the LocationID field of an entry on the SupportedLocations attribute's list + // If the Status field is set to UnsupportedLocation, the StatusText field SHALL be an empty string. + if (!IsSupportedLocation(aSelectedLocation)) + { + exitResponse(SelectLocationsStatus::kUnsupportedLocation, ""_span); + return; + } + + // Checking for duplicate locations. + uint32_t j = 0; + auto jLocationIter = req.newLocations.Value().begin(); + while (j < i) + { + jLocationIter + .Next(); // Since j < i and i is valid, we can safely call Next() without checking the return value. + if (jLocationIter.GetValue() == aSelectedLocation) + { + exitResponse(SelectLocationsStatus::kDuplicatedLocations, ""_span); + return; + } + j += 1; + } + + // check to see if parameter list and attribute still match + if (matchesCurrentSelectedLocations) + { + if (!mDelegate->GetSelectedLocationByIndex(ignoredIndex, oldSelectedLocation) || + (aSelectedLocation != oldSelectedLocation)) + { + matchesCurrentSelectedLocations = false; + } + } + + i += 1; + } + + // after iterating with Next through DecodableType - check for failure + if (CHIP_NO_ERROR != iLocationIter.GetStatus()) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + } + } + + // If the NewLocations field is the same as the value of the SelectedLocations attribute + // the SelectLocationsResponse command SHALL have the Status field set to Success and + // the StatusText field MAY be supplied with a human-readable string or include an empty string. + if (matchesCurrentSelectedLocations) + { + exitResponse(SelectLocationsStatus::kSuccess, ""_span); + return; + } + + char delegateStatusBuffer[kMaxSizeStatusText]; + MutableCharSpan delegateStatusText(delegateStatusBuffer); + + // If the current state of the device doesn't allow for the locations to be selected, + // the SelectLocationsResponse command SHALL have the Status field set to InvalidInMode. + // if the Status field is set to InvalidInMode, the StatusText field SHOULD indicate why the request is not allowed, + // given the current mode of the device, which may involve other clusters. + // (note - locationStatusText to be filled out by delegated function for if return value is false) + if (!mDelegate->IsSetSelectedLocationsAllowed(delegateStatusText)) + { + exitResponse(SelectLocationsStatus::kInvalidInMode, delegateStatusText); + return; + } + + // Reset in case the delegate accidentally modified this string. + delegateStatusText = MutableCharSpan(delegateStatusBuffer); + + // ask the device to handle SelectLocations Command + // (note - locationStatusText to be filled out by delegated function for kInvalidInMode and InvalidSet) + auto locationStatus = SelectLocationsStatus::kSuccess; + if (!mDelegate->IsValidSelectLocationsSet(req, locationStatus, delegateStatusText)) + { + exitResponse(locationStatus, delegateStatusText); + return; + } + + { + // If the device successfully accepts the request, the server will attempt to operate at the location(s) + // indicated by the entries of the NewLocation field, when requested to operate, + // the SelectLocationsResponse command SHALL have the Status field set to Success, + // and the SelectedLocations attribute SHALL be set to the value of the NewLocations field. + mDelegate->ClearSelectedLocations(); + + if (!req.newLocations.IsNull()) + { + auto locationIter = req.newLocations.Value().begin(); + uint32_t ignored; + while (locationIter.Next()) + { + mDelegate->AddSelectedLocation(locationIter.GetValue(), ignored); + } + } + + NotifySelectedLocationsChanged(); + } + + exitResponse(SelectLocationsStatus::kSuccess, ""_span); +} + +void Instance::HandleSkipCurrentLocationCmd(HandlerContext & ctx) +{ + ChipLogDetail(Zcl, "Service Area: HandleSkipCurrentLocation"); + + // On receipt of this command the device SHALL respond with a SkipCurrentLocationResponse command. + auto exitResponse = [ctx](SkipCurrentLocationStatus status, CharSpan statusText) { + Commands::SkipCurrentLocationResponse::Type response{ + .status = status, + .statusText = Optional(statusText), + }; + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + }; + + // If the SelectedLocations attribute is null, the response status should be set to InvalidLocationList. + // If the Status field is set to InvalidLocationList, the StatusText field SHALL be an empty string. + if (mDelegate->GetNumberOfSelectedLocations() == 0) + { + ChipLogError(Zcl, "Selected Locations attribute is null"); + exitResponse(SkipCurrentLocationStatus::kInvalidLocationList, ""_span); + return; + } + + // If the CurrentLocation attribute is null, the status should be set to InvalidInMode. + // If the Status field is not set to Success, or InvalidLocationList, the StatusText field SHALL include a vendor defined error + // description. + if (mCurrentLocation.IsNull()) + { + exitResponse(SkipCurrentLocationStatus::kInvalidInMode, "Current Location attribute is null"_span); + return; + } + + // have the device attempt to skip + // If the Status field is not set to Success, or InvalidLocationList, the StatusText field SHALL include a vendor defined error + // description. InvalidInMode | The received request cannot be handled due to the current mode of the device. (skipStatusText to + // be filled out by delegated function on failure.) + char skipStatusBuffer[kMaxSizeStatusText]; + MutableCharSpan skipStatusText(skipStatusBuffer); + + if (!mDelegate->HandleSkipCurrentLocation(skipStatusText)) + { + exitResponse(SkipCurrentLocationStatus::kInvalidInMode, skipStatusText); + return; + } +} + +//************************************************************************* +// attribute notifications + +void Instance::NotifySupportedLocationsChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::SupportedLocations::Id); +} + +void Instance::NotifySupportedMapsChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::SupportedMaps::Id); +} + +void Instance::NotifySelectedLocationsChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::SelectedLocations::Id); +} + +void Instance::NotifyCurrentLocationChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::CurrentLocation::Id); +} + +void Instance::NotifyEstimatedEndTimeChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::EstimatedEndTime::Id); +} + +void Instance::NotifyProgressChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::Progress::Id); +} + +// **************************************************************************** +// Supported Locations manipulators + +bool Instance::IsSupportedLocation(uint32_t aLocationId) +{ + uint32_t ignoredIndex; + LocationStructureWrapper ignoredLocation; + + return mDelegate->GetSupportedLocationById(aLocationId, ignoredIndex, ignoredLocation); +} + +bool Instance::IsValidSupportedLocation(const LocationStructureWrapper & aLocation) +{ + // If the HomeLocationInfo field is null, the LandmarkTag field SHALL NOT be null. + // If the LandmarkTag field is null, the HomeLocationInfo field SHALL NOT be null. + if (aLocation.locationInfo.locationInfo.IsNull() && aLocation.locationInfo.landmarkTag.IsNull()) + { + ChipLogDetail(Zcl, "IsValidAsSupportedLocation %u - must have locationInfo and/or LandmarkTag", aLocation.locationID); + return false; + } + + // If HomeLocationInfo is not null, and its LocationName field is an empty string, at least one of the following SHALL NOT + // be null: HomeLocationInfo's FloorNumber field, HomeLocationInfo's AreaType field, the LandmarkTag field + if (!aLocation.locationInfo.locationInfo.IsNull()) + { + if (aLocation.locationInfo.locationInfo.Value().locationName.empty() && + aLocation.locationInfo.locationInfo.Value().floorNumber.IsNull() && + aLocation.locationInfo.locationInfo.Value().areaType.IsNull() && aLocation.locationInfo.landmarkTag.IsNull()) + { + ChipLogDetail( + Zcl, "IsValidAsSupportedLocation %u - LocationName is empty string, FloorNumber, AreaType, LandmarkTag are null", + aLocation.locationID); + return false; + } + } + + // If the LandmarkTag field is null, the PositionTag field SHALL be null. + if (aLocation.locationInfo.landmarkTag.IsNull() && !aLocation.locationInfo.positionTag.IsNull()) + { + ChipLogDetail(Zcl, "IsValidAsSupportedLocation %u - PositionTag with no LandmarkTag", aLocation.locationID); + return false; + } + + if (mDelegate->GetNumberOfSupportedMaps() == 0) + { + // If the SupportedMaps attribute is null, mapid SHALL be null. + if (!aLocation.mapID.IsNull()) + { + ChipLogDetail(Zcl, "IsValidSupportedLocation %u - map Id %u is not in empty supported map list", aLocation.locationID, + aLocation.mapID.Value()); + return false; + } + } + else + { + // If the SupportedMaps attribute is not null, mapID SHALL be the ID of an entry from the SupportedMaps attribute. + if (!IsSupportedMap(aLocation.mapID.Value())) + { + ChipLogError(Zcl, "IsValidSupportedLocation %u - map Id %u is not in supported map list", aLocation.locationID, + aLocation.mapID.Value()); + return false; + } + } + + return true; +} + +bool Instance::IsUniqueSupportedLocation(const LocationStructureWrapper & aLocation, bool ignoreLocationId) +{ + BitMask config; + + if (ignoreLocationId) + { + config.Set(LocationStructureWrapper::IsEqualConfig::kIgnoreLocationId); + } + + // If the SupportedMaps attribute is not null, each entry in this list SHALL have a unique value for the combination of the + // MapID and LocationInfo fields. If the SupportedMaps attribute is null, each entry in this list SHALL have a unique value for + // the LocationInfo field. + if (mDelegate->GetNumberOfSupportedMaps() == 0) + { + config.Set(LocationStructureWrapper::IsEqualConfig::kIgnoreMapId); + } + + uint8_t locationIndex = 0; + LocationStructureWrapper entry; + while (mDelegate->GetSupportedLocationByIndex(locationIndex++, entry)) + { + if (aLocation.IsEqual(entry, config)) + { + return false; + } + } + + return true; +} + +bool Instance::ReportEstimatedEndTimeChange(const DataModel::Nullable & aEstimatedEndTime) +{ + if (mEstimatedEndTime == aEstimatedEndTime) + { + return false; + } + + // The value of this attribute SHALL only be reported in the following cases: + // - when it changes from null. + if (mEstimatedEndTime.IsNull()) + { + return true; + } + + // - when it changes from 0 + if (mEstimatedEndTime.Value() == 0) + { + return true; + } + + if (aEstimatedEndTime.IsNull()) + { + return false; + } + + // From this point we know that mEstimatedEndTime and aEstimatedEndTime are not null and not the same. + + // - when it changes to 0 + if (aEstimatedEndTime.Value() == 0) + { + return true; + } + + // - when it decreases + return (aEstimatedEndTime.Value() < mEstimatedEndTime.Value()); +} + +bool Instance::AddSupportedLocation(uint32_t aLocationId, const DataModel::Nullable & aMapId, + const CharSpan & aLocationName, const DataModel::Nullable & aFloorNumber, + const DataModel::Nullable & aAreaType, + const DataModel::Nullable & aLandmarkTag, + const DataModel::Nullable & aPositionTag, + const DataModel::Nullable & aSurfaceTag) +{ + // Create location object for validation. + LocationStructureWrapper aNewLocation(aLocationId, aMapId, aLocationName, aFloorNumber, aAreaType, aLandmarkTag, aPositionTag, + aSurfaceTag); + + // Does device mode allow this attribute to be updated? + if (!mDelegate->IsSupportedLocationsChangeAllowed()) + { + return false; + } + + // Check there is space for the entry. + if (mDelegate->GetNumberOfSupportedLocations() >= kMaxNumSupportedLocations) + { + ChipLogError(Zcl, "AddSupportedLocation %u - too many entries", aLocationId); + return false; + } + + // Verify cluster requirements concerning valid fields and field relationships. + if (!IsValidSupportedLocation(aNewLocation)) + { + ChipLogError(Zcl, "AddSupportedLocation %u - not a valid location object", aNewLocation.locationID); + return false; + } + + // Each entry in Supported Locations SHALL have a unique value for the ID field. + // If the SupportedMaps attribute is not null, each entry in this list SHALL have a unique value for the combination of the + // MapID and LocationInfo fields. If the SupportedMaps attribute is null, each entry in this list SHALL have a unique value for + // the LocationInfo field. + if (!IsUniqueSupportedLocation(aNewLocation, false)) + { + ChipLogError(Zcl, "AddSupportedLocation %u - not a unique location object", aNewLocation.locationID); + return false; + } + + // Add the SupportedLocation to the SupportedLocations attribute. + uint32_t ignoredIndex; + if (!mDelegate->AddSupportedLocation(aNewLocation, ignoredIndex)) + { + return false; + } + + NotifySupportedLocationsChanged(); + return true; +} + +bool Instance::ModifySupportedLocation(uint32_t aLocationId, const DataModel::Nullable & aMapId, + const CharSpan & aLocationName, const DataModel::Nullable & aFloorNumber, + const DataModel::Nullable & aAreaType, + const DataModel::Nullable & aLandmarkTag, + const DataModel::Nullable & aPositionTag, + const DataModel::Nullable & aSurfaceTag) +{ + bool mapIDChanged = false; + uint32_t listIndex; + + // get existing supported location to modify + LocationStructureWrapper supportedLocation; + if (!mDelegate->GetSupportedLocationById(aLocationId, listIndex, supportedLocation)) + { + ChipLogError(Zcl, "ModifySupportedLocation %u - not a supported locationID", aLocationId); + return false; + } + + { + // check for mapID change + if ((aMapId.IsNull() != supportedLocation.mapID.IsNull()) || + (!aMapId.IsNull() && !supportedLocation.mapID.IsNull() && (aMapId.Value() != supportedLocation.mapID.Value()))) + { + // does device mode allow this attribute to be updated? + if (!mDelegate->IsSupportedLocationsChangeAllowed()) + { + return false; + } + mapIDChanged = true; + } + + // create new location object for validation + LocationStructureWrapper aNewLocation(aLocationId, aMapId, aLocationName, aFloorNumber, aAreaType, aLandmarkTag, + aPositionTag, aSurfaceTag); + + // verify cluster requirements concerning valid fields and field relationships + if (!IsValidSupportedLocation(aNewLocation)) + { + ChipLogError(Zcl, "ModifySupportedLocation %u - not a valid location object", aNewLocation.locationID); + return false; + } + + // Updated location description must not match another existing location description. + // We ignore comparing the location ID as one of the locations will match this one. + if (!IsUniqueSupportedLocation(aNewLocation, true)) + { + ChipLogError(Zcl, "ModifySupportedLocation %u - not a unique location object", aNewLocation.locationID); + return false; + } + + // Replace the supported location with the modified location. + if (!mDelegate->ModifySupportedLocation(listIndex, aNewLocation)) + { + return false; + } + } + + if (mapIDChanged) + { + mDelegate->HandleSupportedLocationsUpdated(); + } + + NotifySupportedLocationsChanged(); + return true; +} + +bool Instance::ClearSupportedLocations() +{ + // does device mode allow this attribute to be updated? + if (!mDelegate->IsSupportedLocationsChangeAllowed()) + { + return false; + } + + if (mDelegate->ClearSupportedLocations()) + { + mDelegate->HandleSupportedLocationsUpdated(); + NotifySupportedLocationsChanged(); + return true; + } + + return false; +} + +//************************************************************************* +// Supported Maps manipulators + +bool Instance::IsSupportedMap(uint8_t aMapId) +{ + uint32_t ignoredIndex; + MapStructureWrapper ignoredMap; + + return mDelegate->GetSupportedMapById(aMapId, ignoredIndex, ignoredMap); +} + +bool Instance::AddSupportedMap(uint8_t aMapId, const CharSpan & aMapName) +{ + // check max# of list entries + if (mDelegate->GetNumberOfSupportedMaps() >= kMaxNumSupportedMaps) + { + ChipLogError(Zcl, "AddSupportedMap %u - maximum number of entries", aMapId); + return false; + } + + // Map name SHALL include readable text that describes the map name (cannot be empty string). + if (aMapName.empty()) + { + ChipLogError(Zcl, "AddSupportedMap %u - Name must not be empty string", aMapId); + return false; + } + + // Each entry in this list SHALL have a unique value for the Name field. + uint8_t mapIndex = 0; + MapStructureWrapper entry; + + while (mDelegate->GetSupportedMapByIndex(mapIndex++, entry)) + { + // the name cannot be the same as an existing map + if (entry.IsNameEqual(aMapName)) + { + ChipLogError(Zcl, "AddSupportedMap %u - A map already exists with same name '%.*s'", aMapId, + static_cast(entry.GetName().size()), entry.GetName().data()); + return false; + } + + // Each entry in this list SHALL have a unique value for the MapID field. + if (aMapId == entry.mapID) + { + ChipLogError(Zcl, "AddSupportedMap - non-unique Id %u", aMapId); + return false; + } + } + + { + // add to supported maps attribute + MapStructureWrapper newMap(aMapId, aMapName); + uint32_t ignoredIndex; + if (!mDelegate->AddSupportedMap(newMap, ignoredIndex)) + { + return false; + } + } + + // map successfully added + NotifySupportedMapsChanged(); + return true; +} + +bool Instance::RenameSupportedMap(uint8_t aMapId, const CharSpan & newMapName) +{ + uint32_t modifiedIndex; + MapStructureWrapper modifiedMap; + + // get existing entry + if (!mDelegate->GetSupportedMapById(aMapId, modifiedIndex, modifiedMap)) + { + ChipLogError(Zcl, "RenameSupportedMap Id %u - map does not exist", aMapId); + return false; + } + + // Map name SHALL include readable text that describes the map's name. It cannot be empty string. + if (newMapName.empty()) + { + ChipLogError(Zcl, "RenameSupportedMap %u - Name must not be empty string", aMapId); + return false; + } + + // update the local copy of the map + modifiedMap.Set(modifiedMap.mapID, newMapName); + + // Each entry in this list SHALL have a unique value for the Name field. + uint32_t loopIndex = 0; + MapStructureWrapper entry; + + while (mDelegate->GetSupportedMapByIndex(loopIndex, entry)) + { + if (modifiedIndex == loopIndex) + { + continue; // don't check local modified map against its own list entry + } + + if (entry.IsNameEqual(newMapName)) + { + ChipLogError(Zcl, "RenameSupportedMap %u - map already exists with same name '%.*s'", aMapId, + static_cast(entry.GetName().size()), entry.GetName().data()); + return false; + } + + ++loopIndex; + } + + if (!mDelegate->ModifySupportedMap(modifiedIndex, modifiedMap)) + { + return false; + } + + // map successfully renamed + NotifySupportedMapsChanged(); + return true; +} + +bool Instance::ClearSupportedMaps() +{ + // does device mode allow this attribute to be updated? + if (!mDelegate->IsSupportedMapChangeAllowed()) + { + return false; + } + + if (mDelegate->ClearSupportedMaps()) + { + ClearSupportedLocations(); + NotifySupportedMapsChanged(); + return true; + } + + return false; +} + +//************************************************************************* +// Selected Locations manipulators + +bool Instance::AddSelectedLocation(uint32_t & aSelectedLocation) +{ + // check max# of list entries + if (mDelegate->GetNumberOfSelectedLocations() >= kMaxNumSelectedLocations) + { + ChipLogError(Zcl, "AddSelectedLocation %u - maximum number of entries", aSelectedLocation); + return false; + } + + // each item in this list SHALL match the LocationID field of an entry on the SupportedLocations attribute's list + if (!IsSupportedLocation(aSelectedLocation)) + { + ChipLogError(Zcl, "AddSelectedLocation %u - not a supported location", aSelectedLocation); + return false; + } + + // each entry in this list SHALL have a unique value + if (mDelegate->IsSelectedLocation(aSelectedLocation)) + { + ChipLogError(Zcl, "AddSelectedLocation %u - duplicated location", aSelectedLocation); + return false; + } + + // Does device mode allow modification of selected locations? + char locationStatusBuffer[kMaxSizeStatusText]; + MutableCharSpan locationStatusText(locationStatusBuffer); + + if (!mDelegate->IsSetSelectedLocationsAllowed(locationStatusText)) + { + ChipLogError(Zcl, "AddSelectedLocation %u - %.*s", aSelectedLocation, static_cast(locationStatusText.size()), + locationStatusText.data()); + return false; + } + + uint32_t ignoredIndex; + return mDelegate->AddSelectedLocation(aSelectedLocation, ignoredIndex); +} + +bool Instance::ClearSelectedLocations() +{ + if (mDelegate->ClearSelectedLocations()) + { + NotifySelectedLocationsChanged(); + return true; + } + + return false; +} + +//************************************************************************* +// Current Location manipulators + +DataModel::Nullable Instance::GetCurrentLocation() +{ + return mCurrentLocation; +} + +bool Instance::SetCurrentLocation(const DataModel::Nullable & aCurrentLocation) +{ + // If not null, the value of this attribute SHALL match the LocationID field of an entry on the SupportedLocations attribute's + // list. + if ((!aCurrentLocation.IsNull()) && (!IsSupportedLocation(aCurrentLocation.Value()))) + { + ChipLogError(Zcl, "SetCurrentLocation %u - location is not supported", aCurrentLocation.Value()); + return false; + } + + bool notifyChange = mCurrentLocation != aCurrentLocation; + + mCurrentLocation = aCurrentLocation; + if (notifyChange) + { + NotifyCurrentLocationChanged(); + } + + // EstimatedEndTime SHALL be null if the CurrentLocation attribute is null. + if (mCurrentLocation.IsNull()) + { + SetEstimatedEndTime(DataModel::NullNullable); + } + + return true; +} + +//************************************************************************* +// Estimated End Time manipulators + +DataModel::Nullable Instance::GetEstimatedEndTime() +{ + return mEstimatedEndTime; +} + +bool Instance::SetEstimatedEndTime(const DataModel::Nullable & aEstimatedEndTime) +{ + // EstimatedEndTime SHALL be null if the CurrentLocation attribute is null. + if (mCurrentLocation.IsNull() && !aEstimatedEndTime.IsNull()) + { + ChipLogError(Zcl, "SetEstimatedEndTime - must be null if Current Location is null"); + return false; + } + + bool notifyChange = ReportEstimatedEndTimeChange(aEstimatedEndTime); + + mEstimatedEndTime = aEstimatedEndTime; + + if (notifyChange) + { + NotifyEstimatedEndTimeChanged(); + } + + // success + return true; +} + +//************************************************************************* +// Progress list manipulators + +bool Instance::AddPendingProgressElement(uint32_t aLocationId) +{ + // create progress element + Structs::ProgressStruct::Type inactiveProgress = { aLocationId, OperationalStatusEnum::kPending }; + + // check max# of list entries + if (mDelegate->GetNumberOfProgressElements() >= kMaxNumProgressElements) + { + ChipLogError(Zcl, "AddPendingProgressElement - maximum number of entries"); + return false; + } + + // For each entry in this list, the LocationID field SHALL match an entry on the SupportedLocations attribute's list. + if (!IsSupportedLocation(aLocationId)) + { + ChipLogError(Zcl, "AddPendingProgressElement - not a supported location %u", aLocationId); + return false; + } + + // Each entry in this list SHALL have a unique value for the LocationID field. + if (mDelegate->IsProgressElement(aLocationId)) + { + ChipLogError(Zcl, "AddPendingProgressElement - progress element already exists for location %u", aLocationId); + return false; + } + + uint32_t ignoredIndex; + + if (!mDelegate->AddProgressElement(inactiveProgress, ignoredIndex)) + { + return false; + } + + NotifyProgressChanged(); + return true; +} + +bool Instance::SetProgressStatus(uint32_t aLocationId, OperationalStatusEnum opStatus) +{ + uint32_t listIndex; + Structs::ProgressStruct::Type progressElement; + + if (!mDelegate->GetProgressElementById(aLocationId, listIndex, progressElement)) + { + ChipLogError(Zcl, "SetProgressStatus - progress element does not exist for location %u", aLocationId); + return false; + } + + // If the status value is not changing, there in no need to modify the existing element. + if (progressElement.status == opStatus) + { + return true; + } + + // set the progress status in the local copy + progressElement.status = opStatus; + + // TotalOperationalTime SHALL be null if the Status field is not set to Completed or Skipped. + if ((opStatus != OperationalStatusEnum::kCompleted) && (opStatus != OperationalStatusEnum::kSkipped)) + { + progressElement.totalOperationalTime.Value().SetNull(); + } + + // add the updated element to the progress attribute + if (!mDelegate->ModifyProgressElement(listIndex, progressElement)) + { + return false; + } + + NotifyProgressChanged(); + return true; +} + +bool Instance::SetProgressTotalOperationalTime(uint32_t aLocationId, const DataModel::Nullable & aTotalOperationalTime) +{ + uint32_t listIndex; + Structs::ProgressStruct::Type progressElement; + + if (!mDelegate->GetProgressElementById(aLocationId, listIndex, progressElement)) + { + ChipLogError(Zcl, "SetProgressTotalOperationalTime - progress element does not exist for location %u", aLocationId); + return false; + } + + // If the time value is not changing, there is no need to modify the existing element. + if (progressElement.totalOperationalTime == aTotalOperationalTime) + { + return true; + } + + // This attribute SHALL be null if the Status field is not set to Completed or Skipped + if (((progressElement.status == OperationalStatusEnum::kCompleted) || + (progressElement.status == OperationalStatusEnum::kSkipped)) && + !aTotalOperationalTime.IsNull()) + { + ChipLogError(Zcl, + "SetProgressTotalOperationalTime - location %u opStatus value %u - can be non-null only if opStatus is " + "Completed or Skipped", + aLocationId, to_underlying(progressElement.status)); + return false; + } + + // set the time in the local copy + progressElement.totalOperationalTime.Emplace(aTotalOperationalTime); + + // add the updated element to the progress attribute + if (!mDelegate->ModifyProgressElement(listIndex, progressElement)) + { + return false; + } + + NotifyProgressChanged(); + return true; +} + +bool Instance::SetProgressEstimatedTime(uint32_t aLocationId, const DataModel::Nullable & aEstimatedTime) +{ + uint32_t listIndex; + Structs::ProgressStruct::Type progressElement; + + if (!mDelegate->GetProgressElementById(aLocationId, listIndex, progressElement)) + { + ChipLogError(Zcl, "SetProgressEstimatedTime - progress element does not exist for location %u", aLocationId); + return false; + } + + // If the time value is not changing, there is no need to modify the existing element. + if (progressElement.estimatedTime == aEstimatedTime) + { + return true; + }; + + // set the time in the local copy + progressElement.estimatedTime.Emplace(aEstimatedTime); + + // add the updated element to the progress attribute + if (!mDelegate->ModifyProgressElement(listIndex, progressElement)) + { + return false; + } + + NotifyProgressChanged(); + return true; +} + +bool Instance::ClearProgress() +{ + if (mDelegate->ClearProgress()) + { + NotifyProgressChanged(); + return true; + } + + return false; +} + +// attribute manipulators - Feature Map + +bool Instance::HasFeature(Feature feature) const +{ + return mFeature.Has(feature); +} + +} // namespace ServiceArea +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/service-area-server/service-area-server.h b/src/app/clusters/service-area-server/service-area-server.h new file mode 100644 index 00000000000000..f43ea07337406f --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-server.h @@ -0,0 +1,357 @@ +/* + * + * 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 "service-area-cluster-objects.h" +#include "service-area-delegate.h" +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ServiceArea { + +/** + * Instance is a class that represents an instance of the generic Service Area cluster. + * It implements AttributeAccessInterface and CommandHandlerInterface so it can + * handle commands for any implementation of the location cluster. + * Custom implementations of the Service Area cluster override functions in the Delegate class + * must be provided to operate with specific devices. + */ +class Instance : public AttributeAccessInterface, public CommandHandlerInterface +{ +public: + /** + * @brief Creates a Service Area cluster instance. The Init() method needs to be called for this instance + * to be registered and called by the interaction model at the appropriate times. + * @param[in] aDelegate A pointer to the delegate to be used by this server. + * @param[in] aEndpointId The endpoint on which this cluster exists. This must match the zap configuration. + * @param[in] aFeature The supported features of this Service Area Cluster. + * + * @note the caller must ensure that the delegate lives throughout the instance's lifetime. + */ + Instance(Delegate * aDelegate, EndpointId aEndpointId, BitMask aFeature); + + ~Instance() override; + + /** + * Stop this class objects from being copied. + */ + Instance(const Instance &) = delete; + Instance & operator=(const Instance &) = delete; + + /** + * @brief Initialise the Service Area server instance. + * @return an error if the given endpoint and cluster Id have not been enabled in zap or if the + * CommandHandler or AttributeHandler registration fails, else CHIP_NO_ERROR. + */ + CHIP_ERROR Init(); + +private: + Delegate * mDelegate; + EndpointId mEndpointId; + ClusterId mClusterId; + + // Attribute Data Store + DataModel::Nullable mCurrentLocation; + DataModel::Nullable mEstimatedEndTime; + BitMask mFeature; + + //************************************************************************* + // core functions + + /** + * @brief Read Attribute - inherited from AttributeAccessInterface. + * @return appropriately mapped CHIP_ERROR if applicable. + */ + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + + /** + * @brief Command handler - inherited from CommandHandlerInterface. + * @param[in, out] ctx command context. + */ + void InvokeCommand(HandlerContext & ctx) override; + + //************************************************************************* + // attribute readers + + CHIP_ERROR ReadSupportedLocations(chip::app::AttributeValueEncoder & aEncoder); + + CHIP_ERROR ReadSupportedMaps(chip::app::AttributeValueEncoder & aEncoder); + + CHIP_ERROR ReadSelectedLocations(chip::app::AttributeValueEncoder & aEncoder); + + CHIP_ERROR ReadProgress(chip::app::AttributeValueEncoder & aEncoder); + + //************************************************************************* + // command handlers + + /** + * @param[in, out] ctx Returns the Interaction Model status code which was user determined in the business logic. + * If the input value is invalid, returns the Interaction Model status code of INVALID_COMMAND. + * @param[in] req the command parameters + */ + void HandleSelectLocationsCmd(HandlerContext & ctx, const Commands::SelectLocations::DecodableType & req); + + /** + * @param[in, out] ctx Returns the Interaction Model status code which was user determined in the business logic. + * If the input value is invalid, returns the Interaction Model status code of INVALID_COMMAND. + */ + void HandleSkipCurrentLocationCmd(HandlerContext & ctx); + + //************************************************************************* + // attribute notifications + + void NotifySupportedLocationsChanged(); + void NotifySupportedMapsChanged(); + void NotifySelectedLocationsChanged(); + void NotifyCurrentLocationChanged(); + void NotifyEstimatedEndTimeChanged(); + void NotifyProgressChanged(); + + //************************************************************************* + // Supported Locations manipulators + + /** + * @return true if a location with the aLocationId ID exists in the supported locations attribute. False otherwise. + */ + bool IsSupportedLocation(uint32_t aLocationId); + + /** + * @brief Check if the given location adheres to the restrictions required by the supported locations attribute. + * @return true if the aLocation meets all checks. + */ + bool IsValidSupportedLocation(const LocationStructureWrapper & aLocation); + + /** + * @brief check if aLocation is unique with regard to supported locations. + * @param[in] aLocation the location to check. + * @param[out] ignoreLocationId if true, we do not check if the location ID is unique. + * @return true if there isn't a location in supported locations that matches aLocation. + * + * @note This method may ignore checking the MapId uniqueness. This depends on whether the SupportedMaps attribute is null. + */ + bool IsUniqueSupportedLocation(const LocationStructureWrapper & aLocation, bool ignoreLocationId); + + /** + * @brief Check if changing the estimated end time attribute to aEstimatedEndTime requires the change to be reported. + * @param aEstimatedEndTime The new estimated end time. + * @return true if the change requires a report. + */ + bool ReportEstimatedEndTimeChange(const DataModel::Nullable & aEstimatedEndTime); + +public: + /** + * @brief Add new location to the supported locations list. + * @param[in] aLocationId unique identifier of this location. + * @param[in] aMapId identifier of supported map. + * @param[in] aLocationName human readable name for this location (empty string if not used). + * @param[in] aFloorNumber represents floor level - negative values for below ground. + * @param[in] aAreaType common namespace Area tag - indicates an association of the location with an indoor or outdoor area of a + * home. + * @param[in] aLandmarkTag common namespace Landmark tag - indicates an association of the location with a home landmark. + * @param[in] aPositionTag common namespace Position tag - indicates the position of the location with respect to the landmark. + * @param[in] aSurfaceTag common namespace Floor Surface tag - indicates an association of the location with a surface type. + * @return true if the new location passed validation checks and was successfully added to the list. + * + * @note if aLocationName is larger than kLocationNameMaxSize, it will be truncated. + */ + bool AddSupportedLocation(uint32_t aLocationId, const DataModel::Nullable & aMapId, const CharSpan & aLocationName, + const DataModel::Nullable & aFloorNumber, const DataModel::Nullable & aAreaType, + const DataModel::Nullable & aLandmarkTag, + const DataModel::Nullable & aPositionTag, + const DataModel::Nullable & aSurfaceTag); + + /** + * @brief Modify/replace an existing location in the supported locations list. + * @param[in] aLocationId unique identifier of this location. + * @param[in] aMapId identifier of supported map (will not be modified). + * @param[in] aLocationName human readable name for this location (empty string if not used). + * @param[in] aFloorNumber represents floor level - negative values for below ground. + * @param[in] aAreaType common namespace Area tag - indicates an association of the location with an indoor or outdoor area of a + * home. + * @param[in] aLandmarkTag common namespace Landmark tag - indicates an association of the location with a home landmark. + * @param[in] aPositionTag common namespace Position tag - indicates the position of the location with respect to the landmark. + * @param[in] aSurfaceTag common namespace Floor Surface tag - indicates an association of the location with a surface type. + * @return true if the location is a member of supported locations, the modifications pass all validation checks and the + * location was modified. + * + * @note if aLocationName is larger than kLocationNameMaxSize, it will be truncated. + * @note if mapID is changed, the delegate's HandleSupportedLocationsUpdated method is called. + */ + bool ModifySupportedLocation(uint32_t aLocationId, const DataModel::Nullable & aMapId, const CharSpan & aLocationName, + const DataModel::Nullable & aFloorNumber, + const DataModel::Nullable & aAreaType, + const DataModel::Nullable & aLandmarkTag, + const DataModel::Nullable & aPositionTag, + const DataModel::Nullable & aSurfaceTag); + + /** + * @return true if the SupportedLocations attribute was not already null. + * + * @note if SupportedLocations is cleared, the delegate's HandleSupportedLocationsUpdated method is called. + */ + bool ClearSupportedLocations(); + + //************************************************************************* + // Supported Maps manipulators + + /** + * @return true if a map with the aMapId ID exists in the supported maps attribute. False otherwise. + */ + bool IsSupportedMap(uint8_t aMapId); + + /** + * @brief Add a new map to the supported maps list. + * @param[in] aMapId The ID of the new map to be added. + * @param[in] aMapName The name of the map to be added. This cannot be an empty string. + * @return true if the new map passed validation checks and was successfully added to the list. + */ + bool AddSupportedMap(uint8_t aMapId, const CharSpan & aMapName); + + /** + * @brief Rename an existing map in the supported maps list. + * @param[in] aMapId The id of the map to modify. + * @param[in] newMapName The new name of the map. This cannot be empty string. + * @return true if the new name passed validation checks and was successfully modified. + * + * @note if the specified map is not a member of the supported maps list, returns false with no action taken. + */ + bool RenameSupportedMap(uint8_t aMapId, const CharSpan & newMapName); + + /** + * @return true if the SupportedMaps attribute was not already null. + * + * @note if SupportedMaps is cleared, the delegate's HandleSupportedLocationsUpdated method is called. + */ + bool ClearSupportedMaps(); + + //************************************************************************* + // Selected Locations manipulators + + /** + * @brief Add a selected location. + * @param[in] aSelectedLocation The locationID to add. + * @bool true if successfully added. + */ + bool AddSelectedLocation(uint32_t & aSelectedLocation); + + /** + * @return true if the SelectedLocations attribute was not already null. + */ + bool ClearSelectedLocations(); + + //************************************************************************* + // Current Location manipulators + + DataModel::Nullable GetCurrentLocation(); + + /** + * @param[in] aCurrentLocation The location ID that the CurrentLocation attribute should be set to. Must be a supported location + * or NULL. + * @return true if the current location is set, false otherwise. + * + * @note if current location is set to null, estimated end time will be set to null. + */ + bool SetCurrentLocation(const DataModel::Nullable & aCurrentLocation); + + //************************************************************************* + // Estimated End Time manipulators + + /** + * @return The estimated epoch time in seconds when operation at the location indicated by the CurrentLocation attribute will be + * completed. + */ + DataModel::Nullable GetEstimatedEndTime(); + + /** + * @param[in] aEstimatedEndTime The estimated epoch time in seconds when operation at the location indicated by the + * CurrentLocation attribute will be completed. + * @return true if attribute is set, false otherwise. + */ + bool SetEstimatedEndTime(const DataModel::Nullable & aEstimatedEndTime); + + //************************************************************************* + // Progress list manipulators + + /** + * @brief Add a progress element in a pending status to the progress list. + * @param[in] aLocationId location id of the progress element. + * @return true if the new progress element passed validation checks and was successfully added to the list, false otherwise. + */ + bool AddPendingProgressElement(uint32_t aLocationId); + + /** + * @brief Set the status of progress element identified by locationID. + * @param[in] aLocationId The locationID of the progress element to update. + * @param[in] status The location cluster operation status for this location. + * @return true if progress element is found and status is set, false otherwise. + * + * @note TotalOperationalTime is set to null if resulting opStatus is not equal to Completed or Skipped. + */ + bool SetProgressStatus(uint32_t aLocationId, OperationalStatusEnum opStatus); + + /** + * @brief Set the total operational time for the progress element identified by locationID. + * @param[in] aLocationId The locationID of the progress element to update. + * @param[in] aTotalOperationalTime The total operational time for this location. + * @return true if progress element is found and operational time is set, false otherwise. + */ + bool SetProgressTotalOperationalTime(uint32_t aLocationId, const DataModel::Nullable & aTotalOperationalTime); + + /** + * @brief Set the estimated time for the progress element identified by locationID. + * @param[in] aLocationId The locationID of the progress element to update. + * @param[in] aEstimatedTime The estimated time for this location. + * @return true if progress element is found and estimated time is set, false otherwise. + */ + bool SetProgressEstimatedTime(uint32_t aLocationId, const DataModel::Nullable & aEstimatedTime); + + /** + * @return true if the progress list was not already null, false otherwise. + */ + bool ClearProgress(); + + //************************************************************************* + // Feature Map attribute + + /** + * @brief Check if a feature is supported. + * @param[in] feature the feature enum. + * @return true if the feature is supported. + * + * @note the Service Area features are set at startup and are read-only to both device and client. + */ + bool HasFeature(ServiceArea::Feature feature) const; +}; + +} // namespace ServiceArea +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.cpp b/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.cpp new file mode 100644 index 00000000000000..dfc395f6bee81d --- /dev/null +++ b/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.cpp @@ -0,0 +1,155 @@ +/** + * + * 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 "PresetStructWithOwnedMembers.h" + +using namespace chip; +using namespace chip::app; +using namespace DataModel; +using namespace chip::app::Clusters::Thermostat::Structs; + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +PresetStructWithOwnedMembers::PresetStructWithOwnedMembers(const PresetStruct::Type & other) +{ + *this = other; +} + +void PresetStructWithOwnedMembers::operator=(const PresetStruct::Type & other) +{ + SetPresetScenario(other.presetScenario); + CHIP_ERROR err = SetPresetHandle(other.presetHandle); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Failed to set Preset handle with err %" CHIP_ERROR_FORMAT, err.Format()); + } + err = SetName(other.name); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Failed to set Preset name with err %" CHIP_ERROR_FORMAT, err.Format()); + } + SetCoolingSetpoint(other.coolingSetpoint); + SetHeatingSetpoint(other.heatingSetpoint); + SetBuiltIn(other.builtIn); +} + +void PresetStructWithOwnedMembers::SetPresetScenario(PresetScenarioEnum enumValue) +{ + presetScenario = enumValue; +} + +CHIP_ERROR PresetStructWithOwnedMembers::SetPresetHandle(const Nullable & newPresetHandle) +{ + if (!newPresetHandle.IsNull()) + { + size_t newPresetHandleSize = newPresetHandle.Value().size(); + if (newPresetHandleSize > kPresetHandleSize) + { + ChipLogError(Zcl, "Failed to set Preset handle. New preset handle size (%u) > allowed preset handle size (%u)", + static_cast(newPresetHandleSize), static_cast(kPresetNameSize)); + return CHIP_ERROR_NO_MEMORY; + } + MutableByteSpan targetSpan(presetHandleData); + ReturnErrorOnFailure(CopySpanToMutableSpan(newPresetHandle.Value(), targetSpan)); + presetHandle.SetNonNull(targetSpan); + } + else + { + presetHandle.SetNull(); + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR PresetStructWithOwnedMembers::SetName(const Optional> & newName) +{ + if (newName.HasValue() && !newName.Value().IsNull()) + { + size_t newNameSize = newName.Value().Value().size(); + if (newNameSize > kPresetNameSize) + { + ChipLogError(Zcl, "Failed to set Preset name. New name size (%u) > allowed preset name size (%u)", + static_cast(newNameSize), static_cast(kPresetNameSize)); + return CHIP_ERROR_NO_MEMORY; + } + MutableCharSpan targetSpan(presetNameData); + CharSpan newNameSpan = newName.Value().Value(); + ReturnErrorOnFailure(CopyCharSpanToMutableCharSpan(newNameSpan, targetSpan)); + + DataModel::Nullable nullableCharSpan; + nullableCharSpan.SetNonNull(targetSpan); + name.SetValue(nullableCharSpan); + } + else + { + name.ClearValue(); + } + return CHIP_NO_ERROR; +} + +void PresetStructWithOwnedMembers::SetCoolingSetpoint(const Optional & newCoolingSetpoint) +{ + coolingSetpoint = newCoolingSetpoint; +} + +void PresetStructWithOwnedMembers::SetHeatingSetpoint(const Optional & newHeatingSetpoint) +{ + heatingSetpoint = newHeatingSetpoint; +} + +void PresetStructWithOwnedMembers::SetBuiltIn(DataModel::Nullable newBuiltIn) +{ + builtIn = newBuiltIn; +} + +PresetScenarioEnum PresetStructWithOwnedMembers::GetPresetScenario() const +{ + return presetScenario; +} + +DataModel::Nullable PresetStructWithOwnedMembers::GetPresetHandle() const +{ + return presetHandle; +} + +Optional> PresetStructWithOwnedMembers::GetName() const +{ + return name; +} + +Optional PresetStructWithOwnedMembers::GetCoolingSetpoint() const +{ + return coolingSetpoint; +} + +Optional PresetStructWithOwnedMembers::GetHeatingSetpoint() const +{ + return heatingSetpoint; +} + +DataModel::Nullable PresetStructWithOwnedMembers::GetBuiltIn() const +{ + return builtIn; +} + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.h b/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.h new file mode 100644 index 00000000000000..7161fb874989e2 --- /dev/null +++ b/src/app/clusters/thermostat-server/PresetStructWithOwnedMembers.h @@ -0,0 +1,72 @@ +/** + * + * 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. + */ + +/**************************************************************************** + * @file + * @brief This class has a struct PresetStructWithOwnedMembers that inherits from + * Structs::PresetStruct::Type and manages the storage of the preset handle + * member which it owns. + * + ******************************************************************************* + ******************************************************************************/ + +#pragma once + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +static constexpr size_t kPresetHandleSize = 16; + +static constexpr size_t kPresetNameSize = 64; + +struct PresetStructWithOwnedMembers : protected Structs::PresetStruct::Type +{ +public: + PresetStructWithOwnedMembers() = default; + PresetStructWithOwnedMembers(const Structs::PresetStruct::Type & other); + void operator=(const Structs::PresetStruct::Type & other); + + void SetPresetScenario(PresetScenarioEnum enumValue); + CHIP_ERROR SetPresetHandle(const DataModel::Nullable & newPresetHandle); + CHIP_ERROR SetName(const Optional> & newName); + void SetCoolingSetpoint(const Optional & newCoolingSetpoint); + void SetHeatingSetpoint(const Optional & newHeatingSetpoint); + void SetBuiltIn(DataModel::Nullable newBuiltIn); + + PresetScenarioEnum GetPresetScenario() const; + DataModel::Nullable GetPresetHandle() const; + Optional> GetName() const; + Optional GetCoolingSetpoint() const; + Optional GetHeatingSetpoint() const; + DataModel::Nullable GetBuiltIn() const; + + using Structs::PresetStruct::Type::Encode; + using Structs::PresetStruct::Type::kIsFabricScoped; + +private: + uint8_t presetHandleData[kPresetHandleSize] = { 0 }; + char presetNameData[kPresetNameSize]; +}; + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thermostat-server/thermostat-delegate.h b/src/app/clusters/thermostat-server/thermostat-delegate.h new file mode 100644 index 00000000000000..86c1e532b92fc2 --- /dev/null +++ b/src/app/clusters/thermostat-server/thermostat-delegate.h @@ -0,0 +1,129 @@ +/** + * + * 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. + */ + +#pragma once + +#include "PresetStructWithOwnedMembers.h" +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +/** @brief + * Defines methods for implementing application-specific logic for handling Presets in the thermostat cluster. + * It defines the interfaces that a thermostat should implement to enable support for reading and writing the + * Presets attribute and reading and writing the ActivePresetHandle attribute. + */ +class Delegate +{ +public: + Delegate() = default; + + virtual ~Delegate() = default; + + /** + * @brief Get the preset type at a given index in the PresetTypes attribute + * + * @param[in] index The index of the preset type in the list. + * @param[out] presetType The preset type at the given index in the list. + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the preset types list. + */ + virtual CHIP_ERROR GetPresetTypeAtIndex(size_t index, Structs::PresetTypeStruct::Type & presetType) = 0; + + /** + * @brief Get the NumberOfPresets attribute value. + * + * @return The max number of presets supported. Return 0 if not set. + */ + virtual uint8_t GetNumberOfPresets() = 0; + + /** + * @brief Get the preset at a given index in the Presets attribute. + * + * @param[in] index The index of the preset in the list. + * @param[out] preset The PresetStructWithOwnedMembers struct that has the data from the preset + * at the given index in the Presets attribute list. + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the presets list. + */ + virtual CHIP_ERROR GetPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) = 0; + + /** + * @brief Get the ActivePresetHandle attribute value. + * + * @param[out] activePresetHandle The MutableByteSpan to copy the active preset handle into. On success, + * the callee must update the length to the length of the copied data. If the value of + * the attribute is null, the callee must set the MutableByteSpan to empty. + */ + virtual CHIP_ERROR GetActivePresetHandle(MutableByteSpan & activePresetHandle) = 0; + + /** + * @brief Set the ActivePresetHandle attribute value. + * + * @param[in] newActivePresetHandle The octet string to set the active preset handle to. + */ + virtual CHIP_ERROR SetActivePresetHandle(const DataModel::Nullable & newActivePresetHandle) = 0; + + /** + * @brief Appends a preset to the pending presets list maintained by the delegate. + * The delegate must ensure it makes a copy of the provided preset and the data + * of its preset handle, if any. For example, it could create a PresetStructWithOwnedMembers + * from the provided preset. + * + * @param[in] preset The preset to add to the list. + * + * @return CHIP_NO_ERROR if the preset was appended to the list successfully. + * @return CHIP_ERROR if there was an error adding the preset to the list. + */ + virtual CHIP_ERROR AppendToPendingPresetList(const Structs::PresetStruct::Type & preset) = 0; + + /** + * @brief Get the Preset at a given index in the pending presets list. + * + * @param[in] index The index of the preset in the list. + * @param[out] preset The PresetStructWithOwnedMembers struct that has the data from the pending preset + * list at the given index. + * @return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED if the index is out of range for the pending presets list. + */ + virtual CHIP_ERROR GetPendingPresetAtIndex(size_t index, PresetStructWithOwnedMembers & preset) = 0; + + /** + * @brief Updates the presets attribute with the content of the pending presets list. If the preset in the pending presets list + * matches i.e. has the same presetHandle as an existing entry in the Presets attribute, the thermostat will update the entry + * with the new preset values, otherwise it will add a new preset to the Presets attribute. For new presets that get added, + * it is the responsibility of this API to allocate unique preset handles to the presets before saving the preset. This will be + * called when the Thermostat receives a CommitPresetsSchedulesRequest command to commit the pending preset changes. + * + * @return CHIP_NO_ERROR if the updates to the presets attribute has been committed successfully. + * @return CHIP_ERROR if the updates to the presets attribute failed to commit for some reason. + * + */ + virtual CHIP_ERROR ApplyPendingPresets() = 0; + + /** + * @brief Clears the pending presets list. + * + */ + virtual void ClearPendingPresetList() = 0; +}; + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thermostat-server/thermostat-server.cpp b/src/app/clusters/thermostat-server/thermostat-server.cpp index c650a30c871989..71c2f3d6fd6260 100644 --- a/src/app/clusters/thermostat-server/thermostat-server.cpp +++ b/src/app/clusters/thermostat-server/thermostat-server.cpp @@ -15,7 +15,9 @@ * limitations under the License. */ -#include +#include "thermostat-server.h" +#include "PresetStructWithOwnedMembers.h" + #include #include @@ -26,11 +28,13 @@ #include #include #include +#include using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::Thermostat; +using namespace chip::app::Clusters::Thermostat::Structs; using namespace chip::app::Clusters::Thermostat::Attributes; using imcode = Protocols::InteractionModel::Status; @@ -65,16 +69,645 @@ constexpr int8_t kDefaultDeadBand = 25; // 2.5C is the default namespace { -class ThermostatAttrAccess : public AttributeAccessInterface +ThermostatAttrAccess gThermostatAttrAccess; + +static_assert(kThermostatEndpointCount <= kEmberInvalidEndpointIndex, "Thermostat Delegate table size error"); + +Delegate * gDelegateTable[kThermostatEndpointCount] = { nullptr }; + +Delegate * GetDelegate(EndpointId endpoint) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= ArraySize(gDelegateTable) ? nullptr : gDelegateTable[ep]); +} + +/** + * @brief Check if a preset is valid. + * + * @param[in] preset The preset to check. + * + * @return true If the preset is valid i.e the PresetHandle (if not null) fits within size constraints and the presetScenario enum + * value is valid. Otherwise, return false. + */ +bool IsValidPresetEntry(const PresetStruct::Type & preset) +{ + // Check that the preset handle is not too long. + if (!preset.presetHandle.IsNull() && preset.presetHandle.Value().size() > kPresetHandleSize) + { + return false; + } + + // Ensure we have a valid PresetScenario. + return (preset.presetScenario != PresetScenarioEnum::kUnknownEnumValue); +} + +/** + * @brief Callback that is called when the timeout for editing the presets expires. + * + * @param[in] systemLayer The system layer. + * @param[in] callbackContext The context passed to the timer callback. + */ +void TimerExpiredCallback(System::Layer * systemLayer, void * callbackContext) +{ + EndpointId endpoint = static_cast(reinterpret_cast(callbackContext)); + + Delegate * delegate = GetDelegate(endpoint); + VerifyOrReturn(delegate != nullptr, ChipLogError(Zcl, "Delegate is null. Unable to handle timer expired")); + + delegate->ClearPendingPresetList(); + gThermostatAttrAccess.SetPresetsEditable(endpoint, false); +} + +/** + * @brief Schedules a timer for the given timeout in seconds. + * + * @param[in] endpoint The endpoint to use. + * @param[in] timeoutSeconds The timeout in seconds. + */ +void ScheduleTimer(EndpointId endpoint, uint16_t timeoutSeconds) +{ + DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(timeoutSeconds), TimerExpiredCallback, + reinterpret_cast(static_cast(endpoint))); +} + +/** + * @brief Clears the currently scheduled timer. + * + * @param[in] endpoint The endpoint to use. + */ +void ClearTimer(EndpointId endpoint) +{ + DeviceLayer::SystemLayer().CancelTimer(TimerExpiredCallback, reinterpret_cast(static_cast(endpoint))); +} + +/** + * @brief Extends the currently scheduled timer to a new timeout value in seconds + * + * @param[in] endpoint The endpoint to use. + * @param[in] timeoutSeconds The timeout in seconds to extend the timer to. + */ +void ExtendTimer(EndpointId endpoint, uint16_t timeoutSeconds) +{ + DeviceLayer::SystemLayer().ExtendTimerTo(System::Clock::Seconds16(timeoutSeconds), TimerExpiredCallback, + reinterpret_cast(static_cast(endpoint))); +} + +/** + * @brief Checks if the preset is built-in + * + * @param[in] preset The preset to check. + * + * @return true If the preset is built-in, false otherwise. + */ +bool IsBuiltIn(const PresetStructWithOwnedMembers & preset) +{ + return preset.GetBuiltIn().ValueOr(false); +} + +/** + * @brief Checks if the presets are matching i.e the presetHandles are the same. + * + * @param[in] preset The preset to check. + * @param[in] presetToMatch The preset to match with. + * + * @return true If the presets match, false otherwise. If both preset handles are null, returns false + */ +bool PresetHandlesExistAndMatch(const PresetStructWithOwnedMembers & preset, const PresetStructWithOwnedMembers & presetToMatch) +{ + return !preset.GetPresetHandle().IsNull() && !presetToMatch.GetPresetHandle().IsNull() && + preset.GetPresetHandle().Value().data_equal(presetToMatch.GetPresetHandle().Value()); +} + +/** + * @brief Get the source scoped node id. + * + * @param[in] commandObj The command handler object. + * + * @return The scoped node id of the source node. If the scoped node id is not retreived, return ScopedNodeId(). + */ +ScopedNodeId GetSourceScopedNodeId(CommandHandler * commandObj) +{ + ScopedNodeId sourceNodeId = ScopedNodeId(); + auto sessionHandle = commandObj->GetExchangeContext()->GetSessionHandle(); + + if (sessionHandle->IsSecureSession()) + { + sourceNodeId = sessionHandle->AsSecureSession()->GetPeer(); + } + else if (sessionHandle->IsGroupSession()) + { + sourceNodeId = sessionHandle->AsIncomingGroupSession()->GetPeer(); + } + return sourceNodeId; +} + +/** + * @brief Utility to clean up state by clearing the pending presets list, canceling the timer + * and setting PresetsEditable to false and clear the originator scoped node id. + * + * @param[in] delegate The delegate to use. + * @param[in] endpoint The endpoint to use. + */ +void CleanUp(Delegate * delegate, EndpointId endpoint) +{ + if (delegate != nullptr) + { + delegate->ClearPendingPresetList(); + } + ClearTimer(endpoint); + gThermostatAttrAccess.SetPresetsEditable(endpoint, false); + gThermostatAttrAccess.SetOriginatorScopedNodeId(endpoint, ScopedNodeId()); +} + +/** + * @brief Sends a response for the command and cleans up state by calling CleanUp() + * + * @param[in] delegate The delegate to use. + * @param[in] endpoint The endpoint to use. + * @param[in] commandObj The command handler to use to add the status response. + * @param[in] commandPath The command path. + * @param[in] status The status code to send as the response. + * + * @return true to indicate the response has been sent and command has been handled. + */ +bool SendResponseAndCleanUp(Delegate * delegate, EndpointId endpoint, CommandHandler * commandObj, + const ConcreteCommandPath & commandPath, imcode status) +{ + commandObj->AddStatus(commandPath, status); + CleanUp(delegate, endpoint); + return true; +} + +/** + * @brief Finds an entry in the pending presets list that matches a preset. + * The presetHandle of the two presets must match. + * + * @param[in] delegate The delegate to use. + * @param[in] presetToMatch The preset to match with. + * + * @return true if a matching entry was found in the pending presets list, false otherwise. + */ +bool MatchingPendingPresetExists(Delegate * delegate, const PresetStructWithOwnedMembers & presetToMatch) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers preset; + CHIP_ERROR err = delegate->GetPendingPresetAtIndex(i, preset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "MatchingPendingPresetExists: GetPendingPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, + err.Format()); + return false; + } + + if (PresetHandlesExistAndMatch(preset, presetToMatch)) + { + return true; + } + } + return false; +} + +/** + * @brief Finds and returns an entry in the Presets attribute list that matches a preset. + * The presetHandle of the two presets must match. + * + * @param[in] delegate The delegate to use. + * @param[in] presetToMatch The preset to match with. + * @param[out] matchingPreset The preset in the Presets attribute list that has the same PresetHandle as the presetToMatch. + * + * @return true if a matching entry was found in the presets attribute list, false otherwise. + */ +bool GetMatchingPresetInPresets(Delegate * delegate, const PresetStructWithOwnedMembers & presetToMatch, + PresetStructWithOwnedMembers & matchingPreset) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + for (uint8_t i = 0; true; i++) + { + CHIP_ERROR err = delegate->GetPresetAtIndex(i, matchingPreset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "GetMatchingPresetInPresets: GetPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, err.Format()); + return false; + } + + if (PresetHandlesExistAndMatch(matchingPreset, presetToMatch)) + { + return true; + } + } + return false; +} + +/** + * @brief Checks if the given preset handle is present in the presets attribute + * @param[in] delegate The delegate to use. + * @param[in] presetHandleToMatch The preset handle to match with. + * + * @return true if the given preset handle is present in the presets attribute list, false otherwise. + */ +bool IsPresetHandlePresentInPresets(Delegate * delegate, const ByteSpan & presetHandleToMatch) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + PresetStructWithOwnedMembers matchingPreset; + for (uint8_t i = 0; true; i++) + { + CHIP_ERROR err = delegate->GetPresetAtIndex(i, matchingPreset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return false; + } + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "IsPresetHandlePresentInPresets: GetPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, + err.Format()); + return false; + } + + if (!matchingPreset.GetPresetHandle().IsNull() && matchingPreset.GetPresetHandle().Value().data_equal(presetHandleToMatch)) + { + return true; + } + } + return false; +} + +/** + * @brief Returns the length of the list of presets if the pending presets were to be applied. The calculation is done by + * adding the number of presets in Presets attribute list to the number of pending presets in the pending + * presets list and subtracting the number of duplicate presets. This is called before changes are actually applied. + * + * @param[in] delegate The delegate to use. + * + * @return count of the updated Presets attribute if the pending presets were applied to it. Return 0 for error cases. + */ +uint8_t CountUpdatedPresetsAfterApplyingPendingPresets(Delegate * delegate) +{ + uint8_t numberOfPresets = 0; + uint8_t numberOfMatches = 0; + uint8_t numberOfPendingPresets = 0; + + VerifyOrReturnValue(delegate != nullptr, 0); + + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers preset; + CHIP_ERROR err = delegate->GetPresetAtIndex(i, preset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "GetUpdatedPresetsCount: GetPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, err.Format()); + return 0; + } + numberOfPresets++; + + bool found = MatchingPendingPresetExists(delegate, preset); + + if (found) + { + numberOfMatches++; + } + } + + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers pendingPreset; + CHIP_ERROR err = delegate->GetPendingPresetAtIndex(i, pendingPreset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "GetUpdatedPresetsCount: GetPendingPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, + err.Format()); + return 0; + } + numberOfPendingPresets++; + } + + // TODO: #34546 - Need to support deletion of presets that are removed from Presets. + // This API needs to modify its logic for the deletion case. + return static_cast(numberOfPresets + numberOfPendingPresets - numberOfMatches); +} + +/** + * @brief Checks if the presetScenario is present in the PresetTypes attribute. + * + * @param[in] delegate The delegate to use. + * @param[in] presetScenario The presetScenario to match with. + * + * @return true if the presetScenario is found, false otherwise. + */ +bool PresetScenarioExistsInPresetTypes(Delegate * delegate, PresetScenarioEnum presetScenario) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + for (uint8_t i = 0; true; i++) + { + PresetTypeStruct::Type presetType; + auto err = delegate->GetPresetTypeAtIndex(i, presetType); + if (err != CHIP_NO_ERROR) + { + return false; + } + + if (presetType.presetScenario == presetScenario) + { + return true; + } + } + return false; +} + +/** + * @brief Returns the count of preset entries in the pending presets list that have the matching presetHandle. + * @param[in] delegate The delegate to use. + * @param[in] presetHandleToMatch The preset handle to match. + * + * @return count of the number of presets found with the matching presetHandle. Returns 0 if no matching presets were found. + */ +uint8_t CountPresetsInPendingListWithPresetHandle(Delegate * delegate, const ByteSpan & presetHandleToMatch) +{ + uint8_t count = 0; + VerifyOrReturnValue(delegate != nullptr, count); + + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers preset; + auto err = delegate->GetPendingPresetAtIndex(i, preset); + if (err != CHIP_NO_ERROR) + { + return count; + } + + DataModel::Nullable presetHandle = preset.GetPresetHandle(); + if (!presetHandle.IsNull() && presetHandle.Value().data_equal(presetHandleToMatch)) + { + count++; + } + } + return count; +} + +/** + * @brief Checks if the presetType for the given preset scenario supports name in the presetTypeFeatures bitmap. + * + * @param[in] delegate The delegate to use. + * @param[in] presetScenario The presetScenario to match with. + * + * @return true if the presetType for the given preset scenario supports name, false otherwise. + */ +bool PresetTypeSupportsNames(Delegate * delegate, PresetScenarioEnum scenario) +{ + VerifyOrReturnValue(delegate != nullptr, false); + + for (uint8_t i = 0; true; i++) + { + PresetTypeStruct::Type presetType; + auto err = delegate->GetPresetTypeAtIndex(i, presetType); + if (err != CHIP_NO_ERROR) + { + return false; + } + + if (presetType.presetScenario == scenario) + { + return (presetType.presetTypeFeatures.Has(PresetTypeFeaturesBitmap::kSupportsNames)); + } + } + return false; +} + +int16_t EnforceHeatingSetpointLimits(int16_t HeatingSetpoint, EndpointId endpoint) +{ + // Optional Mfg supplied limits + int16_t AbsMinHeatSetpointLimit = kDefaultAbsMinHeatSetpointLimit; + int16_t AbsMaxHeatSetpointLimit = kDefaultAbsMaxHeatSetpointLimit; + + // Optional User supplied limits + int16_t MinHeatSetpointLimit = kDefaultMinHeatSetpointLimit; + int16_t MaxHeatSetpointLimit = kDefaultMaxHeatSetpointLimit; + + // Attempt to read the setpoint limits + // Absmin/max are manufacturer limits + // min/max are user imposed min/max + + // Note that the limits are initialized above per the spec limits + // if they are not present Get() will not update the value so the defaults are used + imcode status; + + // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3724 + // behavior is not specified when Abs * values are not present and user values are present + // implemented behavior accepts the user values without regard to default Abs values. + + // Per global matter data model policy + // if a attribute is not present then it's default shall be used. + + status = AbsMinHeatSetpointLimit::Get(endpoint, &AbsMinHeatSetpointLimit); + if (status != imcode::Success) + { + ChipLogError(Zcl, "Warning: AbsMinHeatSetpointLimit missing using default"); + } + + status = AbsMaxHeatSetpointLimit::Get(endpoint, &AbsMaxHeatSetpointLimit); + if (status != imcode::Success) + { + ChipLogError(Zcl, "Warning: AbsMaxHeatSetpointLimit missing using default"); + } + status = MinHeatSetpointLimit::Get(endpoint, &MinHeatSetpointLimit); + if (status != imcode::Success) + { + MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + } + + status = MaxHeatSetpointLimit::Get(endpoint, &MaxHeatSetpointLimit); + if (status != imcode::Success) + { + MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; + } + + // Make sure the user imposed limits are within the manufacturer imposed limits + + // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3725 + // Spec does not specify the behavior is the requested setpoint exceeds the limit allowed + // This implementation clamps at the limit. + + // resolution of 3725 is to clamp. + + if (MinHeatSetpointLimit < AbsMinHeatSetpointLimit) + MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + + if (MaxHeatSetpointLimit > AbsMaxHeatSetpointLimit) + MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; + + if (HeatingSetpoint < MinHeatSetpointLimit) + HeatingSetpoint = MinHeatSetpointLimit; + + if (HeatingSetpoint > MaxHeatSetpointLimit) + HeatingSetpoint = MaxHeatSetpointLimit; + + return HeatingSetpoint; +} + +int16_t EnforceCoolingSetpointLimits(int16_t CoolingSetpoint, EndpointId endpoint) +{ + // Optional Mfg supplied limits + int16_t AbsMinCoolSetpointLimit = kDefaultAbsMinCoolSetpointLimit; + int16_t AbsMaxCoolSetpointLimit = kDefaultAbsMaxCoolSetpointLimit; + + // Optional User supplied limits + int16_t MinCoolSetpointLimit = kDefaultMinCoolSetpointLimit; + int16_t MaxCoolSetpointLimit = kDefaultMaxCoolSetpointLimit; + + // Attempt to read the setpoint limits + // Absmin/max are manufacturer limits + // min/max are user imposed min/max + + // Note that the limits are initialized above per the spec limits + // if they are not present Get() will not update the value so the defaults are used + imcode status; + + // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3724 + // behavior is not specified when Abs * values are not present and user values are present + // implemented behavior accepts the user values without regard to default Abs values. + + // Per global matter data model policy + // if a attribute is not present then it's default shall be used. + + status = AbsMinCoolSetpointLimit::Get(endpoint, &AbsMinCoolSetpointLimit); + if (status != imcode::Success) + { + ChipLogError(Zcl, "Warning: AbsMinCoolSetpointLimit missing using default"); + } + + status = AbsMaxCoolSetpointLimit::Get(endpoint, &AbsMaxCoolSetpointLimit); + if (status != imcode::Success) + { + ChipLogError(Zcl, "Warning: AbsMaxCoolSetpointLimit missing using default"); + } + + status = MinCoolSetpointLimit::Get(endpoint, &MinCoolSetpointLimit); + if (status != imcode::Success) + { + MinCoolSetpointLimit = AbsMinCoolSetpointLimit; + } + + status = MaxCoolSetpointLimit::Get(endpoint, &MaxCoolSetpointLimit); + if (status != imcode::Success) + { + MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; + } + + // Make sure the user imposed limits are within the manufacture imposed limits + // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3725 + // Spec does not specify the behavior is the requested setpoint exceeds the limit allowed + // This implementation clamps at the limit. + + // resolution of 3725 is to clamp. + + if (MinCoolSetpointLimit < AbsMinCoolSetpointLimit) + MinCoolSetpointLimit = AbsMinCoolSetpointLimit; + + if (MaxCoolSetpointLimit > AbsMaxCoolSetpointLimit) + MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; + + if (CoolingSetpoint < MinCoolSetpointLimit) + CoolingSetpoint = MinCoolSetpointLimit; + + if (CoolingSetpoint > MaxCoolSetpointLimit) + CoolingSetpoint = MaxCoolSetpointLimit; + + return CoolingSetpoint; +} + +} // anonymous namespace + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + // if endpoint is found, add the delegate in the delegate table + if (ep < ArraySize(gDelegateTable)) + { + gDelegateTable[ep] = delegate; + } +} + +void ThermostatAttrAccess::SetPresetsEditable(EndpointId endpoint, bool presetEditable) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (ep < ArraySize(mPresetsEditables)) + { + mPresetsEditables[ep] = presetEditable; + } +} + +bool ThermostatAttrAccess::GetPresetsEditable(EndpointId endpoint) +{ + bool presetEditable = false; + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (ep < ArraySize(mPresetsEditables)) + { + presetEditable = mPresetsEditables[ep]; + } + return presetEditable; +} + +void ThermostatAttrAccess::SetOriginatorScopedNodeId(EndpointId endpoint, ScopedNodeId originatorNodeId) +{ + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (ep < ArraySize(mPresetEditRequestOriginatorNodeIds)) + { + mPresetEditRequestOriginatorNodeIds[ep] = originatorNodeId; + } +} + +ScopedNodeId ThermostatAttrAccess::GetOriginatorScopedNodeId(EndpointId endpoint) { -public: - ThermostatAttrAccess() : AttributeAccessInterface(Optional::Missing(), Thermostat::Id) {} - - CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; - CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override; -}; + ScopedNodeId originatorNodeId = ScopedNodeId(); + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); -ThermostatAttrAccess gThermostatAttrAccess; + if (ep < ArraySize(mPresetEditRequestOriginatorNodeIds)) + { + originatorNodeId = mPresetEditRequestOriginatorNodeIds[ep]; + } + return originatorNodeId; +} CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) { @@ -107,11 +740,72 @@ CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, A } break; case PresetTypes::Id: { - return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; }); + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + return aEncoder.EncodeList([delegate](const auto & encoder) -> CHIP_ERROR { + for (uint8_t i = 0; true; i++) + { + PresetTypeStruct::Type presetType; + auto err = delegate->GetPresetTypeAtIndex(i, presetType); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(presetType)); + } + }); + } + break; + case NumberOfPresets::Id: { + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + ReturnErrorOnFailure(aEncoder.Encode(delegate->GetNumberOfPresets())); } break; case Presets::Id: { - return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; }); + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + return aEncoder.EncodeList([delegate](const auto & encoder) -> CHIP_ERROR { + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers preset; + auto err = delegate->GetPresetAtIndex(i, preset); + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + ReturnErrorOnFailure(encoder.Encode(preset)); + } + }); + } + break; + case PresetsSchedulesEditable::Id: { + ReturnErrorOnFailure(aEncoder.Encode(GetPresetsEditable(aPath.mEndpointId))); + } + break; + case ActivePresetHandle::Id: { + Delegate * delegate = GetDelegate(aPath.mEndpointId); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + uint8_t buffer[kPresetHandleSize]; + MutableByteSpan activePresetHandle(buffer); + + CHIP_ERROR err = delegate->GetActivePresetHandle(activePresetHandle); + ReturnErrorOnFailure(err); + + if (activePresetHandle.empty()) + { + ReturnErrorOnFailure(aEncoder.EncodeNull()); + } + else + { + ReturnErrorOnFailure(aEncoder.Encode(activePresetHandle)); + } } break; case ScheduleTypes::Id: { @@ -154,10 +848,72 @@ CHIP_ERROR ThermostatAttrAccess::Write(const ConcreteDataAttributePath & aPath, } break; case Presets::Id: { - return CHIP_ERROR_NOT_IMPLEMENTED; + + EndpointId endpoint = aPath.mEndpointId; + Delegate * delegate = GetDelegate(endpoint); + VerifyOrReturnError(delegate != nullptr, CHIP_ERROR_INCORRECT_STATE, ChipLogError(Zcl, "Delegate is null")); + + // Presets are not editable, return INVALID_IN_STATE. + VerifyOrReturnError(GetPresetsEditable(endpoint), CHIP_IM_GLOBAL_STATUS(InvalidInState), + ChipLogError(Zcl, "Presets are not editable")); + + // Check if the OriginatorScopedNodeId at the endpoint is the same as the node editing the presets, + // otherwise return BUSY. + const Access::SubjectDescriptor subjectDescriptor = aDecoder.GetSubjectDescriptor(); + ScopedNodeId scopedNodeId = ScopedNodeId(); + + // Get the node id if the authentication mode is CASE. + if (subjectDescriptor.authMode == Access::AuthMode::kCase) + { + scopedNodeId = ScopedNodeId(subjectDescriptor.subject, subjectDescriptor.fabricIndex); + } + + if (GetOriginatorScopedNodeId(endpoint) != scopedNodeId) + { + ChipLogError(Zcl, "Another node is editing presets. Server is busy. Try again later"); + return CHIP_IM_GLOBAL_STATUS(Busy); + } + + // If the list operation is replace all, clear the existing pending list, iterate over the new presets list + // and add to the pending presets list. + if (!aPath.IsListOperation() || aPath.mListOp == ConcreteDataAttributePath::ListOperation::ReplaceAll) + { + // Clear the pending presets list + delegate->ClearPendingPresetList(); + + Presets::TypeInfo::DecodableType newPresetsList; + ReturnErrorOnFailure(aDecoder.Decode(newPresetsList)); + + // Iterate over the presets and call the delegate to append to the list of pending presets. + auto iter = newPresetsList.begin(); + while (iter.Next()) + { + const PresetStruct::Type & preset = iter.GetValue(); + if (IsValidPresetEntry(preset)) + { + ReturnErrorOnFailure(delegate->AppendToPendingPresetList(preset)); + } + else + { + return CHIP_IM_GLOBAL_STATUS(ConstraintError); + } + } + return iter.GetStatus(); + } + + // If the list operation is AppendItem, call the delegate to append the item to the list of pending presets. + if (aPath.mListOp == ConcreteDataAttributePath::ListOperation::AppendItem) + { + PresetStruct::Type preset; + ReturnErrorOnFailure(aDecoder.Decode(preset)); + if (IsValidPresetEntry(preset)) + { + return delegate->AppendToPendingPresetList(preset); + } + return CHIP_IM_GLOBAL_STATUS(ConstraintError); + } } break; - case Schedules::Id: { return CHIP_ERROR_NOT_IMPLEMENTED; } @@ -169,7 +925,10 @@ CHIP_ERROR ThermostatAttrAccess::Write(const ConcreteDataAttributePath & aPath, return CHIP_NO_ERROR; } -} // anonymous namespace +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip void emberAfThermostatClusterServerInitCallback(chip::EndpointId endpoint) { @@ -496,182 +1255,310 @@ bool emberAfThermostatClusterSetActivePresetRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::SetActivePresetRequest::DecodableType & commandData) { - // TODO - return false; + EndpointId endpoint = commandPath.mEndpointId; + Delegate * delegate = GetDelegate(endpoint); + + if (delegate == nullptr) + { + ChipLogError(Zcl, "Delegate is null"); + commandObj->AddStatus(commandPath, imcode::InvalidInState); + return true; + } + + ByteSpan newPresetHandle = commandData.presetHandle; + + // If the preset handle passed in the command is not present in the Presets attribute, return INVALID_COMMAND. + if (!IsPresetHandlePresentInPresets(delegate, newPresetHandle)) + { + commandObj->AddStatus(commandPath, imcode::InvalidCommand); + return true; + } + + CHIP_ERROR err = delegate->SetActivePresetHandle(DataModel::MakeNullable(newPresetHandle)); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Failed to set ActivePresetHandle with error %" CHIP_ERROR_FORMAT, err.Format()); + commandObj->AddStatus(commandPath, StatusIB(err).mStatus); + return true; + } + + commandObj->AddStatus(commandPath, imcode::Success); + return true; } bool emberAfThermostatClusterStartPresetsSchedulesEditRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::StartPresetsSchedulesEditRequest::DecodableType & commandData) { - // TODO - return false; + ScopedNodeId sourceNodeId = GetSourceScopedNodeId(commandObj); + + EndpointId endpoint = commandPath.mEndpointId; + + // If the presets are editable and the scoped node id of the client sending StartPresetsSchedulesEditRequest command + // is not the same as the one that previously originated a StartPresetsSchedulesEditRequest command, return BUSY. + if (gThermostatAttrAccess.GetPresetsEditable(endpoint) && + (gThermostatAttrAccess.GetOriginatorScopedNodeId(endpoint) != sourceNodeId)) + { + commandObj->AddStatus(commandPath, imcode::Busy); + return true; + } + + // If presets are editable and the scoped node id of the client sending StartPresetsSchedulesEditRequest command + // is the same as the one that previously originated a StartPresetsSchedulesEditRequest command, extend the timer. + if (gThermostatAttrAccess.GetPresetsEditable(endpoint)) + { + ExtendTimer(endpoint, commandData.timeoutSeconds); + commandObj->AddStatus(commandPath, imcode::Success); + return true; + } + + // Set presets editable to true and the scoped originator node id to the source scoped node id, and start a timer with the + // timeout in seconds passed in the command args. Return success. + gThermostatAttrAccess.SetPresetsEditable(endpoint, true); + gThermostatAttrAccess.SetOriginatorScopedNodeId(endpoint, sourceNodeId); + ScheduleTimer(endpoint, commandData.timeoutSeconds); + commandObj->AddStatus(commandPath, imcode::Success); + return true; } bool emberAfThermostatClusterCancelPresetsSchedulesEditRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::CancelPresetsSchedulesEditRequest::DecodableType & commandData) { - // TODO - return false; + EndpointId endpoint = commandPath.mEndpointId; + + // If presets are not editable, return INVALID_IN_STATE. + if (!gThermostatAttrAccess.GetPresetsEditable(endpoint)) + { + commandObj->AddStatus(commandPath, imcode::InvalidInState); + return true; + } + + ScopedNodeId sourceNodeId = GetSourceScopedNodeId(commandObj); + + // If the node id sending the CancelPresetsSchedulesRequest command is not the same as the one which send the + // previous StartPresetsSchedulesEditRequest, return UNSUPPORTED_ACCESS. + if (gThermostatAttrAccess.GetOriginatorScopedNodeId(endpoint) != sourceNodeId) + { + commandObj->AddStatus(commandPath, imcode::UnsupportedAccess); + return true; + } + + Delegate * delegate = GetDelegate(endpoint); + + if (delegate == nullptr) + { + ChipLogError(Zcl, "Delegate is null"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } + + // Clear the timer, discard the changes and set PresetsEditable to false. + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::Success); } bool emberAfThermostatClusterCommitPresetsSchedulesRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::CommitPresetsSchedulesRequest::DecodableType & commandData) { - // TODO - return false; -} + EndpointId endpoint = commandPath.mEndpointId; + Delegate * delegate = GetDelegate(endpoint); -bool emberAfThermostatClusterSetTemperatureSetpointHoldPolicyCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::DecodableType & commandData) -{ - // TODO - return false; -} + if (delegate == nullptr) + { + ChipLogError(Zcl, "Delegate is null"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } -int16_t EnforceHeatingSetpointLimits(int16_t HeatingSetpoint, EndpointId endpoint) -{ - // Optional Mfg supplied limits - int16_t AbsMinHeatSetpointLimit = kDefaultAbsMinHeatSetpointLimit; - int16_t AbsMaxHeatSetpointLimit = kDefaultAbsMaxHeatSetpointLimit; + // If presets are not editable, return INVALID_IN_STATE. + if (!gThermostatAttrAccess.GetPresetsEditable(endpoint)) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } - // Optional User supplied limits - int16_t MinHeatSetpointLimit = kDefaultMinHeatSetpointLimit; - int16_t MaxHeatSetpointLimit = kDefaultMaxHeatSetpointLimit; + ScopedNodeId sourceNodeId = GetSourceScopedNodeId(commandObj); - // Attempt to read the setpoint limits - // Absmin/max are manufacturer limits - // min/max are user imposed min/max + // If the node id sending the CommitPresetsSchedulesRequest command is not the same as the one which send the + // StartPresetsSchedulesEditRequest, return UNSUPPORTED_ACCESS. + if (gThermostatAttrAccess.GetOriginatorScopedNodeId(endpoint) != sourceNodeId) + { + commandObj->AddStatus(commandPath, imcode::UnsupportedAccess); + return true; + } - // Note that the limits are initialized above per the spec limits - // if they are not present Get() will not update the value so the defaults are used - imcode status; + PresetStructWithOwnedMembers preset; + CHIP_ERROR err = CHIP_NO_ERROR; - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3724 - // behavior is not specified when Abs * values are not present and user values are present - // implemented behavior accepts the user values without regard to default Abs values. + // For each preset in the presets attribute, check that the matching preset in the pending presets list does not + // violate any spec constraints. + for (uint8_t i = 0; true; i++) + { + err = delegate->GetPresetAtIndex(i, preset); - // Per global matter data model policy - // if a attribute is not present then it's default shall be used. + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, + "emberAfThermostatClusterCommitPresetsSchedulesRequestCallback: GetPresetAtIndex failed with error " + "%" CHIP_ERROR_FORMAT, + err.Format()); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } - status = AbsMinHeatSetpointLimit::Get(endpoint, &AbsMinHeatSetpointLimit); - if (status != imcode::Success) - { - ChipLogError(Zcl, "Warning: AbsMinHeatSetpointLimit missing using default"); + bool found = MatchingPendingPresetExists(delegate, preset); + + // If a built in preset in the Presets attribute list is removed and not found in the pending presets list, return + // CONSTRAINT_ERROR. + if (IsBuiltIn(preset) && !found) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } } - status = AbsMaxHeatSetpointLimit::Get(endpoint, &AbsMaxHeatSetpointLimit); - if (status != imcode::Success) + // If there is an ActivePresetHandle set, find the preset in the pending presets list that matches the ActivePresetHandle + // attribute. If a preset is not found with the same presetHandle, return INVALID_IN_STATE. If there is no ActivePresetHandle + // attribute set, continue with other checks. + uint8_t buffer[kPresetHandleSize]; + MutableByteSpan activePresetHandle(buffer); + + err = delegate->GetActivePresetHandle(activePresetHandle); + + if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "Warning: AbsMaxHeatSetpointLimit missing using default"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); } - status = MinHeatSetpointLimit::Get(endpoint, &MinHeatSetpointLimit); - if (status != imcode::Success) + + if (!activePresetHandle.empty()) { - MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + uint8_t count = CountPresetsInPendingListWithPresetHandle(delegate, activePresetHandle); + if (count == 0) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } } - status = MaxHeatSetpointLimit::Get(endpoint, &MaxHeatSetpointLimit); - if (status != imcode::Success) + // For each preset in the pending presets list, check that the preset does not violate any spec constraints. + for (uint8_t i = 0; true; i++) { - MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; - } + PresetStructWithOwnedMembers pendingPreset; + err = delegate->GetPendingPresetAtIndex(i, pendingPreset); - // Make sure the user imposed limits are within the manufacturer imposed limits + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, + "emberAfThermostatClusterCommitPresetsSchedulesRequestCallback: GetPendingPresetAtIndex failed with error " + "%" CHIP_ERROR_FORMAT, + err.Format()); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3725 - // Spec does not specify the behavior is the requested setpoint exceeds the limit allowed - // This implementation clamps at the limit. + bool isPendingPresetWithNullPresetHandle = pendingPreset.GetPresetHandle().IsNull(); - // resolution of 3725 is to clamp. + // If the preset handle is null and the built in field is set to true, return CONSTRAINT_ERROR. + if (isPendingPresetWithNullPresetHandle && IsBuiltIn(pendingPreset)) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } - if (MinHeatSetpointLimit < AbsMinHeatSetpointLimit) - MinHeatSetpointLimit = AbsMinHeatSetpointLimit; + bool foundMatchingPresetInPresets = false; + PresetStructWithOwnedMembers matchingPreset; + if (!isPendingPresetWithNullPresetHandle) + { + foundMatchingPresetInPresets = GetMatchingPresetInPresets(delegate, pendingPreset, matchingPreset); - if (MaxHeatSetpointLimit > AbsMaxHeatSetpointLimit) - MaxHeatSetpointLimit = AbsMaxHeatSetpointLimit; + // If the presetHandle for the pending preset is not null and a matching preset is not found in the + // presets attribute list, return NOT_FOUND. + if (!foundMatchingPresetInPresets) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::NotFound); + } - if (HeatingSetpoint < MinHeatSetpointLimit) - HeatingSetpoint = MinHeatSetpointLimit; + // Find the number of presets in the pending preset list that match the preset handle. If there are duplicate + // entries, return CONSTRAINT_ERROR. + uint8_t count = CountPresetsInPendingListWithPresetHandle(delegate, pendingPreset.GetPresetHandle().Value()); + if (count > 1) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } + } - if (HeatingSetpoint > MaxHeatSetpointLimit) - HeatingSetpoint = MaxHeatSetpointLimit; + // If the preset is found in the presets attribute list and the preset is builtIn in the pending presets list + // but not in the presets attribute list, return UNSUPPORTED_ACCESS. + if (foundMatchingPresetInPresets && (IsBuiltIn(pendingPreset) && !IsBuiltIn(matchingPreset))) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::UnsupportedAccess); + } - return HeatingSetpoint; -} + // If the preset is found in the presets attribute list and the preset is builtIn in the presets attribute + // but not in the pending presets list, return UNSUPPORTED_ACCESS. + if (foundMatchingPresetInPresets && (!IsBuiltIn(pendingPreset) && IsBuiltIn(matchingPreset))) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::UnsupportedAccess); + } -int16_t EnforceCoolingSetpointLimits(int16_t CoolingSetpoint, EndpointId endpoint) -{ - // Optional Mfg supplied limits - int16_t AbsMinCoolSetpointLimit = kDefaultAbsMinCoolSetpointLimit; - int16_t AbsMaxCoolSetpointLimit = kDefaultAbsMaxCoolSetpointLimit; + // If the presetScenario is not found in the preset types, return CONSTRAINT_ERROR. + PresetScenarioEnum presetScenario = pendingPreset.GetPresetScenario(); + if (!PresetScenarioExistsInPresetTypes(delegate, presetScenario)) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } - // Optional User supplied limits - int16_t MinCoolSetpointLimit = kDefaultMinCoolSetpointLimit; - int16_t MaxCoolSetpointLimit = kDefaultMaxCoolSetpointLimit; + // If the preset type for the preset scenario does not support names and a name is specified, return CONSTRAINT_ERROR. + if (!PresetTypeSupportsNames(delegate, presetScenario) && pendingPreset.GetName().HasValue()) + { + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ConstraintError); + } - // Attempt to read the setpoint limits - // Absmin/max are manufacturer limits - // min/max are user imposed min/max + // Enforce the Setpoint Limits for both the cooling and heating setpoints in the pending preset. + Optional coolingSetpointValue = pendingPreset.GetCoolingSetpoint(); + if (coolingSetpointValue.HasValue()) + { + pendingPreset.SetCoolingSetpoint(MakeOptional(EnforceCoolingSetpointLimits(coolingSetpointValue.Value(), endpoint))); + } - // Note that the limits are initialized above per the spec limits - // if they are not present Get() will not update the value so the defaults are used - imcode status; + Optional heatingSetpointValue = pendingPreset.GetHeatingSetpoint(); + if (heatingSetpointValue.HasValue()) + { + pendingPreset.SetHeatingSetpoint(MakeOptional(EnforceHeatingSetpointLimits(heatingSetpointValue.Value(), endpoint))); + } + } - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3724 - // behavior is not specified when Abs * values are not present and user values are present - // implemented behavior accepts the user values without regard to default Abs values. + uint8_t totalCount = CountUpdatedPresetsAfterApplyingPendingPresets(delegate); - // Per global matter data model policy - // if a attribute is not present then it's default shall be used. + uint8_t numberOfPresetsSupported = delegate->GetNumberOfPresets(); - status = AbsMinCoolSetpointLimit::Get(endpoint, &AbsMinCoolSetpointLimit); - if (status != imcode::Success) + if (numberOfPresetsSupported == 0) { - ChipLogError(Zcl, "Warning: AbsMinCoolSetpointLimit missing using default"); + ChipLogError(Zcl, "emberAfThermostatClusterCommitPresetsSchedulesRequestCallback: Failed to get NumberOfPresets"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); } - status = AbsMaxCoolSetpointLimit::Get(endpoint, &AbsMaxCoolSetpointLimit); - if (status != imcode::Success) + // If the expected length of the presets attribute with the applied changes exceeds the total number of presets supported, + // return RESOURCE_EXHAUSTED. Note that the changes are not yet applied. + if (numberOfPresetsSupported > 0 && totalCount > numberOfPresetsSupported) { - ChipLogError(Zcl, "Warning: AbsMaxCoolSetpointLimit missing using default"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::ResourceExhausted); } - status = MinCoolSetpointLimit::Get(endpoint, &MinCoolSetpointLimit); - if (status != imcode::Success) - { - MinCoolSetpointLimit = AbsMinCoolSetpointLimit; - } + // TODO: Check if the number of presets for each presetScenario exceeds the max number of presets supported for that + // scenario. We plan to support only one preset for each presetScenario for our use cases so defer this for re-evaluation. - status = MaxCoolSetpointLimit::Get(endpoint, &MaxCoolSetpointLimit); - if (status != imcode::Success) + // Call the delegate API to apply the pending presets to the presets attribute and update it. + err = delegate->ApplyPendingPresets(); + + if (err != CHIP_NO_ERROR) { - MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); } - // Make sure the user imposed limits are within the manufacture imposed limits - // https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/3725 - // Spec does not specify the behavior is the requested setpoint exceeds the limit allowed - // This implementation clamps at the limit. - - // resolution of 3725 is to clamp. - - if (MinCoolSetpointLimit < AbsMinCoolSetpointLimit) - MinCoolSetpointLimit = AbsMinCoolSetpointLimit; - - if (MaxCoolSetpointLimit > AbsMaxCoolSetpointLimit) - MaxCoolSetpointLimit = AbsMaxCoolSetpointLimit; - - if (CoolingSetpoint < MinCoolSetpointLimit) - CoolingSetpoint = MinCoolSetpointLimit; - - if (CoolingSetpoint > MaxCoolSetpointLimit) - CoolingSetpoint = MaxCoolSetpointLimit; - - return CoolingSetpoint; + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::Success); } bool emberAfThermostatClusterSetpointRaiseLowerCallback(app::CommandHandler * commandObj, diff --git a/src/app/clusters/thermostat-server/thermostat-server.h b/src/app/clusters/thermostat-server/thermostat-server.h new file mode 100644 index 00000000000000..955ab9e5c5a777 --- /dev/null +++ b/src/app/clusters/thermostat-server/thermostat-server.h @@ -0,0 +1,103 @@ +/** + * + * 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. + */ + +/**************************************************************************** + * @file + * @brief APIs for the Thermostat cluster. + * + ******************************************************************************* + ******************************************************************************/ + +#pragma once + +#include "thermostat-delegate.h" + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace Thermostat { + +static constexpr size_t kThermostatEndpointCount = + MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; + +/** + * @brief Thermostat Attribute Access Interface. + */ +class ThermostatAttrAccess : public chip::app::AttributeAccessInterface +{ +public: + ThermostatAttrAccess() : AttributeAccessInterface(Optional::Missing(), Thermostat::Id) {} + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, chip::app::AttributeValueDecoder & aDecoder) override; + + /** + * @brief Sets the scoped node id of the originator that send the last successful + * StartPresetsSchedulesEditRequest for the given endpoint. + * + * @param[in] endpoint The endpoint. + * @param[in] originatorNodeId The originator scoped node id. + */ + void SetOriginatorScopedNodeId(EndpointId endpoint, ScopedNodeId originatorNodeId); + + /** + * @brief Gets the scoped node id of the originator that send the last successful + * StartPresetsSchedulesEditRequest for the given endpoint. + * + * @param[in] endpoint The endpoint. + * + * @return the scoped node id for the given endpoint if set. Otherwise returns ScopedNodeId(). + */ + ScopedNodeId GetOriginatorScopedNodeId(EndpointId endpoint); + + /** + * @brief Sets the presets editable flag for the given endpoint + * + * @param[in] endpoint The endpoint. + * @param[in] presetEditable The value of the presets editable. + */ + void SetPresetsEditable(EndpointId endpoint, bool presetEditable); + + /** + * @brief Gets the prests editable flag value for the given endpoint + * + * @param[in] endpoint The endpoint. + * + * @return the presets editable flag value for the given endpoint if set. Otherwise returns false. + */ + bool GetPresetsEditable(EndpointId endpoint); + +private: + ScopedNodeId mPresetEditRequestOriginatorNodeIds[kThermostatEndpointCount]; + + bool mPresetsEditables[kThermostatEndpointCount]; +}; + +/** + * @brief Sets the default delegate for the specific thermostat features. + * + * @param[in] endpoint The endpoint to set the default delegate on. + * @param[in] delegate The default delegate. + */ +void SetDefaultDelegate(EndpointId endpoint, Delegate * delegate); + +} // namespace Thermostat +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp b/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp new file mode 100644 index 00000000000000..5592da410100c2 --- /dev/null +++ b/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp @@ -0,0 +1,357 @@ +/* + * + * 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 "thread-border-router-management-server.h" + +#include "app-common/zap-generated/cluster-objects.h" +#include "app-common/zap-generated/ids/Attributes.h" +#include "app-common/zap-generated/ids/Clusters.h" +#include "app-common/zap-generated/ids/Commands.h" +#include "app/AttributeAccessInterfaceRegistry.h" +#include "app/AttributeValueEncoder.h" +#include "app/CommandHandler.h" +#include "app/CommandHandlerInterface.h" +#include "app/CommandHandlerInterfaceRegistry.h" +#include "app/InteractionModelEngine.h" +#include "app/MessageDef/StatusIB.h" +#include "app/clusters/general-commissioning-server/general-commissioning-server.h" +#include "app/data-model/Nullable.h" +#include "lib/core/CHIPError.h" +#include "lib/core/Optional.h" +#include "lib/support/CodeUtils.h" +#include "lib/support/Span.h" +#include "lib/support/ThreadOperationalDataset.h" +#include "platform/CHIPDeviceEvent.h" +#include "platform/PlatformManager.h" +#include "protocols/interaction_model/StatusCode.h" + +namespace chip { +namespace app { +namespace Clusters { +namespace ThreadBorderRouterManagement { + +using Protocols::InteractionModel::Status; + +static bool IsCommandOverCASESession(CommandHandlerInterface::HandlerContext & ctx) +{ + Messaging::ExchangeContext * exchangeCtx = ctx.mCommandHandler.GetExchangeContext(); + return exchangeCtx && exchangeCtx->HasSessionHandle() && exchangeCtx->GetSessionHandle()->IsSecureSession() && + exchangeCtx->GetSessionHandle()->AsSecureSession()->GetSecureSessionType() == Transport::SecureSession::Type::kCASE; +} + +Status ServerInstance::HandleGetDatasetRequest(bool isOverCASESession, Delegate::DatasetType type, + Thread::OperationalDataset & dataset) +{ + VerifyOrDie(mDelegate); + if (!isOverCASESession) + { + return Status::UnsupportedAccess; + } + + CHIP_ERROR err = mDelegate->GetDataset(dataset, type); + if (err != CHIP_NO_ERROR) + { + return err == CHIP_IM_GLOBAL_STATUS(NotFound) ? StatusIB(err).mStatus : Status::Failure; + } + return Status::Success; +} + +Status ServerInstance::HandleSetActiveDatasetRequest(CommandHandler * commandHandler, + const Commands::SetActiveDatasetRequest::DecodableType & req) +{ + // The SetActiveDatasetRequest command SHALL be FailSafeArmed. Upon receiving this command, the Thread BR will set its + // active dataset. If the dataset is set successfully, OnActivateDatasetComplete will be called with CHIP_NO_ERROR, prompting + // the Thread BR to respond with a success status. If an error occurs while setting the active dataset, the Thread BR should + // respond with a failure status. In this case, when the FailSafe timer expires, the active dataset set by this command will be + // reverted. If the FailSafe timer expires before the Thread BR responds, the Thread BR will respond with a timeout status and + // the active dataset should also be reverted. + VerifyOrDie(mDelegate); + VerifyOrReturnValue(mFailsafeContext.IsFailSafeArmed(commandHandler->GetAccessingFabricIndex()), Status::FailsafeRequired); + + Thread::OperationalDataset activeDataset; + Thread::OperationalDataset currentActiveDataset; + uint64_t currentActiveDatasetTimestamp = 0; + // If any of the parameters in the ActiveDataset is invalid, the command SHALL fail with a status code + // of INVALID_COMMAND. + VerifyOrReturnValue(activeDataset.Init(req.activeDataset) == CHIP_NO_ERROR, Status::InvalidCommand); + + // If this command is invoked when the ActiveDatasetTimestamp attribute is not null, the command SHALL + // fail with a status code of INVALID_IN_STATE. + if ((mDelegate->GetDataset(currentActiveDataset, Delegate::DatasetType::kActive) == CHIP_NO_ERROR) && + (currentActiveDataset.GetActiveTimestamp(currentActiveDatasetTimestamp) == CHIP_NO_ERROR)) + { + return Status::InvalidInState; + } + // If there is a back end command process, return status BUSY. + if (mAsyncCommandHandle.Get()) + { + return Status::Busy; + } + commandHandler->FlushAcksRightAwayOnSlowCommand(); + mAsyncCommandHandle = CommandHandler::Handle(commandHandler); + mBreadcrumb = req.breadcrumb; + mSetActiveDatasetSequenceNumber++; + mDelegate->SetActiveDataset(activeDataset, mSetActiveDatasetSequenceNumber, this); + return Status::Success; +} + +Status ServerInstance::HandleSetPendingDatasetRequest(const Commands::SetPendingDatasetRequest::DecodableType & req) +{ + VerifyOrDie(mDelegate); + if (!mDelegate->GetPanChangeSupported()) + { + return Status::UnsupportedCommand; + } + Thread::OperationalDataset pendingDataset; + // If any of the parameters in the PendingDataset is invalid, the command SHALL fail with a status code + // of INVALID_COMMAND. + ReturnErrorCodeIf(pendingDataset.Init(req.pendingDataset) != CHIP_NO_ERROR, Status::InvalidCommand); + CHIP_ERROR err = mDelegate->SetPendingDataset(pendingDataset); + return StatusIB(err).mStatus; +} + +void AddDatasetResponse(CommandHandlerInterface::HandlerContext & ctx, Status status, const Thread::OperationalDataset & dataset) +{ + if (status != Status::Success) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); + return; + } + Commands::DatasetResponse::Type response; + response.dataset = dataset.AsByteSpan(); + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); +} + +void ServerInstance::InvokeCommand(HandlerContext & ctxt) +{ + switch (ctxt.mRequestPath.mCommandId) + { + case Commands::GetActiveDatasetRequest::Id: + HandleCommand(ctxt, [this](HandlerContext & ctx, const auto & req) { + Thread::OperationalDataset dataset; + Status status = HandleGetActiveDatasetRequest(IsCommandOverCASESession(ctx), dataset); + AddDatasetResponse(ctx, status, dataset); + }); + break; + case Commands::GetPendingDatasetRequest::Id: + HandleCommand(ctxt, [this](HandlerContext & ctx, const auto & req) { + Thread::OperationalDataset dataset; + Status status = HandleGetPendingDatasetRequest(IsCommandOverCASESession(ctx), dataset); + AddDatasetResponse(ctx, status, dataset); + }); + break; + case Commands::SetActiveDatasetRequest::Id: + HandleCommand(ctxt, [this](HandlerContext & ctx, const auto & req) { + mPath = ctx.mRequestPath; + Status status = HandleSetActiveDatasetRequest(&ctx.mCommandHandler, req); + if (status != Status::Success) + { + // If status is not Success, we should immediately report the status. Otherwise the async work will report the + // status to the client. + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); + } + }); + break; + case Commands::SetPendingDatasetRequest::Id: + HandleCommand(ctxt, [this](HandlerContext & ctx, const auto & req) { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, HandleSetPendingDatasetRequest(req)); + }); + break; + default: + break; + } +} + +void ServerInstance::ReadFeatureMap(BitFlags & outFeatureMap) +{ + if (mDelegate->GetPanChangeSupported()) + { + outFeatureMap.Set(Feature::kPANChange); + } +} + +CHIP_ERROR ServerInstance::ReadBorderRouterName(MutableCharSpan & outBorderRouterName) +{ + mDelegate->GetBorderRouterName(outBorderRouterName); + VerifyOrReturnValue(outBorderRouterName.size() <= kBorderRouterNameMaxLength, CHIP_IM_GLOBAL_STATUS(Failure)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ServerInstance::ReadBorderAgentID(MutableByteSpan & outBorderAgentId) +{ + VerifyOrReturnValue((mDelegate->GetBorderAgentId(outBorderAgentId) == CHIP_NO_ERROR) && + (outBorderAgentId.size() == kBorderAgentIdLength), + CHIP_IM_GLOBAL_STATUS(Failure)); + return CHIP_NO_ERROR; +} + +Optional ServerInstance::ReadActiveDatasetTimestamp() +{ + uint64_t activeDatasetTimestampValue = 0; + Thread::OperationalDataset activeDataset; + if ((mDelegate->GetDataset(activeDataset, Delegate::DatasetType::kActive) == CHIP_NO_ERROR) && + (activeDataset.GetActiveTimestamp(activeDatasetTimestampValue) == CHIP_NO_ERROR)) + { + return MakeOptional(activeDatasetTimestampValue); + } + return NullOptional; +} + +CHIP_ERROR ServerInstance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + if (aPath.mClusterId != ThreadBorderRouterManagement::Id) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + VerifyOrDie(mDelegate); + CHIP_ERROR status = CHIP_NO_ERROR; + switch (aPath.mAttributeId) + { + case Globals::Attributes::FeatureMap::Id: { + BitFlags featureMap; + ReadFeatureMap(featureMap); + status = aEncoder.Encode(featureMap); + break; + } + case Attributes::BorderRouterName::Id: { + char borderRouterNameBuf[kBorderRouterNameMaxLength] = { 0 }; + MutableCharSpan borderRouterName(borderRouterNameBuf); + status = ReadBorderRouterName(borderRouterName); + // If there are any internal errors, the status will be returned and the client will get an error report. + if (status == CHIP_NO_ERROR) + { + status = aEncoder.Encode(borderRouterName); + } + break; + } + case Attributes::BorderAgentID::Id: { + uint8_t borderAgentIDBuf[kBorderAgentIdLength] = { 0 }; + MutableByteSpan borderAgentID(borderAgentIDBuf); + status = ReadBorderAgentID(borderAgentID); + if (status == CHIP_NO_ERROR) + { + status = aEncoder.Encode(borderAgentID); + } + break; + } + case Attributes::ThreadVersion::Id: { + uint16_t threadVersion = mDelegate->GetThreadVersion(); + status = aEncoder.Encode(threadVersion); + break; + } + case Attributes::InterfaceEnabled::Id: { + bool interfaceEnabled = mDelegate->GetInterfaceEnabled(); + status = aEncoder.Encode(interfaceEnabled); + break; + } + case Attributes::ActiveDatasetTimestamp::Id: { + Optional activeDatasetTimestamp = ReadActiveDatasetTimestamp(); + status = activeDatasetTimestamp.HasValue() ? aEncoder.Encode(DataModel::MakeNullable(activeDatasetTimestamp.Value())) + : aEncoder.EncodeNull(); + break; + } + default: + break; + } + return status; +} + +void ServerInstance::CommitSavedBreadcrumb() +{ + if (mBreadcrumb.HasValue()) + { + GeneralCommissioning::SetBreadcrumb(mBreadcrumb.Value()); + } + mBreadcrumb.ClearValue(); +} + +void ServerInstance::OnActivateDatasetComplete(uint32_t sequenceNum, CHIP_ERROR error) +{ + auto commandHandleRef = std::move(mAsyncCommandHandle); + auto commandHandle = commandHandleRef.Get(); + if (commandHandle == nullptr) + { + return; + } + if (mSetActiveDatasetSequenceNumber != sequenceNum) + { + // Previous SetActiveDatasetRequest was handled. + return; + } + if (error == CHIP_NO_ERROR) + { + // TODO: SPEC Issue #10022 + CommitSavedBreadcrumb(); + } + else + { + ChipLogError(Zcl, "Failed on activating the active dataset for Thread BR: %" CHIP_ERROR_FORMAT, error.Format()); + } + commandHandle->AddStatus(mPath, StatusIB(error).mStatus); +} + +void ServerInstance::ReportAttributeChanged(AttributeId attributeId) +{ + MatterReportingAttributeChangeCallback(mServerEndpointId, Id, attributeId); +} + +void ServerInstance::OnFailSafeTimerExpired() +{ + if (mDelegate) + { + mDelegate->RevertActiveDataset(); + } + auto commandHandleRef = std::move(mAsyncCommandHandle); + auto commandHandle = commandHandleRef.Get(); + if (commandHandle == nullptr) + { + return; + } + commandHandle->AddStatus(mPath, Status::Timeout); +} + +void ServerInstance::OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) +{ + ServerInstance * _this = reinterpret_cast(arg); + if (event->Type == DeviceLayer::DeviceEventType::kFailSafeTimerExpired) + { + _this->OnFailSafeTimerExpired(); + } + else if (event->Type == DeviceLayer::DeviceEventType::kCommissioningComplete) + { + _this->mDelegate->CommitActiveDataset(); + } +} + +CHIP_ERROR ServerInstance::Init() +{ + ReturnErrorCodeIf(!mDelegate, CHIP_ERROR_INVALID_ARGUMENT); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); + VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); + ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(OnPlatformEventHandler, reinterpret_cast(this))); + return mDelegate->Init(this); +} + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip + +void MatterThreadBorderRouterManagementPluginServerInitCallback() +{ + // Nothing to do, the server init routine will be done in Instance::Init() +} diff --git a/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.h b/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.h new file mode 100644 index 00000000000000..a2b6d7949ffdff --- /dev/null +++ b/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.h @@ -0,0 +1,106 @@ +/* + * + * 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. + */ + +#pragma once + +#include "thread-br-delegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ThreadBorderRouterManagement { + +class ServerInstance : public CommandHandlerInterface, + public AttributeAccessInterface, + public Delegate::ActivateDatasetCallback, + public Delegate::AttributeChangeCallback +{ +public: + using Status = Protocols::InteractionModel::Status; + ServerInstance(EndpointId endpointId, Delegate * delegate, FailSafeContext & failSafeContext) : + CommandHandlerInterface(Optional(endpointId), Id), + AttributeAccessInterface(Optional(endpointId), Id), mDelegate(delegate), mServerEndpointId(endpointId), + mFailsafeContext(failSafeContext) + {} + virtual ~ServerInstance() = default; + + CHIP_ERROR Init(); + + // CommandHanlerInterface + void InvokeCommand(HandlerContext & ctx) override; + + // AttributeAccessInterface + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + + // ActivateDatasetCallback + void OnActivateDatasetComplete(uint32_t sequenceNum, CHIP_ERROR error) override; + + // AttributeChangeCallback + void ReportAttributeChanged(AttributeId attributeId) override; + +private: + // TODO: Split the business logic from the unit test class + friend class TestThreadBorderRouterManagementCluster; + // Command Handlers + Status HandleGetActiveDatasetRequest(bool isOverCASESession, Thread::OperationalDataset & dataset) + { + return HandleGetDatasetRequest(isOverCASESession, Delegate::DatasetType::kActive, dataset); + } + Status HandleGetPendingDatasetRequest(bool isOverCASESession, Thread::OperationalDataset & dataset) + { + return HandleGetDatasetRequest(isOverCASESession, Delegate::DatasetType::kPending, dataset); + } + Status HandleSetActiveDatasetRequest(CommandHandler * commandHandler, + const Commands::SetActiveDatasetRequest::DecodableType & req); + Status HandleSetPendingDatasetRequest(const Commands::SetPendingDatasetRequest::DecodableType & req); + Status HandleGetDatasetRequest(bool isOverCASESession, Delegate::DatasetType type, Thread::OperationalDataset & dataset); + + // Attribute Read handlers + void ReadFeatureMap(BitFlags & feature); + Optional ReadActiveDatasetTimestamp(); + CHIP_ERROR ReadBorderRouterName(MutableCharSpan & borderRouterName); + CHIP_ERROR ReadBorderAgentID(MutableByteSpan & borderAgentId); + + static void OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + void OnFailSafeTimerExpired(); + void CommitSavedBreadcrumb(); + + Delegate * mDelegate; + app::CommandHandler::Handle mAsyncCommandHandle; + ConcreteCommandPath mPath = ConcreteCommandPath(0, 0, 0); + Optional mBreadcrumb; + uint32_t mSetActiveDatasetSequenceNumber = 0; + EndpointId mServerEndpointId; + FailSafeContext & mFailsafeContext; +}; + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h b/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h new file mode 100644 index 00000000000000..201540af96ecff --- /dev/null +++ b/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h @@ -0,0 +1,115 @@ +/* + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace ThreadBorderRouterManagement { + +constexpr size_t kBorderRouterNameMaxLength = 63; +constexpr size_t kBorderAgentIdLength = 16; + +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + class ActivateDatasetCallback + { + public: + ActivateDatasetCallback() = default; + virtual ~ActivateDatasetCallback() = default; + // If the dataset is set successfully, OnActivateDatasetComplete should be called with CHIP_NO_ERROR when the + // Border Router is attached to the Thread network. + // If an error occurs while setting the active dataset, this callback should be called with the error. + // The error input of this function could be SDK-range error for CHIP error or OpenThread-range error for Thread error. + virtual void OnActivateDatasetComplete(uint32_t sequenceNum, CHIP_ERROR error) = 0; + }; + + class AttributeChangeCallback + { + public: + AttributeChangeCallback() = default; + virtual ~AttributeChangeCallback() = default; + // If the attributes of the Thread Border Router Management is changed, ReportAttributeChanged should be called. + virtual void ReportAttributeChanged(AttributeId attributeId) = 0; + }; + + enum class DatasetType : uint8_t + { + kActive, + kPending, + }; + + virtual CHIP_ERROR Init(AttributeChangeCallback * attributeChangeCallback) = 0; + + // Get whether PanChange feature is supported for the Thread BR. + virtual bool GetPanChangeSupported() = 0; + + // Get the BorderRouterName of the Thread BR, which will also be the service name of Thread BR's MeshCOP service. + virtual void GetBorderRouterName(MutableCharSpan & borderRouterName) = 0; + + // Get the BorderAgentId of the Thread BR. + // @return + // -IncorrectState When Thread stack is not initialized. + // -InvalidArgument When the size of borderAgentId is not 16 bytes. + // -ThreadErrors When failing to get BorderAgentId. + virtual CHIP_ERROR GetBorderAgentId(MutableByteSpan & borderAgentId) = 0; + + // Get the Thread version which matches the value mapping defined in the "Version TLV" section of the Thread specification. + virtual uint16_t GetThreadVersion() = 0; + + // Get whether the associated IEEE 802.15.4 Thread interface is enabled or disabled. + virtual bool GetInterfaceEnabled() = 0; + + // Get the active dataset or the pending dataset. + // @return + // -IncorrectState When Thread stack is not initialized. + // -NotFound when failing to get the dataset. + virtual CHIP_ERROR GetDataset(Thread::OperationalDataset & dataset, DatasetType type) = 0; + + // There should be no active dataset configured when calling this API, otherwise we should use SetPendingDataset. + // The Delegate implementation must store the sequence number and pass it to OnActivateDatasetComplete. + virtual void SetActiveDataset(const Thread::OperationalDataset & activeDataset, uint32_t sequenceNum, + ActivateDatasetCallback * callback) = 0; + + // This function will check save whether there is active dataset configured. + virtual CHIP_ERROR CommitActiveDataset() = 0; + + // The function is called when Failsafe timer is triggered or when the Border Router reboots with a previous Failsafe timer + // started but not disarmed before reboot. The delegate implementation should check whether there is a previous SetActiveDataset + // request and revert the active dataset set by the previous SetActiveDataset. Since there should be no configured dataset when + // calling SetActiveDataset, this function will clear the active dataset to allow trying again a new SetActiveDataset operation. + // The delegate is allowed to call OnActivateDatasetComplete for the previous SetActiveDataset request even after this function + // is called as the sequence number passed to OnActivateDatasetComplete will be different. + virtual CHIP_ERROR RevertActiveDataset() = 0; + + virtual CHIP_ERROR SetPendingDataset(const Thread::OperationalDataset & pendingDataset) = 0; +}; + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/thread-network-directory-server/thread-network-directory-server.cpp b/src/app/clusters/thread-network-directory-server/thread-network-directory-server.cpp index d1f3de7c58bbc8..384686693b0a69 100644 --- a/src/app/clusters/thread-network-directory-server/thread-network-directory-server.cpp +++ b/src/app/clusters/thread-network-directory-server/thread-network-directory-server.cpp @@ -274,8 +274,10 @@ void ThreadNetworkDirectoryServer::HandleOperationalDatasetRequest( uint8_t datasetBuffer[kSizeOperationalDataset]; MutableByteSpan datasetSpan(datasetBuffer); + OperationalDatasetResponse::Type response; SuccessOrExit(err = mStorage.GetNetworkDataset(ExtendedPanId(req.extendedPanID), datasetSpan)); - ctx.mCommandHandler.AddStatus(ctx.mRequestPath, IMStatus::Success); + response.operationalDataset = datasetSpan; + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); return; exit: ChipLogError(Zcl, "GetOperationalDataset: %" CHIP_ERROR_FORMAT, err.Format()); diff --git a/src/app/clusters/water-heater-management-server/water-heater-management-server.cpp b/src/app/clusters/water-heater-management-server/water-heater-management-server.cpp index 447a6646766452..6af249370e8fb8 100644 --- a/src/app/clusters/water-heater-management-server/water-heater-management-server.cpp +++ b/src/app/clusters/water-heater-management-server/water-heater-management-server.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -39,7 +40,7 @@ constexpr uint16_t kClusterRevision = 1; CHIP_ERROR Instance::Init() { - ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; @@ -47,7 +48,7 @@ CHIP_ERROR Instance::Init() void Instance::Shutdown() { - InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); unregisterAttributeAccessOverride(this); } diff --git a/src/app/clusters/wifi-network-management-server/wifi-network-management-server.cpp b/src/app/clusters/wifi-network-management-server/wifi-network-management-server.cpp index f99ccdf5aafad3..43048498602ff8 100644 --- a/src/app/clusters/wifi-network-management-server/wifi-network-management-server.cpp +++ b/src/app/clusters/wifi-network-management-server/wifi-network-management-server.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -99,11 +100,20 @@ CHIP_ERROR WiFiNetworkManagementServer::SetNetworkCredentials(ByteSpan ssid, Byt VerifyOrDie(mPassphrase.SetLength(passphrase.size()) == CHIP_NO_ERROR); memcpy(mPassphrase.Bytes(), passphrase.data(), passphrase.size()); - // Note: The spec currently defines no way to signal a passphrase change if (ssidChanged) { MatterReportingAttributeChangeCallback(GetEndpointId(), WiFiNetworkManagement::Id, Ssid::Id); } + if (passphraseChanged) + { + mPassphraseSurrogate++; + System::Clock::Milliseconds64 realtime; + if (System::SystemClock().GetClock_RealTimeMS(realtime) == CHIP_NO_ERROR) + { + mPassphraseSurrogate = std::max(mPassphraseSurrogate, realtime.count()); + } + MatterReportingAttributeChangeCallback(GetEndpointId(), WiFiNetworkManagement::Id, PassphraseSurrogate::Id); + } return CHIP_NO_ERROR; } @@ -113,6 +123,8 @@ CHIP_ERROR WiFiNetworkManagementServer::Read(const ConcreteReadAttributePath & a { case Ssid::Id: return HaveNetworkCredentials() ? aEncoder.Encode(SsidSpan()) : aEncoder.EncodeNull(); + case PassphraseSurrogate::Id: + return HaveNetworkCredentials() ? aEncoder.Encode(mPassphraseSurrogate) : aEncoder.EncodeNull(); } return CHIP_NO_ERROR; } diff --git a/src/app/clusters/wifi-network-management-server/wifi-network-management-server.h b/src/app/clusters/wifi-network-management-server/wifi-network-management-server.h index ce438edf79ff73..c538c585e74899 100644 --- a/src/app/clusters/wifi-network-management-server/wifi-network-management-server.h +++ b/src/app/clusters/wifi-network-management-server/wifi-network-management-server.h @@ -57,6 +57,7 @@ class WiFiNetworkManagementServer : private AttributeAccessInterface, private Co static_assert(std::numeric_limits::max() >= sizeof(mSsid)); ByteSpan SsidSpan() const { return ByteSpan(mSsid, mSsidLen); } + uint64_t mPassphraseSurrogate = 0; Crypto::SensitiveDataBuffer<64> mPassphrase; ByteSpan PassphraseSpan() const { return mPassphrase.Span(); } diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index a3ae2dc621fd03..d8d276f53a0700 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -24,6 +24,7 @@ CommandHandlerInterfaceOnlyClusters: - Scenes Management - RVC Run Mode - RVC Clean Mode + - Service Area - Dishwasher Mode - Laundry Washer Mode - Oven Mode @@ -42,7 +43,9 @@ CommandHandlerInterfaceOnlyClusters: - Electrical Power Measurement - Electrical Energy Measurement - Wi-Fi Network Management + - Thread Border Router Management - Thread Network Directory + - Water Heater Management - Water Heater Mode # We need a more configurable way of deciding which clusters have which init functions.... diff --git a/src/app/server/CommissioningWindowManager.cpp b/src/app/server/CommissioningWindowManager.cpp index 229fd67c5bb24b..47bc3e8ff97f07 100644 --- a/src/app/server/CommissioningWindowManager.cpp +++ b/src/app/server/CommissioningWindowManager.cpp @@ -71,6 +71,12 @@ void CommissioningWindowManager::OnPlatformEvent(const DeviceLayer::ChipDeviceEv #if CONFIG_NETWORK_LAYER_BLE && CHIP_DEVICE_CONFIG_SUPPORTS_CONCURRENT_CONNECTION // If in NonConcurrentConnection, this will already have been completed mServer->GetBleLayerObject()->CloseAllBleConnections(); +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + DeviceLayer::ConnectivityManager::WiFiPAFAdvertiseParam args; + args.enable = false; + args.ExtCmds = nullptr; + DeviceLayer::ConnectivityMgr().SetWiFiPAFAdvertisingEnabled(args); #endif } else if (event->Type == DeviceLayer::DeviceEventType::kFailSafeTimerExpired) diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index 33f657f7ec1030..22cd274ba87e39 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -56,6 +56,10 @@ #include #include +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#include +#endif + #if defined(CHIP_SUPPORT_ENABLE_STORAGE_API_AUDIT) || defined(CHIP_SUPPORT_ENABLE_STORAGE_LOAD_TEST_AUDIT) #include #endif // defined(CHIP_SUPPORT_ENABLE_STORAGE_API_AUDIT) || defined(CHIP_SUPPORT_ENABLE_STORAGE_LOAD_TEST_AUDIT) @@ -214,6 +218,10 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) TcpListenParameters(DeviceLayer::TCPEndPointManager()) .SetAddressType(IPAddressType::kIPv6) .SetListenPort(mOperationalServicePort) +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + , + Transport::WiFiPAFListenParameters(DeviceLayer::ConnectivityMgr().GetWiFiPAF()) #endif ); diff --git a/src/app/server/Server.h b/src/app/server/Server.h index 9e0216877fea61..2f6126a4ace635 100644 --- a/src/app/server/Server.h +++ b/src/app/server/Server.h @@ -65,6 +65,9 @@ #if CONFIG_NETWORK_LAYER_BLE #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#include +#endif #include #include #include @@ -104,6 +107,10 @@ using ServerTransportMgr = chip::TransportMgr +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + , + chip::Transport::WiFiPAFBase #endif >; diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 59d8f2c325fd8c..e600fbeb3f1987 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -139,6 +139,17 @@ source_set("operational-state-test-srcs") { ] } +source_set("thread-border-router-management-test-srcs") { + sources = [ "${chip_root}/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp" ] + + public_deps = [ + "${chip_root}/src/app", + "${chip_root}/src/app/common:cluster-objects", + "${chip_root}/src/app/util/mock:mock_ember", + "${chip_root}/src/lib/core", + ] +} + source_set("app-test-stubs") { sources = [ "test-ember-api.cpp", @@ -249,6 +260,9 @@ chip_test_suite("tests") { "${chip_root}/src/app/server", "${chip_root}/src/messaging/tests/echo:common", ] + } else if (!chip_fake_platform) { + test_sources += [ "TestThreadBorderRouterManagementCluster.cpp" ] + public_deps += [ ":thread-border-router-management-test-srcs" ] } if (!chip_fake_platform) { diff --git a/src/app/tests/TestThreadBorderRouterManagementCluster.cpp b/src/app/tests/TestThreadBorderRouterManagementCluster.cpp new file mode 100644 index 00000000000000..a6915824fb2ea2 --- /dev/null +++ b/src/app/tests/TestThreadBorderRouterManagementCluster.cpp @@ -0,0 +1,336 @@ +/* + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace GeneralCommissioning { +// Mock function +void SetBreadcrumb(Attributes::Breadcrumb::TypeInfo::Type breadcrumb) {} +} // namespace GeneralCommissioning + +namespace ThreadBorderRouterManagement { + +class TestDelegate : public Delegate +{ +public: + TestDelegate() = default; + ~TestDelegate() = default; + + CHIP_ERROR Init(AttributeChangeCallback * callback) override { return CHIP_NO_ERROR; } + + bool GetPanChangeSupported() override { return mPanChangeSupported; } + + void GetBorderRouterName(MutableCharSpan & borderRouterName) override + { + size_t nameIndex = mUseInvalidBorderRouterName ? 1 : 0; + if (borderRouterName.size() >= strlen(kTestName[nameIndex])) + { + CopyCharSpanToMutableCharSpan(CharSpan(kTestName[nameIndex], strlen(kTestName[nameIndex])), borderRouterName); + } + } + + CHIP_ERROR GetBorderAgentId(MutableByteSpan & borderAgentId) override + { + if (borderAgentId.size() >= mTestBorderAgentIdLen) + { + CopySpanToMutableSpan(ByteSpan(kTestBorderAgentId, mTestBorderAgentIdLen), borderAgentId); + return CHIP_NO_ERROR; + } + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + uint16_t GetThreadVersion() override { return kTestThreadVersion; } + + bool GetInterfaceEnabled() override { return mInterfaceEnabled; } + + CHIP_ERROR GetDataset(Thread::OperationalDataset & dataset, DatasetType type) override + { + if (type == DatasetType::kActive && mStoredActiveDatasetLen) + { + dataset.Init(ByteSpan(mStoredActiveDataset, mStoredActiveDatasetLen)); + return CHIP_NO_ERROR; + } + if (type == DatasetType::kPending && mPendingDatasetLen) + { + dataset.Init(ByteSpan(mPendingDataset, mPendingDatasetLen)); + return CHIP_NO_ERROR; + } + return CHIP_IM_GLOBAL_STATUS(NotFound); + } + + void SetActiveDataset(const Thread::OperationalDataset & activeDataset, uint32_t sequenceNumber, + ActivateDatasetCallback * callback) override + { + memcpy(mActiveDataset, activeDataset.AsByteSpan().data(), activeDataset.AsByteSpan().size()); + mActiveDatasetLen = activeDataset.AsByteSpan().size(); + mCallback = callback; + mSetActiveDatasetCommandSequenceNum = sequenceNumber; + } + + CHIP_ERROR CommitActiveDataset() override { return CHIP_NO_ERROR; } + + CHIP_ERROR RevertActiveDataset() override + { + mStoredActiveDatasetLen = 0; + mInterfaceEnabled = false; + mCallback = nullptr; + return CHIP_NO_ERROR; + } + + CHIP_ERROR SetPendingDataset(const Thread::OperationalDataset & pendingDataset) override + { + memcpy(mPendingDataset, pendingDataset.AsByteSpan().data(), pendingDataset.AsByteSpan().size()); + mPendingDatasetLen = pendingDataset.AsByteSpan().size(); + return CHIP_NO_ERROR; + } + + void ActivateActiveDataset() + { + memcpy(mStoredActiveDataset, mActiveDataset, Thread::kSizeOperationalDataset); + mStoredActiveDatasetLen = mActiveDatasetLen; + mInterfaceEnabled = true; + if (mCallback) + { + mCallback->OnActivateDatasetComplete(mSetActiveDatasetCommandSequenceNum, CHIP_NO_ERROR); + } + mCallback = nullptr; + } + + bool mPanChangeSupported = true; + const char * kTestName[2] = { "TestName", "TestNameLength64________________________________________________" }; + const uint8_t kTestBorderAgentId[kBorderAgentIdLength] = { 0x0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; + const uint16_t kTestThreadVersion = 4; + uint8_t mActiveDataset[Thread::kSizeOperationalDataset] = { 0 }; + size_t mActiveDatasetLen = 0; + uint8_t mStoredActiveDataset[Thread::kSizeOperationalDataset] = { 0 }; + size_t mStoredActiveDatasetLen = 0; + uint8_t mPendingDataset[Thread::kSizeOperationalDataset] = { 0 }; + size_t mPendingDatasetLen = 0; + bool mUseInvalidBorderRouterName = true; + size_t mTestBorderAgentIdLen = kBorderAgentIdLength - 1; + bool mInterfaceEnabled = false; + uint32_t mSetActiveDatasetCommandSequenceNum = 0; + ActivateDatasetCallback * mCallback = nullptr; +}; + +constexpr EndpointId kTestEndpointId = 1; +constexpr FabricIndex kTestAccessingFabricIndex = 1; +static FailSafeContext sTestFailsafeContext; +static TestDelegate sTestDelegate; +static ServerInstance sTestSeverInstance(kTestEndpointId, &sTestDelegate, sTestFailsafeContext); + +class TestSetActiveDatasetCommandHandler : public CommandHandler +{ +public: + TestSetActiveDatasetCommandHandler() : mClusterStatus(Protocols::InteractionModel::Status::Success) {} + CHIP_ERROR FallibleAddStatus(const ConcreteCommandPath & aRequestCommandPath, + const Protocols::InteractionModel::ClusterStatusCode & aStatus, const char * context = nullptr) + { + return CHIP_NO_ERROR; + } + + void AddStatus(const ConcreteCommandPath & aRequestCommandPath, const Protocols::InteractionModel::ClusterStatusCode & aStatus, + const char * context = nullptr) + { + mClusterStatus = aStatus; + } + + FabricIndex GetAccessingFabricIndex() const { return kTestAccessingFabricIndex; } + + CHIP_ERROR AddResponseData(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId, + const DataModel::EncodableToTLV & aEncodable) + { + return CHIP_NO_ERROR; + } + + void AddResponse(const ConcreteCommandPath & aRequestCommandPath, CommandId aResponseCommandId, + const DataModel::EncodableToTLV & aEncodable) + {} + + bool IsTimedInvoke() const { return false; } + + void FlushAcksRightAwayOnSlowCommand() {} + + Access::SubjectDescriptor GetSubjectDescriptor() const + { + Access::SubjectDescriptor subjectDescriptor = { kUndefinedFabricIndex, Access::AuthMode::kNone, kUndefinedNodeId, + kUndefinedCATs }; + return subjectDescriptor; + } + + Messaging::ExchangeContext * GetExchangeContext() const { return nullptr; } + + Protocols::InteractionModel::ClusterStatusCode mClusterStatus; +}; + +TestSetActiveDatasetCommandHandler sTestCommandHandler; + +class TestThreadBorderRouterManagementCluster : public ::testing::Test +{ +public: + static void SetUpTestSuite() + { + ASSERT_EQ(Platform::MemoryInit(), CHIP_NO_ERROR); + ASSERT_EQ(DeviceLayer::PlatformMgr().InitChipStack(), CHIP_NO_ERROR); + } + + static void TearDownTestSuite() + { + DeviceLayer::PlatformMgr().Shutdown(); + Platform::MemoryShutdown(); + } + + void TestAttributeRead(); + void TestCommandHandle(); +}; + +// Test ReadXX functions in ThreadBorderRouterManagement ServerInstance +TEST_F_FROM_FIXTURE(TestThreadBorderRouterManagementCluster, TestAttributeRead) +{ + // FeatureMap attribute + BitFlags featureMap = BitFlags(); + // Make the PAN change feature supported in Test delegate. + sTestDelegate.mPanChangeSupported = true; + sTestSeverInstance.ReadFeatureMap(featureMap); + EXPECT_TRUE(featureMap.Has(Feature::kPANChange)); + // Make the PAN change feature unsupported in Test delegate. + sTestDelegate.mPanChangeSupported = false; + featureMap.ClearAll(); + sTestSeverInstance.ReadFeatureMap(featureMap); + EXPECT_FALSE(featureMap.Has(Feature::kPANChange)); + // BorderRouterName attribute + // Use invalid BR name + sTestDelegate.mUseInvalidBorderRouterName = true; + char borderRouterName[kBorderRouterNameMaxLength + 10] = { 0 }; + MutableCharSpan nameSpan(borderRouterName); + EXPECT_EQ(sTestSeverInstance.ReadBorderRouterName(nameSpan), CHIP_IM_GLOBAL_STATUS(Failure)); + nameSpan = MutableCharSpan(borderRouterName); + // Use valid BR name + sTestDelegate.mUseInvalidBorderRouterName = false; + EXPECT_EQ(sTestSeverInstance.ReadBorderRouterName(nameSpan), CHIP_NO_ERROR); + EXPECT_TRUE(nameSpan.data_equal(CharSpan("TestName", strlen("TestName")))); + // BorderAgentId attribute + uint8_t borderAgentId[kBorderAgentIdLength] = { 0 }; + MutableByteSpan agentIdSpan(borderAgentId); + // Use invalid border agent id + sTestDelegate.mTestBorderAgentIdLen = kBorderAgentIdLength - 1; + EXPECT_EQ(sTestSeverInstance.ReadBorderAgentID(agentIdSpan), CHIP_IM_GLOBAL_STATUS(Failure)); + agentIdSpan = MutableByteSpan(borderAgentId); + // Use valid border agent id + sTestDelegate.mTestBorderAgentIdLen = kBorderAgentIdLength; + EXPECT_EQ(sTestSeverInstance.ReadBorderAgentID(agentIdSpan), CHIP_NO_ERROR); + EXPECT_TRUE(agentIdSpan.data_equal(ByteSpan(sTestDelegate.kTestBorderAgentId))); + // ActiveDatasetTimestamp attribute + // The active dataset timestamp should be null when no active dataset is configured + Optional timestamp = sTestSeverInstance.ReadActiveDatasetTimestamp(); + EXPECT_FALSE(timestamp.HasValue()); +} + +TEST_F_FROM_FIXTURE(TestThreadBorderRouterManagementCluster, TestCommandHandle) +{ + // Test GetActiveDatasetRequest and GetPendingDatasetRequest commands + Thread::OperationalDataset dataset; + using DatasetType = Delegate::DatasetType; + using Status = Protocols::InteractionModel::Status; + // The GetDataset requests should over CASE session. + EXPECT_EQ(sTestSeverInstance.HandleGetDatasetRequest(false /* isOverCASESession */, DatasetType::kActive, dataset), + Status::UnsupportedAccess); + EXPECT_EQ(sTestSeverInstance.HandleGetDatasetRequest(false, DatasetType::kPending, dataset), Status::UnsupportedAccess); + // The GetDataset should return NotFound when no dataset is configured. + EXPECT_EQ(sTestSeverInstance.HandleGetDatasetRequest(true, DatasetType::kActive, dataset), Status::NotFound); + EXPECT_EQ(sTestSeverInstance.HandleGetDatasetRequest(true, DatasetType::kPending, dataset), Status::NotFound); + // Test SetActiveDatasetRequest + ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::DecodableType req1; + uint8_t invalidDataset[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 }; + uint8_t validDataset[] = { 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0b, 0x35, 0x06, + 0x00, 0x04, 0x00, 0x1f, 0xff, 0xe0, 0x02, 0x08, 0xde, 0xaa, 0x00, 0xbe, 0xef, 0x00, 0xca, 0xef, 0x07, + 0x08, 0xfd, 0xde, 0xad, 0x00, 0xbe, 0xef, 0x00, 0x00, 0x05, 0x10, 0xb7, 0x28, 0x08, 0x04, 0x85, 0xcf, + 0xc5, 0x25, 0x7f, 0x68, 0x4c, 0x54, 0x9d, 0x6a, 0x57, 0x5e, 0x03, 0x0a, 0x4f, 0x70, 0x65, 0x6e, 0x54, + 0x68, 0x72, 0x65, 0x61, 0x64, 0x01, 0x02, 0xc1, 0x15, 0x04, 0x10, 0xcb, 0x13, 0x47, 0xeb, 0x0c, 0xd4, + 0xb3, 0x5c, 0xd1, 0x42, 0xda, 0x5e, 0x6d, 0xf1, 0x8b, 0x88, 0x0c, 0x04, 0x02, 0xa0, 0xf7, 0xf8 }; + Optional activeDatasetTimestamp = chip::NullOptional; + activeDatasetTimestamp = sTestSeverInstance.ReadActiveDatasetTimestamp(); + EXPECT_FALSE(activeDatasetTimestamp.HasValue()); + req1.activeDataset = ByteSpan(invalidDataset); + // SetActiveDatasetRequest is FailsafeRequired. + EXPECT_EQ(sTestSeverInstance.HandleSetActiveDatasetRequest(&sTestCommandHandler, req1), Status::FailsafeRequired); + EXPECT_EQ(sTestFailsafeContext.ArmFailSafe(kTestAccessingFabricIndex, System::Clock::Seconds16(1)), CHIP_NO_ERROR); + // SetActiveDatasetRequest should return InvalidCommand when dataset is invalid. + EXPECT_EQ(sTestSeverInstance.HandleSetActiveDatasetRequest(&sTestCommandHandler, req1), Status::InvalidCommand); + req1.activeDataset = ByteSpan(validDataset); + EXPECT_EQ(sTestSeverInstance.HandleSetActiveDatasetRequest(&sTestCommandHandler, req1), Status::Success); + // When the Server is handling a SetActiveDatasetRequest command, it should return Busy after receiving another one. + EXPECT_EQ(sTestSeverInstance.HandleSetActiveDatasetRequest(&sTestCommandHandler, req1), Status::Busy); + EXPECT_FALSE(sTestDelegate.mInterfaceEnabled); + EXPECT_EQ(sTestDelegate.mSetActiveDatasetCommandSequenceNum, static_cast(1)); + // Activate the dataset. + sTestDelegate.ActivateActiveDataset(); + EXPECT_EQ(sTestCommandHandler.mClusterStatus, + Protocols::InteractionModel::ClusterStatusCode(Protocols::InteractionModel::Status::Success)); + sTestFailsafeContext.DisarmFailSafe(); + // The Dataset should be updated. + EXPECT_EQ(sTestSeverInstance.HandleGetDatasetRequest(true, DatasetType::kActive, dataset), Status::Success); + EXPECT_TRUE(dataset.AsByteSpan().data_equal(ByteSpan(validDataset))); + EXPECT_TRUE(sTestDelegate.mInterfaceEnabled); + activeDatasetTimestamp = sTestSeverInstance.ReadActiveDatasetTimestamp(); + // activeDatasetTimestamp should have value. + EXPECT_TRUE(activeDatasetTimestamp.HasValue()); + EXPECT_EQ(sTestFailsafeContext.ArmFailSafe(kTestAccessingFabricIndex, System::Clock::Seconds16(1)), CHIP_NO_ERROR); + // When ActiveDatasetTimestamp is not null, the set active dataset request should return InvalidInState. + EXPECT_EQ(sTestSeverInstance.HandleSetActiveDatasetRequest(&sTestCommandHandler, req1), Status::InvalidInState); + sTestFailsafeContext.DisarmFailSafe(); + // Test SetPendingDatasetRequest command + Commands::SetPendingDatasetRequest::DecodableType req2; + sTestDelegate.mPanChangeSupported = false; + req2.pendingDataset = ByteSpan(validDataset); + // SetPendingDatasetRequest is supported when PANChange feature is enabled. + EXPECT_EQ(sTestSeverInstance.HandleSetPendingDatasetRequest(req2), Status::UnsupportedCommand); + sTestDelegate.mPanChangeSupported = true; + req2.pendingDataset = ByteSpan(invalidDataset); + // SetPendingDatasetRequest should return InvalidCommand when dataset is invalid. + EXPECT_EQ(sTestSeverInstance.HandleSetPendingDatasetRequest(req2), Status::InvalidCommand); + req2.pendingDataset = ByteSpan(validDataset); + // Success SetPendingDatasetRequest + EXPECT_EQ(sTestSeverInstance.HandleSetPendingDatasetRequest(req2), Status::Success); + EXPECT_EQ(sTestSeverInstance.HandleGetDatasetRequest(true, DatasetType::kPending, dataset), Status::Success); + EXPECT_TRUE(dataset.AsByteSpan().data_equal(ByteSpan(validDataset))); +} + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/tests/suites/TestDescriptorCluster.yaml b/src/app/tests/suites/TestDescriptorCluster.yaml index 21a43fbe3c1cd0..39179e1143bd75 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, 3] + value: [1, 2, 3, 4] - label: "Read attribute ClusterRevision" command: "readAttribute" diff --git a/src/app/tests/suites/TestFabricSyncBridgedNode.yaml b/src/app/tests/suites/TestFabricSyncBridgedNode.yaml new file mode 100644 index 00000000000000..6624e710127442 --- /dev/null +++ b/src/app/tests/suites/TestFabricSyncBridgedNode.yaml @@ -0,0 +1,64 @@ +# 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. + +name: Test Fabric Synchronization condition on Bridged Node Device Type + +PICS: + - MCORE.FS + +config: + nodeId: 0x12344321 + endpoint: 1 + endpointCommissionerControl: 0 + +tests: + - label: + "Read the DeviceTypeList attribute of the Descriptor cluster and check + whether the device type is Aggregator." + cluster: "Descriptor" + command: "readAttribute" + attribute: "DeviceTypeList" + response: + value: [ + { + DeviceType: 14, # Aggregator + }, + ] + + - label: + "Read the ServerList attribute of the Descriptor cluster and check + whether the Commissioner Control is present." + endpoint: endpointCommissionerControl + cluster: "Descriptor" + command: "readAttribute" + attribute: "ServerList" + response: + constraints: + type: list + contains: [ + 0x0751, # Commissioner Control Cluster + ] + + - label: + "Read the SupportedDeviceCategories attribute of the Commissioner + Control cluster and check whether the FabricSynchronization bit is + set." + endpoint: endpointCommissionerControl + cluster: "CommissionerControl" + command: "readAttribute" + attribute: "SupportedDeviceCategories" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x01] diff --git a/src/app/tests/suites/certification/PICS.yaml b/src/app/tests/suites/certification/PICS.yaml index cf0159804aeee3..af0aa5895fd426 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -6143,21 +6143,24 @@ PICS: # # server / features # - - label: "Does the device represent a Latching Switch?" + - label: "Does the device represent a Latching Switch (LS)?" id: SWTCH.S.F00 - - label: "Does the device represent a Momentary Switch?" + - label: "Does the device represent a Momentary Switch (MS)?" id: SWTCH.S.F01 - - label: "Does the MS device support Momentary Switch Release?" + - label: "Does the MS device support Momentary Switch Release (MSR)?" id: SWTCH.S.F02 - - label: "Does the MS device support Momentary Switch LongPress?" + - label: "Does the MS device support Momentary Switch LongPress (MSL)?" id: SWTCH.S.F03 - - label: "Does the MS device support Momentary Switch MultiPress?" + - label: "Does the MS device support Momentary Switch MultiPress (MSM)?" id: SWTCH.S.F04 + - label: "Does the device support ActionSwitch feature (AS)?" + id: SWTCH.S.F05 + # # client / features # @@ -10199,3 +10202,19 @@ PICS: - label: "Does the device implement the ActiveEndpoints attribute?" id: PWRTL.S.A0001 + + # + # Thread Network Directory Cluster + # + - label: + "Does the device implement the Thread Network Directory cluster as a + server" + id: THNETDIR.S + + # + # Wi-Fi Network Management Cluster + # + - label: + "Does the device implement the Wi-Fi Network Management cluster as a + server" + id: WIFINM.S diff --git a/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml b/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml index 52919b3cc02e70..fdb1e4137ce468 100644 --- a/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml @@ -33,20 +33,20 @@ tests: - name: "nodeId" value: nodeId - - label: "Step 3: TH reads from the DUT the ClusterRevision attribute." + - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." command: "readAttribute" attribute: "ClusterRevision" response: - value: 1 + value: 2 constraints: type: int16u - label: - "Step 2a: TH reads from the DUT the FeatureMap attribute and Check - values of flags in this FeatureMap" + "Step 3: TH reads from the DUT the FeatureMap attribute and ensures no + invalid bits." PICS: "!SWTCH.S.F00 && !SWTCH.S.F01 && !SWTCH.S.F02 && !SWTCH.S.F03 && - !SWTCH.S.F04" + !SWTCH.S.F04 && !SWTCH.S.F05" command: "readAttribute" attribute: "FeatureMap" response: @@ -55,7 +55,7 @@ tests: type: bitmap32 - label: - "Step 2b: Given SWTCH.S.F00(LS) ensure featuremap has the correct bit + "Step 3a: Given SWTCH.S.F00(LS) ensure featuremap has the correct bits set" PICS: SWTCH.S.F00 command: "readAttribute" @@ -64,11 +64,11 @@ tests: constraints: type: bitmap32 hasMasksSet: [0x01] - hasMasksClear: [0x02, 0x04, 0x08, 0x10] + hasMasksClear: [0x02, 0x04, 0x08, 0x10, 0x20] - label: - "Step 2c: Given SWTCH.S.F01(MS) ensure featuremap has the correct bit - set" + "Step 3b: Given SWTCH.S.F01(MS) ensure featuremap has the correct bits + set: checks on !MSL when MS feature present." PICS: SWTCH.S.F01 command: "readAttribute" attribute: "FeatureMap" @@ -79,8 +79,8 @@ tests: hasMasksClear: [0x1] - label: - "Step 2d: Given SWTCH.S.F02(MSR) ensure featuremap has the correct bit - set" + "Step 3b: Given SWTCH.S.F02(MSR) ensure featuremap has the correct + bits set: checks on MS & !AS & MSR." PICS: SWTCH.S.F02 command: "readAttribute" attribute: "FeatureMap" @@ -88,142 +88,86 @@ tests: constraints: type: bitmap32 hasMasksSet: [0x2, 0x4] - hasMasksClear: [0x1] + hasMasksClear: [0x1, 0x20] - label: - "Step 2e: Given SWTCH.S.F03(MSL) ensure featuremap has the correct bit - set" + "Step 3b: Given SWTCH.S.F03(MSL) ensure featuremap has the correct + bits set: LS cannot be enabled if MSL." PICS: SWTCH.S.F03 command: "readAttribute" attribute: "FeatureMap" response: constraints: type: bitmap32 - hasMasksSet: [0x2, 0x4, 0x8] + hasMasksSet: [0x2, 0x8] hasMasksClear: [0x1] - label: - "Step 2f: Given SWTCH.S.F04(MSM) ensure featuremap has the correct bit - set" + "Step 3b: Given SWTCH.S.F04(MSM) ensure featuremap has the correct + bits set: LS cannot be enabled if MSM." PICS: SWTCH.S.F04 command: "readAttribute" attribute: "FeatureMap" response: constraints: type: bitmap32 - hasMasksSet: [0x2, 0x4, 0x10] + hasMasksSet: [0x2, 0x10] hasMasksClear: [0x1] - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: SWTCH.S.F04 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 4b: TH reads from the DUT the AttributeList attribute." - PICS: "PICS_EVENT_LIST_ENABLED && !SWTCH.S.F04" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4b: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED && !SWTCH.S.F04" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5a: TH reads from the DUT the EventList attribute." - PICS: - "!SWTCH.S.F00 && !SWTCH.S.F01 && !SWTCH.S.F02 && !SWTCH.S.F03 && - !SWTCH.S.F04 " - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 5b: TH reads EventList if SWTCH.S.F00(LS)" - PICS: PICS_EVENT_LIST_ENABLED && SWTCH.S.F00 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - label: - "Step 5c: TH reads EventList if SWTCH.S.F01(MS) & !SWTCH.S.F02(MSR)" - PICS: PICS_EVENT_LIST_ENABLED && SWTCH.S.F01 && !SWTCH.S.F02 + "Step 3b: Given SWTCH.S.F05(AS) ensure featuremap has the correct bits + set: LS and MSR cannot be enabled if AS, and MSM is required by AS." + PICS: SWTCH.S.F05 command: "readAttribute" - attribute: "EventList" + attribute: "FeatureMap" response: constraints: - type: list - contains: [1] + type: bitmap32 + hasMasksSet: [0x2, 0x10, 0x20] + hasMasksClear: [0x1, 0x4] - - label: - "Step 5d: TH reads EventList if SWTCH.S.F01(MS) & SWTCH.S.F02(MSR) & - !SWTCH.S.F03(MSL) & !SWTCH.S.F04(MSM)" - PICS: - " PICS_EVENT_LIST_ENABLED && SWTCH.S.F01 && SWTCH.S.F02 && - !SWTCH.S.F03 && !SWTCH.S.F04 " + - label: "Step 3c: LS and MS are mutually exclusive (1/2)." + PICS: "SWTCH.S.F00" command: "readAttribute" - attribute: "EventList" + attribute: "FeatureMap" response: constraints: - type: list - contains: [1, 3] + type: bitmap32 + hasMasksSet: [0x1] + hasMasksClear: [0x2] - - label: - "Step 5e: TH reads EventList if SWTCH.S.F01(MS) & SWTCH.S.F02(MSR) & - SWTCH.S.F03(MSL) & !SWTCH.S.F04(MSM)" - PICS: - " PICS_EVENT_LIST_ENABLED && SWTCH.S.F01 && SWTCH.S.F02 && SWTCH.S.F03 - && !SWTCH.S.F04 " + - label: "Step 3c: LS and MS are mutually exclusive (2/2)." + PICS: "SWTCH.S.F01" command: "readAttribute" - attribute: "EventList" + attribute: "FeatureMap" response: constraints: - type: list - contains: [1, 2, 3, 4] + type: bitmap32 + hasMasksSet: [0x2] + hasMasksClear: [0x1] - label: - "Step 5f: TH reads EventList if SWTCH.S.F01(MS) & SWTCH.S.F02(MSR) & - !SWTCH.S.F03(MSL) & SWTCH.S.F04(MSM) " - PICS: - " PICS_EVENT_LIST_ENABLED && SWTCH.S.F01 && SWTCH.S.F02 && - !SWTCH.S.F03 && SWTCH.S.F04 " + "Step 4: TH reads from the DUT the AttributeList attribute, verify + that attribute MultiPressMax is present with MSM feature." + PICS: "SWTCH.S.F04" command: "readAttribute" - attribute: "EventList" + attribute: "AttributeList" response: constraints: type: list - contains: [1, 3, 5, 6] + contains: [2] - label: - "Step 5g: TH reads EventList if SWTCH.S.F01(MS) & SWTCH.S.F02(MSR) & - SWTCH.S.F03(MSL) & SWTCH.S.F04(MSM) " - PICS: - " PICS_EVENT_LIST_ENABLED && SWTCH.S.F01 && SWTCH.S.F02 && SWTCH.S.F03 - && SWTCH.S.F04 " + "Step 4: TH reads from the DUT the AttributeList attribute, verify + mandatory attributes." command: "readAttribute" - attribute: "EventList" + attribute: "AttributeList" response: constraints: type: list - contains: [1, 2, 3, 4, 5, 6] + contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." + - label: "Step 5: TH reads from the DUT the AcceptedCommandList attribute." command: "readAttribute" attribute: "AcceptedCommandList" response: @@ -231,7 +175,7 @@ tests: constraints: type: list - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." + - label: "Step 6: TH reads from the DUT the GeneratedCommandList attribute." command: "readAttribute" attribute: "GeneratedCommandList" response: diff --git a/src/app/tests/suites/certification/Test_TC_SWTCH_2_2.yaml b/src/app/tests/suites/certification/Test_TC_SWTCH_2_2.yaml deleted file mode 100644 index 3f4f9cc47c7aad..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_SWTCH_2_2.yaml +++ /dev/null @@ -1,1395 +0,0 @@ -# Copyright (c) 2021 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. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 74.2.2. [TC-SWTCH-2.2] Primary functionality with server as DUT - -PICS: - - SWTCH.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Note" - verification: | - NOTE: https://github.com/project-chip/connectedhomeip/tree/master/examples/all-clusters-app/linux#readme - - Events to be executed as following - 1. Compile app using below command in connectedhomeip folder - a. ./scripts/run_in_build_env.sh "./scripts/build/build_examples.py --target linux-arm64-all-clusters-no-ble-asan-clang build" - 2. Build respective app (all-clusters-app) - 3. Commission DUT to TH - 4. Open 2nd terminal of DUT and provide the below command to obtain PID of DUT ps -aef|grep all-clusters-app - 5. Follow the Verification step below to generate the event in 2nd terminal of DUT - disabled: true - - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - verification: | - Commission DUT to TH - disabled: true - - - label: "Step 2a: Set up subscription to SwitchLatched event" - PICS: SWTCH.S.F00 - verification: | - Please use Interactive mode to Verify the subscription of an event - Here the command to enter interactive mode:-- - ./chip-tool interactive start - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event switch-latched 1 100 1 1 - - [1697604266.130621][7393:7395] CHIP:DMG: SubscribeResponseMessage = - [1697604266.130624][7393:7395] CHIP:DMG: { - [1697604266.130628][7393:7395] CHIP:DMG: SubscriptionId = 0xf6d55121, - [1697604266.130632][7393:7395] CHIP:DMG: MaxInterval = 0x64, - [1697604266.130636][7393:7395] CHIP:DMG: InteractionModelRevision = 11 - [1697604266.130640][7393:7395] CHIP:DMG: } - disabled: true - - - label: "Step 2b: Operator sets switch to first position (zero) on the DUT" - PICS: SWTCH.S.F00 - verification: | - On Raspi platform to trigger the event, give the below command by opening an another terminal in DUT - (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have the capability to generate this event) - - echo '{"Name":"SwitchLatched","NewPosition":0}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the SwitchLatched event with NewPosition 0: - - [1697604377.953057][7384:7386] CHIP:-: Received payload: "{"Name":"SwitchLatched","NewPosition":0}" - [1697604377.955361][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0a9 - [1697604377.955421][7384:7384] CHIP:-: The latching switch is moved to a new position:0 - [1697604377.955430][7384:7384] CHIP:ZCL: SwitchServer: OnSwitchLatch - [1697604377.955474][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000006 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x0 Epoch timestamp: 0x0000018B411B1D63 - disabled: true - - - label: "Step 2c: TH reads the CurrentPosition attribute from the DUT" - PICS: SWTCH.S.F00 - verification: | - switch read current-position 1 1 - - Verify CurrentPosition value is 0 in TH(chip-tool) Log and below is the sample log provided for the raspi platform: - - [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 - [1646209289.746228][2617:2622] CHIP:TOO: CurrentPosition: 0 - disabled: true - - - label: "Step 2d: Operator sets switch to second position (one) on the DUT" - PICS: SWTCH.S.F00 - verification: | - On Raspi platform to trigger the event give the below command by opening an another terminal in DUT - (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have the capability to generate this event) - - echo '{"Name":"SwitchLatched","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the SwitchLatched event with NewPosition set to 1: - - [1697604732.758383][7384:7386] CHIP:-: Received payload: "{"Name":"SwitchLatched","NewPosition":1}" - [1697604732.758668][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0aa - [1697604732.758703][7384:7384] CHIP:-: The latching switch is moved to a new position:1 - [1697604732.758712][7384:7384] CHIP:ZCL: SwitchServer: OnSwitchLatch - [1697604732.758757][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000007 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x0 Epoch timestamp: 0x0000018B41208756 - - switch read-event switch-latched 1 1 - - Verify TH receives SwitchLatched event with NewPosition set to 1 on TH(Chip-tool) log and below is the sample log provided for the raspi platform: - - [1687257297.110327][17168:17170] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 [1687257297.110330][17168:17170] CHIP:TOO: Event number: 7 - [1687257297.110333][17168:17170] CHIP:TOO: Priority: Info - [1687257297.110336][17168:17170] CHIP:TOO: Timestamp: 1687257190679 - [1687257297.110341][17168:17170] CHIP:TOO: SwitchLatched: { - [1687257297.110345][17168:17170] CHIP:TOO: NewPosition: 1 - [1687257297.110349][17168:17170] CHIP:TOO: } - disabled: true - - - label: "Step 2e: TH reads CurrentPosition attribute from the DUT" - PICS: SWTCH.S.F00 - verification: | - switch read current-position 1 1 - - Verify CurrentPosition value is 1 in TH(chip-tool) Log and below is the sample log provided for the raspi platform: - - [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 - [1646209289.746228][2617:2622] CHIP:TOO: CurrentPosition: 1 - disabled: true - - - label: - "Step 2f: If NumberOfPositions>2 (see 2a of TC-SWTCH-2.1) : - Operator - sets switch to next position on the DUT - TH reads the CurrentPosition - attribute from the DUT" - PICS: SWTCH.S.F00 - verification: | - If NumberOfPositions>2, then Set switch to next position Otherwise skip this step. - - For checking the number of positions that switch supports, Please read the NumberOfPositions attribute From TC-SWTCH-2.1 in step 2a . - - switch read number-of-positions 1 1 - - Verify the "NumberOfPositions" attribute value On TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - - [1697605547.057869][7525:7527] CHIP:DMG: } - [1697605547.058012][7525:7527] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0000 DataVersion: 1304215724 - [1697605547.058063][7525:7527] CHIP:TOO: NumberOfPositions: 2 - - On Raspi platform to trigger the event give the below command by opening an another terminal in DUT - (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have the capability to generate this event) - - echo '{"Name":"SwitchLatched","NewPosition":2}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the SwitchLatched event with NewPosition set to 2: - - [1697615458.515582][7384:7386] CHIP:-: Received payload: "{"Name":"SwitchLatched","NewPosition":2}" - [1697615458.515822][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0c5 - [1697615458.515854][7384:7384] CHIP:-: The latching switch is moved to a new position:3 - [1697615458.515867][7384:7384] CHIP:ZCL: SwitchServer: OnSwitchLatch - [1697615458.516014][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x000000000000000B due to overflow: event priority_level: 1 - [1697615458.516081][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697615458.516110][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000024 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x0 Epoch timestamp: 0x0000018B41C430D3 - - switch read-event switch-latched 1 1 - - Verify TH receives SwitchLatched event with NewPosition set to 2 on TH(Chip-tool) log and below is the sample log provided for the raspi platform: - - [1697615514.717194][7767:7769] CHIP:DMG: } - [1697615514.717359][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1697615514.717371][7767:7769] CHIP:TOO: Event number: 36 - [1697615514.717383][7767:7769] CHIP:TOO: Priority: Info - [1697615514.717396][7767:7769] CHIP:TOO: Timestamp: 1697615458515 - [1697615514.717430][7767:7769] CHIP:TOO: SwitchLatched: { - [1697615514.717449][7767:7769] CHIP:TOO: NewPosition: 2 - [1697615514.717464][7767:7769] CHIP:TOO: } - - In the current SDK development, Max number of positions is configured as 2, hence the current test step should fail as NewPosition reached more than the Max NumberOfPositions. - If the DUT supports NumberOfPositions>2, then, position should increase to the next level. Below is the sample command to execute to check the CurrentPosition - - switch read current-position 1 1 - - Verify CurrentPosition value is 2 On TH(chip-tool) Log and below is the sample log provided for the raspi platform: - - [1659600502.023560][4306:4311] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001 DataVersion: 391463069 - [1687847841.651568][19369:19371] CHIP:TOO: CurrentPosition: 2 - disabled: true - - - label: - "Step 2g: If NumberOfPositions>3 : - Repeat step 2f for - NumberOfPositions-3 times - After each time Operator has set switch to - next position on the DUT, - TH reads CurrentPosition attribute from - the DUT" - PICS: SWTCH.S.F00 - verification: | - If NumberOfPositions>3, then Set the switch to next position Otherwise skip this step. - - For checking the number of positions that switch supports, Please read the NumberOfPositions attribute From TC-SWTCH-2.1 in step 2a . - - switch read number-of-positions 1 1 - - Verify the "NumberOfPositions" attribute value On TH(Chip-tool) Log and below is the sample log provided for the raspi platform: - - [1697605547.057869][7525:7527] CHIP:DMG: } - [1697605547.058012][7525:7527] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0000 DataVersion: 1304215724 - [1697605547.058063][7525:7527] CHIP:TOO: NumberOfPositions: 2 - - In Raspi platform to change the switch to third position use the below sample command, its required to use equivalent command on the respective DUT. Open one more terminal on DUT side to execute the echo command . - - echo '{"Name":"SwitchLatched","NewPosition":3}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the SwitchLatched event with NewPosition set to 3: - - [1659600438.058928][7312:7321] CHIP:-: Received payload: "{"Name":"SwitchLatched","NewPosition":3}" - [1659600438.059436][7312:7312] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 1755409d - [1659600438.059519][7312:7312] CHIP:-: The latching switch is moved to a new position:3 - [1659600438.059644][7312:7312] CHIP:ZCL: SwitchServer: OnSwitchLatch - [1659600438.059857][7312:7312] CHIP:EVL: LogEvent event number: 0x0000000000020006 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x0 Sys timestamp: 0x0000000000F10746 - - switch read-event switch-latched 1 1 - - Verify SwitchLatched event with NewPosition set to 3 on TH(Chip-tool) log and below is the sample log provided for the raspi platform: - - [1687258513.235224][17561:17563] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1687258513.235227][17561:17563] CHIP:TOO: Event number: 9 - [1687258513.235230][17561:17563] CHIP:TOO: Priority: Info - [1687258513.235231][17561:17563] CHIP:TOO: Timestamp: 1687258318347 - [1687258513.235235][17561:17563] CHIP:TOO: SwitchLatched: { - [1687258513.235238][17561:17563] CHIP:TOO: NewPosition: 3 - [1687258513.235239][17561:17563] CHIP:TOO: } - - In the current SDK development, Max number of positions are configured as 2, hence the current test step should fail as its reached more than the Max NumberOfPositions. - If the DUT supports NumberOfPositions>3, then position should increase to the next level. Below is the sample command to execute to check the CurrentPosition - - switch read current-position 1 1 - - Verify CurrentPosition value is 3 On TH(chip-tool) Log and below is the sample log provided for the raspi platform and below is the sample log provided for the raspi platform: - - [1659600502.023560][4306:4311] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001 DataVersion: 391463069 - [1687847873.385882][19378:19380] CHIP:TOO: CurrentPosition: 3 - disabled: true - - - label: "Step 2h: Operator returns switch to first position on the DUT" - PICS: SWTCH.S.F00 - verification: | - On Raspi platform to trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have capability to generate this event) - - echo '{"Name":"SwitchLatched","NewPosition":0}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the SwitchLatched event with NewPosition set to 0: - - [1697606147.106734][7384:7386] CHIP:-: Received payload: "{"Name":"SwitchLatched","NewPosition":0}" - [1697606147.106976][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0ae - [1697606147.107012][7384:7384] CHIP:-: The latching switch is moved to a new position:0 - [1697606147.107023][7384:7384] CHIP:ZCL: SwitchServer: OnSwitchLatch - [1697606147.107137][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697606147.107170][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000000B priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x0 Epoch timestamp: 0x0000018B41361C23 - - switch read-event switch-latched 1 1 - - Verify TH receives SwitchLatched event with NewPosition set to 0 on TH(Chip-tool) log and below is the sample log provided for the raspi platform: - - [1697606183.274301][7536:7538] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0000 - [1697606183.274313][7536:7538] CHIP:TOO: Event number: 11 - [1697606183.274320][7536:7538] CHIP:TOO: Priority: Info - [1697606183.274325][7536:7538] CHIP:TOO: Timestamp: 1697606147107 - [1697606183.274350][7536:7538] CHIP:TOO: SwitchLatched: { - [1697606183.274362][7536:7538] CHIP:TOO: NewPosition: 0 - [1697606183.274373][7536:7538] CHIP:TOO: } - disabled: true - - - label: "Step 2i: TH reads the CurrentPosition attribute from the DUT" - PICS: SWTCH.S.F00 - verification: | - switch read current-position 1 1 - - Verify CurrentPosition value is 0 On TH(chip-tool) Log and below is the sample log provided for the raspi platform: - - [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 - [1646209289.746228][2617:2622] CHIP:TOO: CurrentPosition: 0 - disabled: true - - - label: "Step 3a: Set up subscription to InitialPress event" - PICS: SWTCH.S.F01 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - Please use Interactive mode to Verify the subscription of an event - Here the command to enter interactive mode:-- - ./chip-tool interactive start - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event initial-press 1 100 1 1 - - [1697606330.206997][7536:7538] CHIP:DMG: SubscribeResponseMessage = - [1697606330.207001][7536:7538] CHIP:DMG: { - [1697606330.207004][7536:7538] CHIP:DMG: SubscriptionId = 0x460ae381, - [1697606330.207008][7536:7538] CHIP:DMG: MaxInterval = 0x64, - [1697606330.207011][7536:7538] CHIP:DMG: InteractionModelRevision = 11 - [1697606330.207014][7536:7538] CHIP:DMG: } - disabled: true - - - label: "Step 3b: Operator does not operate switch on the DUT" - PICS: SWTCH.S.F01 - verification: | - no Matter messages - disabled: true - - - label: "Step 3c: TH reads the CurrentPosition attribute from the DUT" - PICS: SWTCH.S.F01 - verification: | - switch read current-position 1 1 - - Verify CurrentPosition value is 0 On TH (chip-tool) Log and below is the sample log provided for the raspi platform: - - [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 - [1687847957.516951][19394:19396] CHIP:TOO: CurrentPosition: 0 - disabled: true - - - label: "Step 3d: Operator operates switch (keep it pressed)" - PICS: SWTCH.S.F01 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform to trigger the event give the below command by opening an another terminal in DUT - (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have the capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697606594.815345][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697606594.815586][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0af - [1697606594.815620][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697606594.815631][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697606594.815743][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697606594.815773][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000000C priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B413CF0FF - - switch read-event initial-press 1 1 - - Verify TH receives InitialPress event with NewPosition set to 1 on TH(Chip-tool) log and below is the sample log provided for the raspi platform: - - [1697606630.390750][7536:7538] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697606630.390763][7536:7538] CHIP:TOO: Event number: 12 - [1697606630.390771][7536:7538] CHIP:TOO: Priority: Info - [1697606630.390780][7536:7538] CHIP:TOO: Timestamp: 1697606594815 - [1697606630.390822][7536:7538] CHIP:TOO: InitialPress: { - [1697606630.390840][7536:7538] CHIP:TOO: NewPosition: 1 - [1697606630.390851][7536:7538] CHIP:TOO: } - disabled: true - - - label: "Step 3e: TH reads the CurrentPosition attribute from the DUT" - PICS: SWTCH.S.F01 - verification: | - switch read current-position 1 1 - - Verify CurrentPosition value is 1 On TH(chip-tool) Log and below is the sample log provided for the raspi platform: - - [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 - [1687847982.359195][19398:19400] CHIP:TOO: CurrentPosition: 1 - disabled: true - - - label: "Step 3f: Operator releases switch on the DUT" - PICS: SWTCH.S.F01 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform to trigger the event give the below command by opening an another terminal in DUT - (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have the capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697606778.141141][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697606778.141356][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0b0 - [1697606778.141394][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697606778.141410][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697606778.141548][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697606778.141592][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000000D priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B413FBD1D - disabled: true - - - label: "Step 3g: TH reads the CurrentPosition attribute from the DUT" - PICS: SWTCH.S.F01 - verification: | - switch read current-position 1 1 - - Verify CurrentPosition value is 0 On TH(chip-tool) Log and below is the sample log provided for the raspi platform: - - [1646209289.746157][2617:2622] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Attribute 0x0000_0001DataVersion: 1206711661 - [1687848004.040125][19402:19404] CHIP:TOO: CurrentPosition: 0 - disabled: true - - - label: - "Step 4a: Set up subscription to InitialPress and ShortRelease events" - PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - Please use Interactive mode to Verify the subscription of an event - Here the command to enter interactive mode:-- - 1. ./chip-tool interactive start - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event initial-press 1 100 1 1 - - [1697607013.770976][7736:7738] CHIP:DMG: SubscribeResponseMessage = - [1697607013.770988][7736:7738] CHIP:DMG: { - [1697607013.770998][7736:7738] CHIP:DMG: SubscriptionId = 0xfba47d40, - [1697607013.771010][7736:7738] CHIP:DMG: MaxInterval = 0x64, - [1697607013.771021][7736:7738] CHIP:DMG: InteractionModelRevision = 11 - [1697607013.771030][7736:7738] CHIP:DMG: } - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event short-release 1 100 1 1 - - [1697607082.641213][7736:7738] CHIP:DMG: SubscribeResponseMessage = - [1697607082.641216][7736:7738] CHIP:DMG: { - [1697607082.641221][7736:7738] CHIP:DMG: SubscriptionId = 0xbe6a8e5d, - [1697607082.641225][7736:7738] CHIP:DMG: MaxInterval = 0x64, - [1697607082.641229][7736:7738] CHIP:DMG: InteractionModelRevision = 11 - [1697607082.641233][7736:7738] CHIP:DMG: } - disabled: true - - - label: "Step 4b: Operator does not operate switch on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 - verification: | - no Matter messages - disabled: true - - - label: "Step 4c: Operator operates switch (press briefly) on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697607350.058984][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697607350.059268][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0b2 - [1697607350.059302][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697607350.059311][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697607350.059431][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697607350.059466][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000000F priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B4148772B - - switch read-event initial-press 1 1 - - Verify TH receive InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697607828.913031][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697607828.913034][7767:7769] CHIP:TOO: Event number: 17 - [1697607828.913037][7767:7769] CHIP:TOO: Priority: Info - [1697607828.913040][7767:7769] CHIP:TOO: Timestamp: 1697607697125 - [1697607828.913046][7767:7769] CHIP:TOO: InitialPress: { - [1697607828.913050][7767:7769] CHIP:TOO: NewPosition: 1 - [1697607828.913054][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 4d: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697607957.484361][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697607957.484562][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0b6 - [1697607957.484610][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697607957.484622][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697607957.484732][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697607957.484765][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000013 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B4151BBEC - - switch read-event short-release 1 1 - - Verify TH receive ShortRelease event with PreviousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697608045.926586][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697608045.926590][7767:7769] CHIP:TOO: Event number: 19 - [1697608045.926593][7767:7769] CHIP:TOO: Priority: Info - [1697608045.926596][7767:7769] CHIP:TOO: Timestamp: 1697607957484 - [1697608045.926601][7767:7769] CHIP:TOO: ShortRelease: { - [1697608045.926605][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697608045.926608][7767:7769] CHIP:TOO: } - disabled: true - - - label: - "Step 4e: Operator operates switch (keep pressed for long time, e.g. 5 - seconds) on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform to trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697608104.080281][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697608104.080508][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0b7 - [1697608104.080548][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697608104.080561][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697608104.080675][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697608104.080709][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000014 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B4153F890 - - switch read-event initial-press 1 1 - - Verify InitialPress event with NewPosition set to 1 on TH (chip-tool) log and below is the sample log provided for the raspi platform: - - [1697608164.378204][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697608164.378207][7767:7769] CHIP:TOO: Event number: 20 - [1697608164.378209][7767:7769] CHIP:TOO: Priority: Info - [1697608164.378211][7767:7769] CHIP:TOO: Timestamp: 1697608104080 - [1697608164.378214][7767:7769] CHIP:TOO: InitialPress: { - [1697608164.378217][7767:7769] CHIP:TOO: NewPosition: 1 - [1697608164.378219][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 4f: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F02 && !SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform to trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor DUT should have capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697608242.275996][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697608242.276246][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0b8 - [1697608242.276280][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697608242.276296][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697608242.276424][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697608242.276468][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000015 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B41561464 - - switch read-event short-release 1 1 - - Verify TH receives ShortRelease event with PreviousPosition set to 1 on TH (chip-tool) log and below is the sample log provided for the raspi platform: - - [1697608382.457912][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697608382.457915][7767:7769] CHIP:TOO: Event number: 21 - [1697608382.457917][7767:7769] CHIP:TOO: Priority: Info - [1697608382.457919][7767:7769] CHIP:TOO: Timestamp: 1697608242276 - [1697608382.457923][7767:7769] CHIP:TOO: ShortRelease: { - [1697608382.457927][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697608382.457929][7767:7769] CHIP:TOO: } - disabled: true - - - label: - "Step 5a: Set up subscription to InitialPress, LongPress, - ShortRelease, LongRelease events" - PICS: SWTCH.S.F01 && SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - Please use Interactive mode to Verify the subscription of an event - Here the command to enter interactive mode:-- - ./chip-tool interactive start - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event initial-press 1 100 1 1 - - - [1697608480.015747][7767:7769] CHIP:DMG: SubscribeResponseMessage = - [1697608480.015750][7767:7769] CHIP:DMG: { - [1697608480.015753][7767:7769] CHIP:DMG: SubscriptionId = 0x9c490538, - [1697608480.015756][7767:7769] CHIP:DMG: MaxInterval = 0x64, - [1697608480.015758][7767:7769] CHIP:DMG: InteractionModelRevision = 11 - [1697608480.015761][7767:7769] CHIP:DMG: } - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event long-press 1 100 1 1 - - [1697608527.530605][7767:7769] CHIP:DMG: SubscribeResponseMessage = - [1697608527.530609][7767:7769] CHIP:DMG: { - [1697608527.530613][7767:7769] CHIP:DMG: SubscriptionId = 0xaa07867b, - [1697608527.530619][7767:7769] CHIP:DMG: MaxInterval = 0x64, - [1697608527.530623][7767:7769] CHIP:DMG: InteractionModelRevision = 11 - [1697608527.530628][7767:7769] CHIP:DMG: } - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event short-release 1 100 1 1 - - [1697608580.243388][7767:7769] CHIP:DMG: SubscribeResponseMessage = - [1697608580.243391][7767:7769] CHIP:DMG: { - [1697608580.243394][7767:7769] CHIP:DMG: SubscriptionId = 0x9b71447a, - [1697608580.243397][7767:7769] CHIP:DMG: MaxInterval = 0x64, - [1697608580.243400][7767:7769] CHIP:DMG: InteractionModelRevision = 11 - [1697608580.243402][7767:7769] CHIP:DMG: } - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event long-release 1 100 1 1 - - [1697608657.944735][7767:7769] CHIP:DMG: SubscribeResponseMessage = - [1697608657.944738][7767:7769] CHIP:DMG: { - [1697608657.944741][7767:7769] CHIP:DMG: SubscriptionId = 0x3d884dce, - [1697608657.944745][7767:7769] CHIP:DMG: MaxInterval = 0x64, - [1697608657.944748][7767:7769] CHIP:DMG: InteractionModelRevision = 11 - [1697608657.944751][7767:7769] CHIP:DMG: } - disabled: true - - - label: "Step 5b: Operator does not operate switch on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F03 - verification: | - no Matter messages - disabled: true - - - label: "Step 5c: Operator operates switch (press briefly) on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697608754.628837][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697608754.629085][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0b9 - [1697608754.629120][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697608754.629132][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697608754.629247][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697608754.629277][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000016 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B415DE5C5 - - switch read-event initial-press 1 1 - - Verify TH receives InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697608808.722369][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697608808.722371][7767:7769] CHIP:TOO: Event number: 22 - [1697608808.722374][7767:7769] CHIP:TOO: Priority: Info - [1697608808.722376][7767:7769] CHIP:TOO: Timestamp: 1697608754629 - [1697608808.722380][7767:7769] CHIP:TOO: InitialPress: { - [1697608808.722383][7767:7769] CHIP:TOO: NewPosition: 1 - [1697608808.722385][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 5d: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697608936.890550][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697608936.890789][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0ba - [1697608936.890824][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697608936.890833][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697608936.890948][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697608936.890983][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000017 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B4160ADBA - - switch read-event short-release 1 1 - - Verify TH receives ShortRelease event with PreviousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697608970.793400][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697608970.793402][7767:7769] CHIP:TOO: Event number: 23 - [1697608970.793405][7767:7769] CHIP:TOO: Priority: Info - [1697608970.793408][7767:7769] CHIP:TOO: Timestamp: 1697608936890 - [1697608970.793414][7767:7769] CHIP:TOO: ShortRelease: { - [1697608970.793417][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697608970.793421][7767:7769] CHIP:TOO: } - disabled: true - - - label: - "Step 5e: Operator operates switch (keep pressed for long time, e.g. 5 - seconds) on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697609110.498463][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697609110.498726][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bb - [1697609110.498757][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697609110.498766][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697609110.498925][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 2 - [1697609110.499002][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609110.499030][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000018 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B416353E2 - - switch read-event initial-press 1 1 - - Verify InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697609188.273452][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697609188.273455][7767:7769] CHIP:TOO: Event number: 24 - [1697609188.273457][7767:7769] CHIP:TOO: Priority: Info - [1697609188.273459][7767:7769] CHIP:TOO: Timestamp: 1697609110498 - [1697609188.273463][7767:7769] CHIP:TOO: InitialPress: { - [1697609188.273466][7767:7769] CHIP:TOO: NewPosition: 1 - [1697609188.273469][7767:7769] CHIP:TOO: } - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"LongPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the longPress event with NewPosition set to 1: - - [1697609280.508624][7384:7386] CHIP:-: Received payload: "{"Name":"LongPress","NewPosition":1}" - [1697609280.508890][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bc - [1697609280.508924][7384:7384] CHIP:-: The new position when the momentary switch has been pressed for a long time:1 - [1697609280.508933][7384:7384] CHIP:ZCL: SwitchServer: OnLongPress - [1697609280.509078][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000001 due to overflow: event priority_level: 1 - [1697609280.509144][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609280.509174][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000019 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x2 Epoch timestamp: 0x0000018B4165EBFC - [1697609280.509203][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_005C update version to e31eae9f - - - switch read-event long-press 1 1 - - Verify TH receives longPress event with NewPosition set to 1 on TH (chip-tool) log and below is the sample log provided for the raspi platform: - - [1697609316.967370][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0002 - [1697609316.967375][7767:7769] CHIP:TOO: Event number: 25 - [1697609316.967376][7767:7769] CHIP:TOO: Priority: Info - [1697609316.967380][7767:7769] CHIP:TOO: Timestamp: 1697609280508 - [1697609316.967391][7767:7769] CHIP:TOO: LongPress: { - [1697609316.967397][7767:7769] CHIP:TOO: NewPosition: 1 - [1697609316.967402][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 5f: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F03 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"LongRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the LongRelease event with previousPosition set to 1: - - [1697609417.101354][7384:7386] CHIP:-: Received payload: "{"Name":"LongRelease","PreviousPosition":1}" - [1697609417.101563][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bd - [1697609417.101600][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released after having been pressed for a long time:1 - [1697609417.101614][7384:7384] CHIP:ZCL: SwitchServer: OnLongRelease - [1697609417.101765][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000004 due to overflow: event priority_level: 1 - [1697609417.101831][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609417.101862][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001C priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x4 Epoch timestamp: 0x0000018B4168018D - - switch read-event long-release 1 1 - - Verify TH receives LongRelease event with previousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697609485.675506][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0004 - [1697609485.675509][7767:7769] CHIP:TOO: Event number: 28 - [1697609485.675511][7767:7769] CHIP:TOO: Priority: Info - [1697609485.675513][7767:7769] CHIP:TOO: Timestamp: 1697609417101 - [1697609485.675531][7767:7769] CHIP:TOO: LongRelease: { - [1697609485.675538][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697609485.675542][7767:7769] CHIP:TOO: } - disabled: true - - - label: - "Step 6a: Set up subscription to InitialPress, ShortRelease, - MultiPressOngoing, MultiPressComplete events" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - Please use Interactive mode to Verify the subscription of an event - Here the command to enter interactive mode:-- - - ./chip-tool interactive start - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event initial-press 1 100 1 1 - - [1697609572.733866][7767:7769] CHIP:DMG: SubscribeResponseMessage = - [1697609572.733870][7767:7769] CHIP:DMG: { - [1697609572.733872][7767:7769] CHIP:DMG: SubscriptionId = 0xdb9c2f95, - [1697609572.733875][7767:7769] CHIP:DMG: MaxInterval = 0x64, - [1697609572.733878][7767:7769] CHIP:DMG: InteractionModelRevision = 11 - [1697609572.733880][7767:7769] CHIP:DMG: } - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event short-release 1 100 1 1 - - [1697609772.052026][7767:7769] CHIP:DMG: SubscribeResponseMessage = - [1697609772.052029][7767:7769] CHIP:DMG: { - [1697609772.052032][7767:7769] CHIP:DMG: SubscriptionId = 0xd48293d0, - [1697609772.052035][7767:7769] CHIP:DMG: MaxInterval = 0x64, - [1697609772.052038][7767:7769] CHIP:DMG: InteractionModelRevision = 11 - [1697609772.052040][7767:7769] CHIP:DMG: } - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event multi-press-ongoing 1 100 1 1 - - [1697609745.441125][7767:7769] CHIP:DMG: SubscribeResponseMessage = - [1697609745.441128][7767:7769] CHIP:DMG: { - [1697609745.441131][7767:7769] CHIP:DMG: SubscriptionId = 0x2161432e, - [1697609745.441134][7767:7769] CHIP:DMG: MaxInterval = 0x64, - [1697609745.441136][7767:7769] CHIP:DMG: InteractionModelRevision = 11 - [1697609745.441139][7767:7769] CHIP:DMG: } - - Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - - switch subscribe-event multi-press-complete 1 100 1 1 - - [1697609646.344664][7767:7769] CHIP:DMG: SubscribeResponseMessage = - [1697609646.344669][7767:7769] CHIP:DMG: { - [1697609646.344674][7767:7769] CHIP:DMG: SubscriptionId = 0x9177cb65, - [1697609646.344679][7767:7769] CHIP:DMG: MaxInterval = 0x64, - [1697609646.344684][7767:7769] CHIP:DMG: InteractionModelRevision = 11 - [1697609646.344688][7767:7769] CHIP:DMG: } - disabled: true - - - label: "Step 6b: Operator does not operate switch on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - no Matter messages for this step - disabled: true - - - label: "Step 6c: Operator operates switch (press briefly) on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697609895.678486][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697609895.678744][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0be - [1697609895.678786][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697609895.678800][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697609895.678917][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609895.678949][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001D priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B416F4EFE - - switch read-event initial-press 1 1 - - Verify TH receives InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697609943.498311][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697609943.498313][7767:7769] CHIP:TOO: Event number: 29 - [1697609943.498315][7767:7769] CHIP:TOO: Priority: Info - [1697609943.498317][7767:7769] CHIP:TOO: Timestamp: 1697609895678 - [1697609943.498320][7767:7769] CHIP:TOO: InitialPress: { - [1697609943.498323][7767:7769] CHIP:TOO: NewPosition: 1 - [1697609943.498325][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 6d: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697610020.642902][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697610020.643151][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bf - [1697610020.643184][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697610020.643194][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697610020.643356][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000005 due to overflow: event priority_level: 1 - [1697610020.643427][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610020.643456][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001E priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B41713723 - - switch read-event short-release 1 1 - - Verify TH receives ShortRelease event with PreviousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610069.134658][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697610069.134661][7767:7769] CHIP:TOO: Event number: 30 - [1697610069.134663][7767:7769] CHIP:TOO: Priority: Info - [1697610069.134665][7767:7769] CHIP:TOO: Timestamp: 1697610020643 - [1697610069.134669][7767:7769] CHIP:TOO: ShortRelease: { - [1697610069.134672][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697610069.134675][7767:7769] CHIP:TOO: } - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the MultiPressComplete event with PreviousPosition set to 1: - - [1697610133.480979][7384:7386] CHIP:-: Received payload: "{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":1}" - [1697610133.481239][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0c0 - [1697610133.481271][7384:7384] CHIP:-: The previous position when the momentary switch has been pressed in a multi-press sequence:1 - [1697610133.481280][7384:7384] CHIP:-: 1 times the momentary switch has been pressed - [1697610133.481287][7384:7384] CHIP:ZCL: SwitchServer: OnMultiPressComplete - [1697610133.481399][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610133.481431][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001F priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x6 Epoch timestamp: 0x0000018B4172EFE9 - - switch read-event multi-press-complete 1 1 - - Verify TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610193.287175][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0006 - [1697610193.287187][7767:7769] CHIP:TOO: Event number: 31 - [1697610193.287198][7767:7769] CHIP:TOO: Priority: Info - [1697610193.287207][7767:7769] CHIP:TOO: Timestamp: 1697610133481 - [1697610193.287241][7767:7769] CHIP:TOO: MultiPressComplete: { - [1697610193.287261][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697610193.287273][7767:7769] CHIP:TOO: TotalNumberOfPressesCounted: 1 - [1697610193.287285][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 6e: Operator operates switch (press briefly) on the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697609895.678486][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697609895.678744][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0be - [1697609895.678786][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697609895.678800][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697609895.678917][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609895.678949][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001D priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B416F4EFE - - switch read-event initial-press 1 1 - - Verify TH receives InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697609943.498311][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697609943.498313][7767:7769] CHIP:TOO: Event number: 29 - [1697609943.498315][7767:7769] CHIP:TOO: Priority: Info - [1697609943.498317][7767:7769] CHIP:TOO: Timestamp: 1697609895678 - [1697609943.498320][7767:7769] CHIP:TOO: InitialPress: { - [1697609943.498323][7767:7769] CHIP:TOO: NewPosition: 1 - [1697609943.498325][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 6f: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697610020.642902][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697610020.643151][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bf - [1697610020.643184][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697610020.643194][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697610020.643356][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000005 due to overflow: event priority_level: 1 - [1697610020.643427][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610020.643456][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001E priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B41713723 - - switch read-event short-release 1 1 - - Verify TH receives ShortRelease event with PreviousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610069.134658][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697610069.134661][7767:7769] CHIP:TOO: Event number: 30 - [1697610069.134663][7767:7769] CHIP:TOO: Priority: Info - [1697610069.134665][7767:7769] CHIP:TOO: Timestamp: 1697610020643 - [1697610069.134669][7767:7769] CHIP:TOO: ShortRelease: { - [1697610069.134672][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697610069.134675][7767:7769] CHIP:TOO: } - disabled: true - - - label: - "Step 6g: Briefly after 6f, Operator operates switch again on the - DUT(press briefly)" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697609895.678486][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697609895.678744][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0be - [1697609895.678786][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697609895.678800][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697609895.678917][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609895.678949][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001D priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B416F4EFE - - switch read-event initial-press 1 1 - - Verify TH receives InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697609943.498311][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697609943.498313][7767:7769] CHIP:TOO: Event number: 29 - [1697609943.498315][7767:7769] CHIP:TOO: Priority: Info - [1697609943.498317][7767:7769] CHIP:TOO: Timestamp: 1697609895678 - [1697609943.498320][7767:7769] CHIP:TOO: InitialPress: { - [1697609943.498323][7767:7769] CHIP:TOO: NewPosition: 1 - [1697609943.498325][7767:7769] CHIP:TOO: } - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"MultiPressOngoing","NewPosition":1,"CurrentNumberOfPressesCounted":2}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the MultiPressongoing event with NewPosition set to 1: - - [1697610439.738698][7384:7386] CHIP:-: Received payload: "{"Name":"MultiPressOngoing","NewPosition":1,"CurrentNumberOfPressesCounted":2}" - [1697610439.738953][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0c1 - [1697610439.738982][7384:7384] CHIP:-: The new position when the momentary switch has been pressed in a multi-press sequence:1 - [1697610439.738995][7384:7384] CHIP:-: 2 times the momentary switch has been pressed - [1697610439.739001][7384:7384] CHIP:ZCL: SwitchServer: OnMultiPressOngoing - [1697610439.739129][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000006 due to overflow: event priority_level: 1 - [1697610439.739190][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610439.739220][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000020 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x5 Epoch timestamp: 0x0000018B41779C3B - - switch read-event multi-press-ongoing 1 1 - - Verify TH receives MultiPressongoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 2 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610464.005842][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0005 - [1697610464.005846][7767:7769] CHIP:TOO: Event number: 32 - [1697610464.005848][7767:7769] CHIP:TOO: Priority: Info - [1697610464.005850][7767:7769] CHIP:TOO: Timestamp: 1697610439739 - [1697610464.005861][7767:7769] CHIP:TOO: MultiPressOngoing: { - [1697610464.005866][7767:7769] CHIP:TOO: NewPosition: 1 - [1697610464.005869][7767:7769] CHIP:TOO: CurrentNumberOfPressesCounted: 2 - [1697610464.005872][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 6h: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697610020.642902][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697610020.643151][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bf - [1697610020.643184][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697610020.643194][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697610020.643356][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000005 due to overflow: event priority_level: 1 - [1697610020.643427][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610020.643456][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001E priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B41713723 - - switch read-event short-release 1 1 - - Verify TH receives ShortRelease event with PreviousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610069.134658][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697610069.134661][7767:7769] CHIP:TOO: Event number: 30 - [1697610069.134663][7767:7769] CHIP:TOO: Priority: Info - [1697610069.134665][7767:7769] CHIP:TOO: Timestamp: 1697610020643 - [1697610069.134669][7767:7769] CHIP:TOO: ShortRelease: { - [1697610069.134672][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697610069.134675][7767:7769] CHIP:TOO: } - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":2}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 2 : - - [1697610593.918223][7384:7386] CHIP:-: Received payload: "{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":2}" - [1697610593.918505][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0c2 - [1697610593.918536][7384:7384] CHIP:-: The previous position when the momentary switch has been pressed in a multi-press sequence:1 - [1697610593.918545][7384:7384] CHIP:-: 2 times the momentary switch has been pressed - [1697610593.918552][7384:7384] CHIP:ZCL: SwitchServer: OnMultiPressComplete - [1697610593.918693][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000007 due to overflow: event priority_level: 1 - [1697610593.918774][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610593.918814][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000021 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x6 Epoch timestamp: 0x0000018B4179F67E - - switch read-event multi-press-complete 1 1 - - Verify TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 2 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610633.998752][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0006 - [1697610633.998762][7767:7769] CHIP:TOO: Event number: 33 - [1697610633.998769][7767:7769] CHIP:TOO: Priority: Info - [1697610633.998776][7767:7769] CHIP:TOO: Timestamp: 1697610593918 - [1697610633.998792][7767:7769] CHIP:TOO: MultiPressComplete: { - [1697610633.998803][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697610633.998811][7767:7769] CHIP:TOO: TotalNumberOfPressesCounted: 2 - [1697610633.998821][7767:7769] CHIP:TOO: } - disabled: true - - - label: - "Step 6i: If MultiPressMax == 2 (see 2c of TC-SWTCH-2.1), skip steps - 6j .. 6o" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - no Matter messages for this step - disabled: true - - - label: "Step 6j: Operator operates switch (press briefly) on the DUT" - PICS: "" - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697609895.678486][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697609895.678744][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0be - [1697609895.678786][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697609895.678800][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697609895.678917][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609895.678949][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001D priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B416F4EFE - - switch read-event initial-press 1 1 - - Verify TH receives InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697609943.498311][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697609943.498313][7767:7769] CHIP:TOO: Event number: 29 - [1697609943.498315][7767:7769] CHIP:TOO: Priority: Info - [1697609943.498317][7767:7769] CHIP:TOO: Timestamp: 1697609895678 - [1697609943.498320][7767:7769] CHIP:TOO: InitialPress: { - [1697609943.498323][7767:7769] CHIP:TOO: NewPosition: 1 - [1697609943.498325][7767:7769] CHIP:TOO: } - disabled: true - - - label: "Step 6k: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697610020.642902][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697610020.643151][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bf - [1697610020.643184][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697610020.643194][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697610020.643356][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000005 due to overflow: event priority_level: 1 - [1697610020.643427][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610020.643456][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001E priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B41713723 - - switch read-event short-release 1 1 - - Verify TH receives ShortRelease event with PreviousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610069.134658][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697610069.134661][7767:7769] CHIP:TOO: Event number: 30 - [1697610069.134663][7767:7769] CHIP:TOO: Priority: Info - [1697610069.134665][7767:7769] CHIP:TOO: Timestamp: 1697610020643 - [1697610069.134669][7767:7769] CHIP:TOO: ShortRelease: { - [1697610069.134672][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697610069.134675][7767:7769] CHIP:TOO: } - disabled: true - - - label: - "Step 6l: Briefly after 6k, operator operates switch again on the DUT - (press briefly)" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697609895.678486][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697609895.678744][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0be - [1697609895.678786][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697609895.678800][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697609895.678917][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609895.678949][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001D priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B416F4EFE - - switch read-event initial-press 1 1 - - Verify TH receives InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697609943.498311][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697609943.498313][7767:7769] CHIP:TOO: Event number: 29 - [1697609943.498315][7767:7769] CHIP:TOO: Priority: Info - [1697609943.498317][7767:7769] CHIP:TOO: Timestamp: 1697609895678 - [1697609943.498320][7767:7769] CHIP:TOO: InitialPress: { - [1697609943.498323][7767:7769] CHIP:TOO: NewPosition: 1 - [1697609943.498325][7767:7769] CHIP:TOO: } - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"MultiPressOngoing","NewPosition":1,"CurrentNumberOfPressesCounted":2}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the MultiPressongoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 2: - - [1697611293.571665][7384:7386] CHIP:-: Received payload: "{"Name":"MultiPressOngoing","NewPosition":1,"CurrentNumberOfPressesCounted":2}" - [1697611293.571907][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0c4 - [1697611293.571940][7384:7384] CHIP:-: The new position when the momentary switch has been pressed in a multi-press sequence:1 - [1697611293.571949][7384:7384] CHIP:-: 2 times the momentary switch has been pressed - [1697611293.571955][7384:7384] CHIP:ZCL: SwitchServer: OnMultiPressOngoing - [1697611293.572127][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x000000000000000A due to overflow: event priority_level: 1 - [1697611293.572215][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697611293.572258][7384:7384] CHIP:EVL: LogEvent event number: 0x0000000000000023 priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x5 Epoch timestamp: 0x0000018B4184A383 - - switch read-event multi-press-ongoing 1 1 - - Verify MultiPressongoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 2 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1659695330.923244][3912:3918] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0005 - [1659695330.923264][3912:3918] CHIP:TOO: Event number: 45 - [1659695330.923283][3912:3918] CHIP:TOO: Priority: Info - [1659695330.923302][3912:3918] CHIP:TOO: Timestamp: 17754336 - [1659695330.923326][3912:3918] CHIP:TOO: MultiPressOngoing: { - [1659695330.923346][3912:3918] CHIP:TOO: NewPosition: 1 - [1659695330.923366][3912:3918] CHIP:TOO: CurrentNumberOfPressesCounted: 2 - [1659695330.923385][3912:3918] CHIP:TOO: } - disabled: true - - - label: "Step 6m: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697610020.642902][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697610020.643151][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bf - [1697610020.643184][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697610020.643194][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697610020.643356][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000005 due to overflow: event priority_level: 1 - [1697610020.643427][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610020.643456][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001E priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B41713723 - - switch read-event short-release 1 1 - - Verify TH receives ShortRelease event with PreviousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610069.134658][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697610069.134661][7767:7769] CHIP:TOO: Event number: 30 - [1697610069.134663][7767:7769] CHIP:TOO: Priority: Info - [1697610069.134665][7767:7769] CHIP:TOO: Timestamp: 1697610020643 - [1697610069.134669][7767:7769] CHIP:TOO: ShortRelease: { - [1697610069.134672][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697610069.134675][7767:7769] CHIP:TOO: } - disabled: true - - - label: - "Step 6n: Briefly after 6m, operator operates switch again (press - briefly)" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"InitialPress","NewPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the InitialPress event with NewPosition set to 1: - - [1697609895.678486][7384:7386] CHIP:-: Received payload: "{"Name":"InitialPress","NewPosition":1}" - [1697609895.678744][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0be - [1697609895.678786][7384:7384] CHIP:-: The new position when the momentary switch starts to be pressed:1 - [1697609895.678800][7384:7384] CHIP:ZCL: SwitchServer: OnInitialPress - [1697609895.678917][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697609895.678949][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001D priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x1 Epoch timestamp: 0x0000018B416F4EFE - - switch read-event initial-press 1 1 - - Verify TH receives InitialPress event with NewPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697609943.498311][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0001 - [1697609943.498313][7767:7769] CHIP:TOO: Event number: 29 - [1697609943.498315][7767:7769] CHIP:TOO: Priority: Info - [1697609943.498317][7767:7769] CHIP:TOO: Timestamp: 1697609895678 - [1697609943.498320][7767:7769] CHIP:TOO: InitialPress: { - [1697609943.498323][7767:7769] CHIP:TOO: NewPosition: 1 - [1697609943.498325][7767:7769] CHIP:TOO: } - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"MultiPressOngoing","NewPosition":1,"CurrentNumberOfPressesCounted":3}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the MultiPressongoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 3: - - [1686290991.699382][30125:30127] CHIP:-: Received payload: "{"Name":"MultiPressOngoing","NewPosition":1,"CurrentNumberOfPressesCounted":3}" - [1686290991.699646][30125:30125] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 89759738 - [1686290991.699678][30125:30125] CHIP:-: The new position when the momentary switch has been pressed in a multi-press sequence:1 - [1686290991.699687][30125:30125] CHIP:-: 3 times the momentary switch has been pressed - [1686290991.699694][30125:30125] CHIP:ZCL: SwitchServer: OnMultiPressOngoing - - switch read-event multi-press-ongoing 1 1 - - Verify TH receives MultiPressongoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 3 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1659698336.786184][4081:4086] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0005 - [1659698336.786209][4081:4086] CHIP:TOO: Event number: 57 - [1659698336.786233][4081:4086] CHIP:TOO: Priority: Info - [1659698336.786256][4081:4086] CHIP:TOO: Timestamp: 20718400 - [1659698336.786287][4081:4086] CHIP:TOO: MultiPressOngoing: { - [1659698336.786312][4081:4086] CHIP:TOO: NewPosition: 1 - [1659698336.786337][4081:4086] CHIP:TOO: CurrentNumberOfPressesCounted: 3 - [1659698336.786360][4081:4086] CHIP:TOO: } - disabled: true - - - label: "Step 6o: Operator releases switch from the DUT" - PICS: SWTCH.S.F01 && SWTCH.S.F04 - verification: | - Note : Please skip this step if LATCH SWITCH feature is implemented, because a device can support either a latching switch or a momentary switch. - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"ShortRelease","PreviousPosition":1}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - DUT generated the ShortRelease event with PreviousPosition set to 1: - - [1697610020.642902][7384:7386] CHIP:-: Received payload: "{"Name":"ShortRelease","PreviousPosition":1}" - [1697610020.643151][7384:7384] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to 4dbcc0bf - [1697610020.643184][7384:7384] CHIP:-: The the previous value of the CurrentPosition when the momentary switch has been released:1 - [1697610020.643194][7384:7384] CHIP:ZCL: SwitchServer: OnShortRelease - [1697610020.643356][7384:7384] CHIP:EVL: Dropped 1 event from buffer with priority 1 and event number 0x0000000000000005 due to overflow: event priority_level: 1 - [1697610020.643427][7384:7384] CHIP:EVL: Copy Event to next buffer with priority 1 - [1697610020.643456][7384:7384] CHIP:EVL: LogEvent event number: 0x000000000000001E priority: 1, endpoint id: 0x1 cluster id: 0x0000_003B event id: 0x3 Epoch timestamp: 0x0000018B41713723 - - switch read-event short-release 1 1 - - Verify TH receives ShortRelease event with PreviousPosition set to 1 on TH chip-tool log and below is the sample log provided for the raspi platform: - - [1697610069.134658][7767:7769] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0003 - [1697610069.134661][7767:7769] CHIP:TOO: Event number: 30 - [1697610069.134663][7767:7769] CHIP:TOO: Priority: Info - [1697610069.134665][7767:7769] CHIP:TOO: Timestamp: 1697610020643 - [1697610069.134669][7767:7769] CHIP:TOO: ShortRelease: { - [1697610069.134672][7767:7769] CHIP:TOO: PreviousPosition: 1 - [1697610069.134675][7767:7769] CHIP:TOO: } - - - On Raspi platform To trigger the event give the below command by opening an another terminal in DUT (Below is the example command developed in all-clusters-app to generate the event, Vendor Dut should have capability to generate this event) - - echo '{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":3}' > /tmp/chip_all_clusters_fifo_ (PID of DUT) - - Verify MultiPressonComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 3 on TH (all-cluster-app) log and below is the sample log provided for the raspi platform: - - [1659694592.347850][2530:2538] CHIP:-: Received payload: "{"Name":"MultiPressComplete","PreviousPosition":1,"TotalNumberOfPressesCounted":3}" - [1659694592.348389][2530:2530] CHIP:DMG: Endpoint 1, Cluster 0x0000_003B update version to ee5e772b - [1659694592.348481][2530:2530] CHIP:-: The new position when the momentary switch has been pressed in a multi-press sequence:1 - - switch read-event multi-press-complete 1 1 - - Verify TH receives MultiPressonComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 3 on TH (chip-tool) log and below is the sample log provided for the raspi platform: - - [1659695330.923244][3912:3918] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_003B Event 0x0000_0005 - [1659695330.923264][3912:3918] CHIP:TOO: Event number: 45 - [1659695330.923283][3912:3918] CHIP:TOO: Priority: Info - [1659695330.923302][3912:3918] CHIP:TOO: Timestamp: 17754336 - [1659695330.923326][3912:3918] CHIP:TOO: MultiPressComplete: { - [1659695330.923346][3912:3918] CHIP:TOO: PreviousPosition: 1 - [1659695330.923366][3912:3918] CHIP:TOO: TotalNumberOfPressesCounted: 3 - [1659695330.923385][3912:3918] CHIP:TOO: } - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml index 81011a13251a70..bdb3d2b8ad90db 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml @@ -302,6 +302,27 @@ tests: - name: "SceneID" value: 0x01 + - label: + "Step 2d: TH sends a StoreScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0xFF, which is outside of the + constraints for a SceneID." + PICS: S.S.C04.Rsp + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: GI + - name: "SceneID" + value: 0xFF + response: + values: + - name: "Status" + value: 0x87 + - name: "GroupID" + value: GI + - name: "SceneID" + value: 0xFF + - label: "Step 3a: TH configures AC2 on DUT for all implemented application clusters supporting scenes." @@ -444,6 +465,21 @@ tests: - name: "SceneID" value: 0x01 + - label: + "Step 4e: TH sends a RecallScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0xFF, which is outside of the + constraints for a SceneID." + PICS: S.S.C05.Rsp + command: "RecallScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0xFF + response: + error: CONSTRAINT_ERROR + - label: "Step 5a: TH sends a ViewScene command to DUT with the GroupID field set to G1 and the SceneID field set to 0x01." @@ -555,6 +591,27 @@ tests: - name: "SceneID" value: 0xFE + - label: + "Step 5d: TH sends a ViewScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0xFF, which is outside of the + constraints for a SceneID." + PICS: S.S.C01.Rsp + command: "ViewScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0xFF + response: + values: + - name: "Status" + value: 0x87 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0xFF + - label: "Step 6: TH sends a GetSceneMembership command to DUT with the GroupID field set to G1." @@ -734,7 +791,7 @@ tests: "Step 8d: TH sends a AddScene command to DUT with the GroupID field set to G1, the SceneID field set to 0x01, the TransitionTime field set to 70 000 000 (70 000s) and no extension field sets. This should fail - and return a status of 0x85 (INVALID_COMMAND)." + and return a status of 0x87 (CONSTRAINT_ERROR)." PICS: S.S.C00.Rsp command: "AddScene" arguments: @@ -752,7 +809,7 @@ tests: response: values: - name: "Status" - value: 0x85 + value: 0x87 - name: "GroupID" value: G1 - name: "SceneID" @@ -762,7 +819,7 @@ tests: "Step 8e: TH sends a AddScene command to DUT with the GroupID field set to G1, the SceneID field set to 0x01, the TransitionTime field set to 60 000 001 (60 000.001s) and no extension field sets. This should - fail and return a status of 0x85 (INVALID_COMMAND)." + fail and return a status of 0x87 (CONSTRAINT_ERROR)." PICS: S.S.C00.Rsp command: "AddScene" arguments: @@ -780,12 +837,41 @@ tests: response: values: - name: "Status" - value: 0x85 + value: 0x87 - name: "GroupID" value: G1 - name: "SceneID" value: 0x01 + - label: + "Step 8f: TH sends a AddScene command to DUT with the GroupID field + set to G1, the SceneID field set to 0xFF, which is outside of the + constraints for a SceneID, the TransitionTime field set to 1000 (1s) + and no extension field sets. This should fail and return a status of + 0x87 (CONSTRAINT_ERROR)." + PICS: S.S.C00.Rsp + command: "AddScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0xFF + - name: "TransitionTime" + value: 1000 + - name: "SceneName" + value: "Scene1" + - name: "ExtensionFieldSets" + value: [] + response: + values: + - name: "Status" + value: 0x87 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0xFF + - label: "Step 9a: TH sends a RemoveScene command to DUT with the GroupID field set to G1 and the SceneID field set to 0x01." @@ -848,7 +934,28 @@ tests: value: 0x01 - label: - "Step 9d: TH sends a GetSceneMembership command to DUT with the + "Step 9d: TH sends a RemoveScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0xFF, which is outside of the + constraints for a SceneID." + PICS: S.S.C02.Rsp + command: "RemoveScene" + arguments: + values: + - name: "GroupID" + value: GI + - name: "SceneID" + value: 0xFF + response: + values: + - name: "Status" + value: 0x87 + - name: "GroupID" + value: GI + - name: "SceneID" + value: 0xFF + + - label: + "Step 9e: TH sends a GetSceneMembership command to DUT with the GroupID field set to G1." PICS: S.S.C06.Rsp command: "GetSceneMembership" diff --git a/src/app/tests/suites/certification/Test_TC_THNETDIR_2_1.yaml b/src/app/tests/suites/certification/Test_TC_THNETDIR_2_1.yaml new file mode 100644 index 00000000000000..3a2925dc424175 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_THNETDIR_2_1.yaml @@ -0,0 +1,51 @@ +# 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. + +name: "[TC-THNETDIR-2.1] Simple Attributes check with DUT as Server" + +PICS: + - THNETDIR.S + +config: + nodeId: 0x12344321 + cluster: Thread Network Directory + endpoint: 1 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: DelayCommands + command: WaitForCommissionee + arguments: + values: + - name: nodeId + value: nodeId + + - label: "TH reads SupportedFabrics attribute from DUT" + command: readAttribute + endpoint: 0 + cluster: Operational Credentials + attribute: SupportedFabrics + response: + saveAs: supportedFabrics + constraints: + type: int8u + + - label: "TH reads ThreadNetworkTableSize attribute from DUT" + command: readAttribute + attribute: ThreadNetworkTableSize + response: + constraints: + type: int8u + minValue: 10 # assume 5 supported fabrics + # python: value >= 2 * supportedFabrics diff --git a/src/app/tests/suites/certification/Test_TC_THNETDIR_2_2.yaml b/src/app/tests/suites/certification/Test_TC_THNETDIR_2_2.yaml new file mode 100644 index 00000000000000..be0ec89952d25e --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_THNETDIR_2_2.yaml @@ -0,0 +1,225 @@ +# 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. + +name: "[TC-THNETDIR-2.2] Verification for Add/Remove/Get commands" + +PICS: + - THNETDIR.S + +config: + nodeId: 0x12344321 + cluster: Thread Network Directory + endpoint: 1 + + # Note: TestNetwork* values need to match what's encoded in TestNetworkDataset + TestNetworkDataset: + type: octet_string + defaultValue: "hex:0e080000000000000001000300000f350407fff800020839758ec8144b07fb0708fdf1f1add0797dc00510f366cec7a446bab978d90d27abe38f23030f4f70656e5468726561642d353933380102593804103ca67c969efb0d0c74a4d8ee923b576c0c0402a0f7f8" + TestNetworkExtendedPanId: + type: octet_string + defaultValue: "hex:39758ec8144b07fb" + TestNetworkName: "OpenThread-5938" + TestNetworkChannel: 15 + TestNetworkActiveTimestamp: 1 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: DelayCommands + command: WaitForCommissionee + arguments: + values: + - name: nodeId + value: nodeId + + - label: "TH reads ThreadNetworks attribute from DUT" + command: readAttribute + attribute: ThreadNetworks + response: + saveAs: initialNetworks + constraints: + type: list + + - label: "TH reads PreferredExtendedPanID attribute from DUT" + command: readAttribute + attribute: PreferredExtendedPanID + response: + saveAs: initialPreferredExtendedPanID + constraints: + type: octet_string + minLength: 8 + maxLength: 8 + notValue: TestNetworkExtendedPanId + + - label: + "TH writes ExtendedPanID from TestNetwork to PreferredExtendedPanID on + DUT" + command: writeAttribute + attribute: PreferredExtendedPanID + arguments: + value: TestNetworkExtendedPanId + response: + error: CONSTRAINT_ERROR # TestNetwork is not in ThreadNetworks + + - label: + "TH reads PreferredExtendedPanID attribute from DUT, verifying that + the value did not change" + command: readAttribute + attribute: PreferredExtendedPanID + response: + value: initialPreferredExtendedPanID + + - label: + "TH sends GetOperationalDataset command to DUT with ExtendedPanID of + TestNetwork" + command: GetOperationalDataset + arguments: + values: + - name: ExtendedPanID + value: TestNetworkExtendedPanId + response: + error: NOT_FOUND + + # TODO: Currently fails with darwin-framework-tool because it automatically performs a timed invoke + # - label: "TH sends AddNetwork command to DUT without a timed interaction" + # command: AddNetwork + # arguments: + # values: + # - name: OperationalDataset + # value: TestNetworkDataset + # response: + # error: NEEDS_TIMED_INTERACTION + + - label: "TH sends AddNetwork command to DUT with TestNetwork dataset" + command: AddNetwork + timedInteractionTimeoutMs: 2000 + arguments: + values: + - name: OperationalDataset + value: TestNetworkDataset + + - label: + "TH reads ThreadNetworks attribute from DUT, verifying that the + network has been added" + command: readAttribute + attribute: ThreadNetworks + response: + constraints: + type: list + # python: | + # # Split the list into test (our TestNetwork) and rest (everything else) + # test = next((n for n in value if n['ExtendedPanID'] == TestNetworkExtendedPanId), None) + # rest = [n for n in value if n != test] + # # Check test has the expected values and rest == initialNetworks (ignoring order) + # return (test is not None and + # test['NetworkName'] == TestNetworkName and + # test['Channel'] == TestNetworkChannel and + # test['ActiveTimestamp'] == TestNetworkActiveTimestamp and + # len(value) == len(initialNetworks) + 1 and + # len(rest) == len(initialNetworks) and + # all(n in initialNetworks for n in rest)) + + - label: + "TH sends GetOperationalDataset command to DUT with ExtendedPanID from + TestNetwork" + command: GetOperationalDataset + arguments: + values: + - name: ExtendedPanID + value: TestNetworkExtendedPanId + response: + values: + - name: OperationalDataset + value: TestNetworkDataset + + - label: + "TH writes ExtendedPanID from TestNetwork to PreferredExtendedPanID on + DUT" + command: writeAttribute + attribute: PreferredExtendedPanID + arguments: + value: TestNetworkExtendedPanId + + - label: + "TH reads PreferredExtendedPanID attribute from DUT, verifying that + the value was written" + command: readAttribute + attribute: PreferredExtendedPanID + response: + value: TestNetworkExtendedPanId + + # TODO: Currently fails with darwin-framework-tool because it automatically performs a timed invoke + # - label: "TH sends RemoveNetwork command to DUT without a timed interaction" + # command: RemoveNetwork + # arguments: + # values: + # - name: ExtendedPanID + # value: TestNetworkExtendedPanId + # response: + # error: NEEDS_TIMED_INTERACTION + + - label: + "TH sends RemoveNetwork command to DUT with ExtendedPanID of + TestNetwork while it is the preferred network" + command: RemoveNetwork + timedInteractionTimeoutMs: 2000 + arguments: + values: + - name: ExtendedPanID + value: TestNetworkExtendedPanId + response: + error: CONSTRAINT_ERROR # Preferred network cannot be removed + + - label: "TH writes null to PreferredExtendedPanID on DUT" + command: writeAttribute + attribute: PreferredExtendedPanID + arguments: + value: null + + - label: + "TH reads PreferredExtendedPanID attribute from DUT, verifying that + the value was cleared" + command: readAttribute + attribute: PreferredExtendedPanID + response: + value: null + + - label: + "TH sends RemoveNetwork command to DUT with ExtendedPanID of + TestNetwork" + command: RemoveNetwork + timedInteractionTimeoutMs: 2000 + arguments: + values: + - name: ExtendedPanID + value: TestNetworkExtendedPanId + + - label: + "TH reads ThreadNetworks attribute from DUT, verifying that the + network was removed" + command: readAttribute + attribute: ThreadNetworks + response: + constraints: + type: list + # python: | + # # value == initialNetworks (ignoring order) + # return (len(value) == len(initialNetworks) and + # all(n in initialNetworks for n in value)) + + - label: + "TH writes PreferredExtendedPanID to DUT, restoring the initial value" + command: writeAttribute + attribute: PreferredExtendedPanID + arguments: + value: initialPreferredExtendedPanID diff --git a/src/app/tests/suites/certification/Test_TC_WIFINM_2_1.yaml b/src/app/tests/suites/certification/Test_TC_WIFINM_2_1.yaml new file mode 100644 index 00000000000000..0f9f71157de0ea --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_WIFINM_2_1.yaml @@ -0,0 +1,63 @@ +# 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. + +name: "[TC-WIFINM-2.1] Attributes and commands with DUT as Server" + +PICS: + - WIFINM.S + +config: + nodeId: 0x12344321 + cluster: WiFi Network Management + endpoint: 1 + +# Note: This test assumes the DUT has an active Wi-Fi network, i.e. +# SSID is not null and NetworkPassphraseRequest returns a passphrase. +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: DelayCommands + command: WaitForCommissionee + arguments: + values: + - name: nodeId + value: nodeId + + - label: "TH reads the SSID attribute from the DUT" + command: readAttribute + attribute: SSID + response: + constraints: + type: octet_string + hasValue: true + minLength: 1 + maxLength: 32 + + - label: "TH reads the PassphraseSurrogate attribute from the DUT" + command: readAttribute + attribute: PassphraseSurrogate + response: + constraints: + type: int64u + hasValue: true + + - label: "TH sends the NetworkPassphraseRequest command to the DUT" + command: NetworkPassphraseRequest + response: + values: + - name: Passphrase + constraints: + type: octet_string + hasValue: true + minLength: 8 + maxLength: 64 diff --git a/src/app/tests/suites/certification/ci-pics-values b/src/app/tests/suites/certification/ci-pics-values index 207999a74778b1..152544521f1453 100644 --- a/src/app/tests/suites/certification/ci-pics-values +++ b/src/app/tests/suites/certification/ci-pics-values @@ -713,6 +713,7 @@ SWTCH.S.F01=0 SWTCH.S.F02=0 SWTCH.S.F03=0 SWTCH.S.F04=0 +SWTCH.S.F05=0 SWTCH.C=0 SWTCH.C.F00=1 @@ -2987,4 +2988,10 @@ PWRTL.S.A0001=1 PWRTL.S.F00=0 PWRTL.S.F01=0 PWRTL.S.F02=1 -PWRTL.S.F03=1 \ No newline at end of file +PWRTL.S.F03=1 + +# Thread Network Directory Cluster +THNETDIR.S=1 + +# Wi-Fi Network Management Cluster +WIFINM.S=1 diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index a12d2b75b8a90f..7b99318fe6c9fd 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -281,7 +281,7 @@ "Test_TC_TCCM_1_2", "Test_TC_TCCM_2_1" ], - "Switch": ["Test_TC_SWTCH_2_2", "Test_TC_SWTCH_3_2"], + "Switch": ["Test_TC_SWTCH_3_2"], "TemperatureControl": [], "TemperatureMeasurement": ["Test_TC_TMP_2_2"], "Thermostat": ["Test_TC_TSTAT_3_2"], diff --git a/src/app/util/af-types.h b/src/app/util/af-types.h index 929ad055d0fc1e..bd5b5ed68ce4bb 100644 --- a/src/app/util/af-types.h +++ b/src/app/util/af-types.h @@ -307,6 +307,11 @@ enum class MarkAttributeDirty { kIfChanged, kNo, + // kYes might need to be used if the attribute value was previously changed + // without reporting, and now is being set in a situation where we know + // reporting needs to be triggered (e.g. because QuieterReportingAttribute + // indicated that). + kYes, }; } // namespace app diff --git a/src/app/util/attribute-table.cpp b/src/app/util/attribute-table.cpp index 57b5f43d35071f..303b234ff93862 100644 --- a/src/app/util/attribute-table.cpp +++ b/src/app/util/attribute-table.cpp @@ -407,7 +407,12 @@ Status emAfWriteAttribute(EndpointId endpoint, ClusterId cluster, AttributeId at if (!valueChanging) { - // Just do nothing. + // Just do nothing, except triggering reporting if forced. + if (markDirty == MarkAttributeDirty::kYes) + { + MatterReportingAttributeChangeCallback(endpoint, cluster, attributeID); + } + return Status::Success; } diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp index f903b5b52ea8da..763e198f41fded 100644 --- a/src/app/util/util.cpp +++ b/src/app/util/util.cpp @@ -139,6 +139,7 @@ void MatterEnergyEvseModePluginServerInitCallback() {} void MatterPowerTopologyPluginServerInitCallback() {} void MatterElectricalEnergyMeasurementPluginServerInitCallback() {} void MatterElectricalPowerMeasurementPluginServerInitCallback() {} +void MatterServiceAreaPluginServerInitCallback() {} void MatterWaterHeaterManagementPluginServerInitCallback() {} void MatterWaterHeaterModePluginServerInitCallback() {} diff --git a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml index 17cef9f767ee54..a1595803109bcc 100644 --- a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml @@ -20,7 +20,7 @@ limitations under the License. - + @@ -33,6 +33,14 @@ limitations under the License. + + + + + + + + @@ -49,8 +57,8 @@ limitations under the License. - - + + @@ -60,16 +68,45 @@ limitations under the License. + + + + + + + + + + + + + + + + + + + + General Access Control 0x001F ACCESS_CONTROL_CLUSTER true + + + + + + + + true + The Access Control Cluster exposes a data model view of a - Node's Access Control List (ACL), which codifies the rules used to manage - and enforce Access Control for the Node's endpoints and their associated + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated cluster instances. @@ -84,36 +121,52 @@ limitations under the License. - - SubjectsPerAccessControlEntry - - + SubjectsPerAccessControlEntry + TargetsPerAccessControlEntry + AccessControlEntriesPerFabric + CommissioningARL + ARL - - TargetsPerAccessControlEntry - - + + This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. + + + - - AccessControlEntriesPerFabric - - + + Returns the review token for the request, which can be used to correlate with a FabricRestrictionReviewUpdate event. + + - + The cluster SHALL send AccessControlEntryChanged events whenever its ACL attribute data is changed by an Administrator. - + - + + The cluster SHALL send AccessControlExtensionChanged events whenever its extension attribute data is changed by an Administrator. - + + + + The cluster SHALL send AccessRestrictionEntryChanged events whenever its ARL attribute data is changed by the device maker. + + + + + The cluster SHALL send FabricRestrictionReviewUpdate events to indicate completion of a fabric restriction review. + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml b/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml index ff118a8a80c162..74f88bea39e623 100644 --- a/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml +++ b/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml @@ -96,6 +96,7 @@ limitations under the License. The server SHALL attempt to keep the devices specified active for StayActiveDuration milliseconds when they are next active. + diff --git a/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml index eabc56a4d95916..da813b60fef2e4 100644 --- a/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml @@ -1,6 +1,6 @@ @@ -513,10 +507,6 @@ limitations under the License. This command is used to notify the server that all edits are done and should be committed. - - This command sets the set point hold policy. - - diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml index e97cbc931e6b0e..3a6445b15bbad3 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml @@ -17,7 +17,7 @@ limitations under the License. - + @@ -25,7 +25,7 @@ limitations under the License. - + Network Infrastructure Thread Network Directory 0x0453 @@ -59,7 +59,7 @@ limitations under the License. - + Retrieves a Thread Operational Dataset from the ThreadNetworks list. diff --git a/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml index f05faad4dae4d2..8c8b4d40c3abdd 100644 --- a/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml @@ -17,7 +17,7 @@ limitations under the License. - + Network Infrastructure Wi-Fi Network Management 0x0451 @@ -30,11 +30,15 @@ limitations under the License. - SSID + SSID + + PassphraseSurrogate + + Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. - + This is the response to a NetworkPassphraseRequest. 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 2207303e1ab7b7..4c5a59200e7d49 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -301,6 +301,14 @@ "general_error_boolean", "cluster_error_boolean" ], + "Thread Border Router Management": [ + "BorderRouterName", + "BorderAgentID", + "ThreadVersion", + "InterfaceEnabled", + "ActiveDatasetTimestamp", + "FeatureMap" + ], "Thread Network Diagnostics": [ "Channel", "RoutingRole", @@ -656,12 +664,13 @@ "ClusterRevision" ], "Water Heater Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], - "Wi-Fi Network Management": ["SSID"], + "Wi-Fi Network Management": ["SSID", "PassphraseSurrogate"], "Thread Network Directory": [ "PreferredExtendedPanID", "ThreadNetworks", "ThreadNetworkTableSize" - ] + ], + "Service Area": ["CurrentLocation", "EstimatedEndTime", "FeatureMap"] }, "defaultReportingPolicy": "mandatory", "ZCLDataTypes": ["ARRAY", "BITMAP", "ENUM", "NUMBER", "STRING", "STRUCT"], diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index c2bcc194e8611f..777847fb7f06ad 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -299,6 +299,14 @@ "general_error_boolean", "cluster_error_boolean" ], + "Thread Border Router Management": [ + "BorderRouterName", + "BorderAgentID", + "ThreadVersion", + "InterfaceEnabled", + "ActiveDatasetTimestamp", + "FeatureMap" + ], "Thread Network Diagnostics": [ "Channel", "RoutingRole", @@ -654,12 +662,13 @@ "ClusterRevision" ], "Water Heater Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], - "Wi-Fi Network Management": ["SSID"], + "Wi-Fi Network Management": ["SSID", "PassphraseSurrogate"], "Thread Network Directory": [ "PreferredExtendedPanID", "ThreadNetworks", "ThreadNetworkTableSize" - ] + ], + "Service Area": ["CurrentLocation", "EstimatedEndTime", "FeatureMap"] }, "defaultReportingPolicy": "mandatory", "ZCLDataTypes": ["ARRAY", "BITMAP", "ENUM", "NUMBER", "STRING", "STRUCT"], diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index eb9db222477ffe..e5f0ea9e2e892a 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -72,7 +72,7 @@ "NETWORK_COMMISSIONING_CLUSTER": [], "SAMPLE_MEI_CLUSTER": [], "NITROGEN_DIOXIDE_CONCENTRATION_MEASUREMENT_CLUSTER": [], - "OCCUPANCY_SENSING_CLUSTER": ["occupancy-sensor-server"], + "OCCUPANCY_SENSING_CLUSTER": [], "ON_OFF_CLUSTER": [], "ON_OFF_SWITCH_CONFIGURATION_CLUSTER": [], "OPERATIONAL_CREDENTIALS_CLUSTER": [], @@ -108,6 +108,7 @@ "RVC_CLEAN_MODE_CLUSTER": [], "RVC_RUN_MODE_CLUSTER": [], "SCENES_CLUSTER": [], + "SERVICE_AREA_CLUSTER": [], "SMOKE_CO_ALARM_CLUSTER": [], "SOFTWARE_DIAGNOSTICS_CLUSTER": [], "SWITCH_CLUSTER": [], @@ -284,6 +285,7 @@ "RVC_CLEAN_MODE_CLUSTER": ["mode-base-server"], "RVC_RUN_MODE_CLUSTER": ["mode-base-server"], "SCENES_CLUSTER": ["scenes-server"], + "SERVICE_AREA_CLUSTER": ["service-area-server"], "SMOKE_CO_ALARM_CLUSTER": ["smoke-co-alarm-server"], "SOFTWARE_DIAGNOSTICS_CLUSTER": ["software-diagnostics-server"], "SWITCH_CLUSTER": ["switch-server"], @@ -294,7 +296,9 @@ "THERMOSTAT_USER_INTERFACE_CONFIGURATION_CLUSTER": [ "thermostat-user-interface-configuration-server" ], - "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER": [], + "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER": [ + "thread-border-router-management-server" + ], "THREAD_NETWORK_DIAGNOSTICS_CLUSTER": [ "thread-network-diagnostics-server" ], diff --git a/src/controller/AutoCommissioner.cpp b/src/controller/AutoCommissioner.cpp index 8232292479ff3f..0e83d7125cf175 100644 --- a/src/controller/AutoCommissioner.cpp +++ b/src/controller/AutoCommissioner.cpp @@ -590,11 +590,16 @@ CHIP_ERROR AutoCommissioner::StartCommissioning(DeviceCommissioner * commissione mStopCommissioning = false; mCommissioner = commissioner; mCommissioneeDeviceProxy = proxy; - mNeedsNetworkSetup = - mCommissioneeDeviceProxy->GetSecureSession().Value()->AsSecureSession()->GetPeerAddress().GetTransportType() == - Transport::Type::kBle; + + auto transportType = + mCommissioneeDeviceProxy->GetSecureSession().Value()->AsSecureSession()->GetPeerAddress().GetTransportType(); + mNeedsNetworkSetup = (transportType == Transport::Type::kBle); +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + mNeedsNetworkSetup = mNeedsNetworkSetup || (transportType == Transport::Type::kWiFiPAF); +#endif CHIP_ERROR err = CHIP_NO_ERROR; CommissioningStage nextStage = GetNextCommissioningStage(CommissioningStage::kSecurePairing, err); + mCommissioner->PerformCommissioningStep(mCommissioneeDeviceProxy, nextStage, mParams, this, GetEndpoint(nextStage), GetCommandTimeout(mCommissioneeDeviceProxy, nextStage)); return CHIP_NO_ERROR; diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 5212350c913696..955e36bfb0d8a2 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -66,6 +66,9 @@ #include #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#include +#endif #include #include @@ -466,6 +469,13 @@ DeviceCommissioner::DeviceCommissioner() : mDeviceNOCChainCallback(OnDeviceNOCChainGeneration, this), mSetUpCodePairer(this) {} +DeviceCommissioner::~DeviceCommissioner() +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + DeviceLayer::ConnectivityMgr().WiFiPAFCancelConnect(); +#endif +} + CHIP_ERROR DeviceCommissioner::Init(CommissionerInitParams params) { VerifyOrReturnError(params.operationalCredentialsDelegate != nullptr, CHIP_ERROR_INVALID_ARGUMENT); @@ -730,6 +740,12 @@ CHIP_ERROR DeviceCommissioner::EstablishPASEConnection(NodeId remoteDeviceId, Re peerAddress = Transport::PeerAddress::UDP(params.GetPeerAddress().GetIPAddress(), params.GetPeerAddress().GetPort(), params.GetPeerAddress().GetInterface()); } +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + else if (params.GetPeerAddress().GetTransportType() == Transport::Type::kWiFiPAF) + { + peerAddress = Transport::PeerAddress::WiFiPAF(remoteDeviceId); + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF current = FindCommissioneeDevice(peerAddress); if (current != nullptr) @@ -804,6 +820,24 @@ CHIP_ERROR DeviceCommissioner::EstablishPASEConnection(NodeId remoteDeviceId, Re ExitNow(err = CHIP_ERROR_INVALID_ARGUMENT); } } +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + if (params.GetPeerAddress().GetTransportType() == Transport::Type::kWiFiPAF) + { + if (DeviceLayer::ConnectivityMgr().GetWiFiPAF()->GetWiFiPAFState() != Transport::WiFiPAFBase::State::kConnected) + { + ChipLogProgress(Controller, "WiFi-PAF: Subscribing the NAN-USD devices"); + if (!DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted()) + { + ChipLogError(Controller, "Wi-Fi Management should have be started now."); + ExitNow(CHIP_ERROR_INTERNAL); + } + mRendezvousParametersForDeviceDiscoveredOverWiFiPAF = params; + DeviceLayer::ConnectivityMgr().WiFiPAFConnect(params.GetSetupDiscriminator().value(), (void *) this, + OnWiFiPAFSubscribeComplete, OnWiFiPAFSubscribeError); + ExitNow(CHIP_NO_ERROR); + } + } #endif session = mSystemState->SessionMgr()->CreateUnauthenticatedSession(params.GetPeerAddress(), params.GetMRPConfig()); VerifyOrExit(session.HasValue(), err = CHIP_ERROR_NO_MEMORY); @@ -872,6 +906,43 @@ void DeviceCommissioner::OnDiscoveredDeviceOverBleError(void * appState, CHIP_ER } #endif // CONFIG_NETWORK_LAYER_BLE +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +void DeviceCommissioner::OnWiFiPAFSubscribeComplete(void * appState) +{ + auto self = (DeviceCommissioner *) appState; + auto device = self->mDeviceInPASEEstablishment; + + if (nullptr != device && device->GetDeviceTransportType() == Transport::Type::kWiFiPAF) + { + ChipLogProgress(Controller, "WiFi-PAF: Subscription Completed, dev_id = %lu", device->GetDeviceId()); + auto remoteId = device->GetDeviceId(); + auto params = self->mRendezvousParametersForDeviceDiscoveredOverWiFiPAF; + + self->mRendezvousParametersForDeviceDiscoveredOverWiFiPAF = RendezvousParameters(); + self->ReleaseCommissioneeDevice(device); + LogErrorOnFailure(self->EstablishPASEConnection(remoteId, params)); + } +} + +void DeviceCommissioner::OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err) +{ + auto self = (DeviceCommissioner *) appState; + auto device = self->mDeviceInPASEEstablishment; + + if (nullptr != device && device->GetDeviceTransportType() == Transport::Type::kWiFiPAF) + { + ChipLogError(Controller, "WiFi-PAF: Subscription Error, id = %lu, err = %" CHIP_ERROR_FORMAT, device->GetDeviceId(), + err.Format()); + self->ReleaseCommissioneeDevice(device); + self->mRendezvousParametersForDeviceDiscoveredOverWiFiPAF = RendezvousParameters(); + if (self->mPairingDelegate != nullptr) + { + self->mPairingDelegate->OnPairingComplete(err); + } + } +} +#endif + CHIP_ERROR DeviceCommissioner::Commission(NodeId remoteDeviceId, CommissioningParameters & params) { if (mDefaultCommissioner == nullptr) diff --git a/src/controller/CHIPDeviceController.h b/src/controller/CHIPDeviceController.h index 1c4b490faa891a..4b876156199735 100644 --- a/src/controller/CHIPDeviceController.h +++ b/src/controller/CHIPDeviceController.h @@ -468,7 +468,7 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, { public: DeviceCommissioner(); - ~DeviceCommissioner() override {} + ~DeviceCommissioner() override; #if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY // make this commissioner discoverable /** @@ -847,6 +847,11 @@ class DLL_EXPORT DeviceCommissioner : public DeviceController, static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err); RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverBle; #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + static void OnWiFiPAFSubscribeComplete(void * appState); + static void OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err); + RendezvousParameters mRendezvousParametersForDeviceDiscoveredOverWiFiPAF; +#endif static void OnBasicFailure(void * context, CHIP_ERROR err); static void OnBasicSuccess(void * context, const chip::app::DataModel::NullObjectType &); diff --git a/src/controller/CHIPDeviceControllerFactory.cpp b/src/controller/CHIPDeviceControllerFactory.cpp index 24f60ed9d8a50a..dbc55dd7b7327e 100644 --- a/src/controller/CHIPDeviceControllerFactory.cpp +++ b/src/controller/CHIPDeviceControllerFactory.cpp @@ -141,6 +141,9 @@ CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params) #else stateParams.bleLayer = params.bleLayer; #endif // CONFIG_DEVICE_LAYER +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + stateParams.wifipaf_layer = params.wifipaf_layer; +#endif VerifyOrReturnError(stateParams.bleLayer != nullptr, CHIP_ERROR_INVALID_ARGUMENT); #endif @@ -167,6 +170,10 @@ CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params) Transport::TcpListenParameters(stateParams.tcpEndPointManager) .SetAddressType(IPAddressType::kIPv6) .SetListenPort(params.listenPort) +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + , + Transport::WiFiPAFListenParameters() #endif )); diff --git a/src/controller/CHIPDeviceControllerFactory.h b/src/controller/CHIPDeviceControllerFactory.h index 474357ec4a4bde..16e2ad487126b9 100644 --- a/src/controller/CHIPDeviceControllerFactory.h +++ b/src/controller/CHIPDeviceControllerFactory.h @@ -145,6 +145,9 @@ struct FactoryInitParams #if CONFIG_NETWORK_LAYER_BLE Ble::BleLayer * bleLayer = nullptr; #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + Transport::WiFiPAFLayer * wifipaf_layer = nullptr; +#endif // // Controls enabling server cluster interactions on a controller. This in turn diff --git a/src/controller/CHIPDeviceControllerSystemState.h b/src/controller/CHIPDeviceControllerSystemState.h index da8f25a75d2541..e040ad14616431 100644 --- a/src/controller/CHIPDeviceControllerSystemState.h +++ b/src/controller/CHIPDeviceControllerSystemState.h @@ -52,10 +52,16 @@ #include #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#include +#endif namespace chip { inline constexpr size_t kMaxDeviceTransportBlePendingPackets = 1; +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +inline constexpr size_t kMaxDeviceTransportWiFiPAFPendingPackets = 1; +#endif #if INET_CONFIG_ENABLE_TCP_ENDPOINT inline constexpr size_t kMaxDeviceTransportTcpActiveConnectionCount = CHIP_CONFIG_MAX_ACTIVE_TCP_CONNECTIONS; @@ -76,6 +82,10 @@ using DeviceTransportMgr = #if INET_CONFIG_ENABLE_TCP_ENDPOINT , Transport::TCP +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + , + Transport::WiFiPAF /* WiFiPAF */ #endif >; @@ -93,6 +103,9 @@ struct DeviceControllerSystemStateParams FabricTable * fabricTable = nullptr; #if CONFIG_NETWORK_LAYER_BLE Ble::BleLayer * bleLayer = nullptr; +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + Transport::WiFiPAFLayer * wifipaf_layer = nullptr; #endif Credentials::GroupDataProvider * groupDataProvider = nullptr; Crypto::SessionKeystore * sessionKeystore = nullptr; diff --git a/src/controller/SetUpCodePairer.cpp b/src/controller/SetUpCodePairer.cpp index 17f2e5945eb1bf..99e991dfe8c114 100644 --- a/src/controller/SetUpCodePairer.cpp +++ b/src/controller/SetUpCodePairer.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,13 @@ CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload) } } // namespace +SetUpCodePairer::~SetUpCodePairer() +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + DeviceLayer::ConnectivityMgr().WiFiPAFCancelConnect(); +#endif +} + CHIP_ERROR SetUpCodePairer::PairDevice(NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour commission, DiscoveryType discoveryType, Optional resolutionData) { @@ -129,6 +137,15 @@ CHIP_ERROR SetUpCodePairer::Connect(SetupPayload & payload) } VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err); } + if (searchOverAll || payload.rendezvousInformation.Value().Has(RendezvousInformationFlag::kWiFiPAF)) + { + ChipLogProgress(Controller, "WiFi-PAF: has RendezvousInformationFlag::kWiFiPAF"); + if (CHIP_NO_ERROR == (err = StartDiscoverOverWiFiPAF(payload))) + { + isRunning = true; + } + VerifyOrReturnError(searchOverAll || CHIP_NO_ERROR == err || CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE == err, err); + } } // We always want to search on network because any node that has already been commissioned will use on-network regardless of the @@ -243,6 +260,31 @@ CHIP_ERROR SetUpCodePairer::StopConnectOverSoftAP() return CHIP_NO_ERROR; } +CHIP_ERROR SetUpCodePairer::StartDiscoverOverWiFiPAF(SetupPayload & payload) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + ChipLogProgress(Controller, "Starting commissioning discovery over WiFiPAF"); + VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE); + mWaitingForDiscovery[kWiFiPAFTransport] = true; + CHIP_ERROR err = DeviceLayer::ConnectivityMgr().WiFiPAFConnect(payload.discriminator, (void *) this, OnWiFiPAFSubscribeComplete, + OnWiFiPAFSubscribeError); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Controller, "Commissioning discovery over WiFiPAF failed, err = %" CHIP_ERROR_FORMAT, err.Format()); + mWaitingForDiscovery[kWiFiPAFTransport] = false; + } + return err; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif // CONFIG_NETWORK_LAYER_BLE +} + +CHIP_ERROR SetUpCodePairer::StopConnectOverWiFiPAF() +{ + mWaitingForDiscovery[kWiFiPAFTransport] = false; + return CHIP_NO_ERROR; +} + bool SetUpCodePairer::ConnectToDiscoveredDevice() { if (mWaitingForPASE) @@ -335,6 +377,37 @@ void SetUpCodePairer::OnBLEDiscoveryError(CHIP_ERROR err) } #endif // CONFIG_NETWORK_LAYER_BLE +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +void SetUpCodePairer::OnDiscoveredDeviceOverWifiPAF() +{ + ChipLogProgress(Controller, "Discovered device to be commissioned over WiFiPAF, RemoteId: %lu", mRemoteId); + + mWaitingForDiscovery[kWiFiPAFTransport] = false; + auto param = SetUpCodePairerParameters(); + param.SetPeerAddress(Transport::PeerAddress(Transport::Type::kWiFiPAF, mRemoteId)); + mDiscoveredParameters.emplace_back(param); + ConnectToDiscoveredDevice(); +} + +void SetUpCodePairer::OnWifiPAFDiscoveryError(CHIP_ERROR err) +{ + ChipLogError(Controller, "Commissioning discovery over WiFiPAF failed: %" CHIP_ERROR_FORMAT, err.Format()); + mWaitingForDiscovery[kWiFiPAFTransport] = false; +} + +void SetUpCodePairer::OnWiFiPAFSubscribeComplete(void * appState) +{ + auto self = (SetUpCodePairer *) appState; + self->OnDiscoveredDeviceOverWifiPAF(); +} + +void SetUpCodePairer::OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err) +{ + auto self = (SetUpCodePairer *) appState; + self->OnWifiPAFDiscoveryError(err); +} +#endif + bool SetUpCodePairer::IdIsPresent(uint16_t vendorOrProductID) { return vendorOrProductID != kNotAvailable; @@ -473,6 +546,7 @@ void SetUpCodePairer::ResetDiscoveryState() StopConnectOverBle(); StopConnectOverIP(); StopConnectOverSoftAP(); + StopConnectOverWiFiPAF(); // Just in case any of those failed to reset the waiting state properly. for (auto & waiting : mWaitingForDiscovery) diff --git a/src/controller/SetUpCodePairer.h b/src/controller/SetUpCodePairer.h index e177af7322d391..3414341a2cdd51 100644 --- a/src/controller/SetUpCodePairer.h +++ b/src/controller/SetUpCodePairer.h @@ -77,7 +77,7 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate { public: SetUpCodePairer(DeviceCommissioner * commissioner) : mCommissioner(commissioner) {} - virtual ~SetUpCodePairer() {} + ~SetUpCodePairer(); CHIP_ERROR PairDevice(chip::NodeId remoteId, const char * setUpCode, SetupCodePairerBehaviour connectionType = SetupCodePairerBehaviour::kCommission, @@ -111,6 +111,8 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate CHIP_ERROR StopConnectOverIP(); CHIP_ERROR StartDiscoverOverSoftAP(SetupPayload & payload); CHIP_ERROR StopConnectOverSoftAP(); + CHIP_ERROR StartDiscoverOverWiFiPAF(SetupPayload & payload); + CHIP_ERROR StopConnectOverWiFiPAF(); // Returns whether we have kicked off a new connection attempt. bool ConnectToDiscoveredDevice(); @@ -150,6 +152,7 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate kBLETransport = 0, kIPTransport, kSoftAPTransport, + kWiFiPAFTransport, kTransportTypeCount, }; @@ -165,6 +168,12 @@ class DLL_EXPORT SetUpCodePairer : public DevicePairingDelegate static void OnDiscoveredDeviceOverBleSuccess(void * appState, BLE_CONNECTION_OBJECT connObj); static void OnDiscoveredDeviceOverBleError(void * appState, CHIP_ERROR err); #endif // CONFIG_NETWORK_LAYER_BLE +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + void OnDiscoveredDeviceOverWifiPAF(); + void OnWifiPAFDiscoveryError(CHIP_ERROR err); + static void OnWiFiPAFSubscribeComplete(void * appState); + static void OnWiFiPAFSubscribeError(void * appState, CHIP_ERROR err); +#endif bool NodeMatchesCurrentFilter(const Dnssd::DiscoveredNodeData & nodeData) const; static bool IdIsPresent(uint16_t vendorOrProductID); diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index dd93ed7fe2cc9b..eb9999da242c69 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -448,7 +448,7 @@ cluster Binding = 30 { and enforce Access Control for the Node's endpoints and their associated cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -464,12 +464,42 @@ cluster AccessControl = 31 { kAdminister = 5; } + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + enum ChangeTypeEnum : enum8 { kChanged = 0; kAdded = 1; kRemoved = 2; } + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + struct AccessControlTargetStruct { nullable cluster_id cluster = 0; nullable endpoint_no endpoint = 1; @@ -505,17 +535,41 @@ cluster AccessControl = 31 { fabric_idx fabricIndex = 254; } + fabric_sensitive info event access(read: administer) AccessRestrictionEntryChanged = 2 { + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 3 { + int64u token = 0; + nullable long_char_string instruction = 1; + nullable long_char_string redirectURL = 2; + fabric_idx fabricIndex = 254; + } + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; readonly attribute int16u subjectsPerAccessControlEntry = 2; readonly attribute int16u targetsPerAccessControlEntry = 3; readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; 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 ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): DefaultSuccess = 0; } /** This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. */ @@ -1315,6 +1369,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1323,6 +1380,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1333,6 +1394,10 @@ cluster GeneralCommissioning = 48 { readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1366,12 +1431,23 @@ cluster GeneralCommissioning = 48 { char_string debugText = 1; } + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; /** Set the regulatory configuration to be used during commissioning */ command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; } /** Functionality to configure, enable, disable network credentials and access on a Matter device. */ @@ -2292,8 +2368,12 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; + request struct KeepActiveRequest { + int32u stayActiveDuration = 0; + } + /** The server SHALL attempt to keep the devices specified active for StayActiveDuration milliseconds when they are next active. */ - command KeepActive(): DefaultSuccess = 128; + command KeepActive(KeepActiveRequest): DefaultSuccess = 128; } /** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. @@ -6617,7 +6697,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -6743,11 +6824,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -6853,8 +6929,7 @@ cluster Thermostat = 513 { attribute access(write: manage) optional PresetStruct presets[] = 80; attribute access(write: manage) optional ScheduleStruct schedules[] = 81; readonly attribute optional boolean presetsSchedulesEditable = 82; - readonly attribute optional TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 83; - readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 84; + readonly attribute optional nullable epoch_s setpointHoldExpiryTimestamp = 83; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -6898,10 +6973,6 @@ cluster Thermostat = 513 { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -6920,8 +6991,6 @@ cluster Thermostat = 513 { command access(invoke: manage) CancelPresetsSchedulesEditRequest(): DefaultSuccess = 8; /** This command is used to notify the server that all edits are done and should be committed. */ command access(invoke: manage) CommitPresetsSchedulesRequest(): DefaultSuccess = 9; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ @@ -8121,10 +8190,11 @@ cluster RadonConcentrationMeasurement = 1071 { } /** Functionality to retrieve operational information about a managed Wi-Fi network. */ -cluster WiFiNetworkManagement = 1105 { +provisional cluster WiFiNetworkManagement = 1105 { revision 1; - readonly attribute nullable octet_string<32> ssid = 1; + readonly attribute nullable octet_string<32> ssid = 0; + readonly attribute access(read: manage) nullable int64u passphraseSurrogate = 1; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -8137,7 +8207,7 @@ cluster WiFiNetworkManagement = 1105 { } /** Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. */ - command access(invoke: administer) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0; + command access(invoke: manage) NetworkPassphraseRequest(): NetworkPassphraseResponse = 0; } /** Manage the Thread network of Thread Border Router */ @@ -8184,7 +8254,7 @@ provisional cluster ThreadBorderRouterManagement = 1106 { } /** Manages the names and credentials of Thread networks visible to the user. */ -cluster ThreadNetworkDirectory = 1107 { +provisional cluster ThreadNetworkDirectory = 1107 { revision 1; struct ThreadNetworkStruct { @@ -8225,7 +8295,7 @@ cluster ThreadNetworkDirectory = 1107 { /** Removes an entry from the ThreadNetworks list. */ timed command access(invoke: manage) RemoveNetwork(RemoveNetworkRequest): DefaultSuccess = 1; /** Retrieves a Thread Operational Dataset from the ThreadNetworks list. */ - timed command GetOperationalDataset(GetOperationalDatasetRequest): OperationalDatasetResponse = 2; + command GetOperationalDataset(GetOperationalDatasetRequest): OperationalDatasetResponse = 2; } /** This cluster provides an interface for managing low power mode on a device that supports the Wake On LAN protocol. */ diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index eb527e60667894..466f3947d263c1 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -1457,7 +1457,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5994,4 +5994,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index e11a47a23a8c7c..950e7f818d0db3 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -3963,6 +3963,8 @@ public static class AccessControlCluster extends BaseChipCluster { private static final long SUBJECTS_PER_ACCESS_CONTROL_ENTRY_ATTRIBUTE_ID = 2L; private static final long TARGETS_PER_ACCESS_CONTROL_ENTRY_ATTRIBUTE_ID = 3L; private static final long ACCESS_CONTROL_ENTRIES_PER_FABRIC_ATTRIBUTE_ID = 4L; + private static final long COMMISSIONING_A_R_L_ATTRIBUTE_ID = 5L; + private static final long ARL_ATTRIBUTE_ID = 6L; 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; @@ -3980,6 +3982,26 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } + public void reviewFabricRestrictions(DefaultClusterCallback callback, ArrayList arl) { + reviewFabricRestrictions(callback, arl, 0); + } + + public void reviewFabricRestrictions(DefaultClusterCallback callback, ArrayList arl, int timedInvokeTimeoutMs) { + final long commandId = 0L; + + ArrayList elements = new ArrayList<>(); + final long arlFieldID = 0L; + BaseTLVType arltlvValue = ArrayType.generateArrayType(arl, (elementarl) -> elementarl.encodeTlv()); + elements.add(new StructElement(arlFieldID, arltlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + public interface AclAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -3988,6 +4010,14 @@ public interface ExtensionAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } + public interface CommissioningARLAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface ArlAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -4162,6 +4192,63 @@ public void onSuccess(byte[] tlv) { }, ACCESS_CONTROL_ENTRIES_PER_FABRIC_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readCommissioningARLAttribute( + CommissioningARLAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, COMMISSIONING_A_R_L_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, COMMISSIONING_A_R_L_ATTRIBUTE_ID, true); + } + + public void subscribeCommissioningARLAttribute( + CommissioningARLAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, COMMISSIONING_A_R_L_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, COMMISSIONING_A_R_L_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readArlAttribute( + ArlAttributeCallback callback) { + readArlAttributeWithFabricFilter(callback, true); + } + + public void readArlAttributeWithFabricFilter( + ArlAttributeCallback callback, boolean isFabricFiltered) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ARL_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ARL_ATTRIBUTE_ID, isFabricFiltered); + } + + public void subscribeArlAttribute( + ArlAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ARL_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ARL_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); @@ -8628,6 +8715,10 @@ public static class GeneralCommissioningCluster extends BaseChipCluster { private static final long REGULATORY_CONFIG_ATTRIBUTE_ID = 2L; private static final long LOCATION_CAPABILITY_ATTRIBUTE_ID = 3L; private static final long SUPPORTS_CONCURRENT_CONNECTION_ATTRIBUTE_ID = 4L; + private static final long T_C_ACCEPTED_VERSION_ATTRIBUTE_ID = 5L; + private static final long T_C_MIN_REQUIRED_VERSION_ATTRIBUTE_ID = 6L; + private static final long T_C_ACKNOWLEDGEMENTS_ATTRIBUTE_ID = 7L; + private static final long T_C_ACKNOWLEDGEMENTS_REQUIRED_ATTRIBUTE_ID = 8L; 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; @@ -8764,6 +8855,40 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } + public void setTCAcknowledgements(SetTCAcknowledgementsResponseCallback callback, Integer TCVersion, Integer TCUserResponse) { + setTCAcknowledgements(callback, TCVersion, TCUserResponse, 0); + } + + public void setTCAcknowledgements(SetTCAcknowledgementsResponseCallback callback, Integer TCVersion, Integer TCUserResponse, int timedInvokeTimeoutMs) { + final long commandId = 6L; + + ArrayList elements = new ArrayList<>(); + final long TCVersionFieldID = 0L; + BaseTLVType TCVersiontlvValue = new UIntType(TCVersion); + elements.add(new StructElement(TCVersionFieldID, TCVersiontlvValue)); + + final long TCUserResponseFieldID = 1L; + BaseTLVType TCUserResponsetlvValue = new UIntType(TCUserResponse); + elements.add(new StructElement(TCUserResponseFieldID, TCUserResponsetlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long errorCodeFieldID = 0L; + Integer errorCode = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == errorCodeFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + errorCode = castingValue.value(Integer.class); + } + } + } + callback.onSuccess(errorCode); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + public interface ArmFailSafeResponseCallback extends BaseClusterCallback { void onSuccess(Integer errorCode, String debugText); } @@ -8776,6 +8901,10 @@ public interface CommissioningCompleteResponseCallback extends BaseClusterCallba void onSuccess(Integer errorCode, String debugText); } + public interface SetTCAcknowledgementsResponseCallback extends BaseClusterCallback { + void onSuccess(Integer errorCode); + } + public interface BasicCommissioningInfoAttributeCallback extends BaseAttributeCallback { void onSuccess(ChipStructs.GeneralCommissioningClusterBasicCommissioningInfo value); } @@ -8935,6 +9064,110 @@ public void onSuccess(byte[] tlv) { }, SUPPORTS_CONCURRENT_CONNECTION_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readTCAcceptedVersionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, T_C_ACCEPTED_VERSION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, T_C_ACCEPTED_VERSION_ATTRIBUTE_ID, true); + } + + public void subscribeTCAcceptedVersionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, T_C_ACCEPTED_VERSION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, T_C_ACCEPTED_VERSION_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readTCMinRequiredVersionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, T_C_MIN_REQUIRED_VERSION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, T_C_MIN_REQUIRED_VERSION_ATTRIBUTE_ID, true); + } + + public void subscribeTCMinRequiredVersionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, T_C_MIN_REQUIRED_VERSION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, T_C_MIN_REQUIRED_VERSION_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readTCAcknowledgementsAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, T_C_ACKNOWLEDGEMENTS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, T_C_ACKNOWLEDGEMENTS_ATTRIBUTE_ID, true); + } + + public void subscribeTCAcknowledgementsAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, T_C_ACKNOWLEDGEMENTS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, T_C_ACKNOWLEDGEMENTS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readTCAcknowledgementsRequiredAttribute( + BooleanAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, T_C_ACKNOWLEDGEMENTS_REQUIRED_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Boolean value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, T_C_ACKNOWLEDGEMENTS_REQUIRED_ATTRIBUTE_ID, true); + } + + public void subscribeTCAcknowledgementsRequiredAttribute( + BooleanAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, T_C_ACKNOWLEDGEMENTS_REQUIRED_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Boolean value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, T_C_ACKNOWLEDGEMENTS_REQUIRED_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); @@ -14963,14 +15196,18 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void keepActive(DefaultClusterCallback callback) { - keepActive(callback, 0); + public void keepActive(DefaultClusterCallback callback, Long stayActiveDuration) { + keepActive(callback, stayActiveDuration, 0); } - public void keepActive(DefaultClusterCallback callback, int timedInvokeTimeoutMs) { + public void keepActive(DefaultClusterCallback callback, Long stayActiveDuration, int timedInvokeTimeoutMs) { final long commandId = 128L; ArrayList elements = new ArrayList<>(); + final long stayActiveDurationFieldID = 0L; + BaseTLVType stayActiveDurationtlvValue = new UIntType(stayActiveDuration); + elements.add(new StructElement(stayActiveDurationFieldID, stayActiveDurationtlvValue)); + StructType commandArgs = new StructType(elements); invoke(new InvokeCallbackImpl(callback) { @Override @@ -40225,8 +40462,7 @@ public static class ThermostatCluster extends BaseChipCluster { private static final long PRESETS_ATTRIBUTE_ID = 80L; private static final long SCHEDULES_ATTRIBUTE_ID = 81L; private static final long PRESETS_SCHEDULES_EDITABLE_ATTRIBUTE_ID = 82L; - private static final long TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID = 83L; - private static final long SETPOINT_HOLD_EXPIRY_TIMESTAMP_ATTRIBUTE_ID = 84L; + private static final long SETPOINT_HOLD_EXPIRY_TIMESTAMP_ATTRIBUTE_ID = 83L; 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; @@ -40463,26 +40699,6 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public void setTemperatureSetpointHoldPolicy(DefaultClusterCallback callback, Integer temperatureSetpointHoldPolicy) { - setTemperatureSetpointHoldPolicy(callback, temperatureSetpointHoldPolicy, 0); - } - - public void setTemperatureSetpointHoldPolicy(DefaultClusterCallback callback, Integer temperatureSetpointHoldPolicy, int timedInvokeTimeoutMs) { - final long commandId = 11L; - - ArrayList elements = new ArrayList<>(); - final long temperatureSetpointHoldPolicyFieldID = 0L; - BaseTLVType temperatureSetpointHoldPolicytlvValue = new UIntType(temperatureSetpointHoldPolicy); - elements.add(new StructElement(temperatureSetpointHoldPolicyFieldID, temperatureSetpointHoldPolicytlvValue)); - - StructType commandArgs = new StructType(elements); - invoke(new InvokeCallbackImpl(callback) { - @Override - public void onResponse(StructType invokeStructValue) { - callback.onSuccess(); - }}, commandId, commandArgs, timedInvokeTimeoutMs); - } - public interface GetWeeklyScheduleResponseCallback extends BaseClusterCallback { void onSuccess(Integer numberOfTransitionsForSequence, Integer dayOfWeekForSequence, Integer modeForSequence, ArrayList transitions); } @@ -42400,32 +42616,6 @@ public void onSuccess(byte[] tlv) { }, PRESETS_SCHEDULES_EDITABLE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readTemperatureSetpointHoldPolicyAttribute( - IntegerAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID, true); - } - - public void subscribeTemperatureSetpointHoldPolicyAttribute( - IntegerAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, TEMPERATURE_SETPOINT_HOLD_POLICY_ATTRIBUTE_ID, minInterval, maxInterval); - } - public void readSetpointHoldExpiryTimestampAttribute( SetpointHoldExpiryTimestampAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SETPOINT_HOLD_EXPIRY_TIMESTAMP_ATTRIBUTE_ID); @@ -54135,7 +54325,8 @@ public void onSuccess(byte[] tlv) { public static class WiFiNetworkManagementCluster extends BaseChipCluster { public static final long CLUSTER_ID = 1105L; - private static final long SSID_ATTRIBUTE_ID = 1L; + private static final long SSID_ATTRIBUTE_ID = 0L; + private static final long PASSPHRASE_SURROGATE_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; @@ -54187,6 +54378,10 @@ public interface SsidAttributeCallback extends BaseAttributeCallback { void onSuccess(@Nullable byte[] value); } + public interface PassphraseSurrogateAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Long value); + } + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -54229,6 +54424,32 @@ public void onSuccess(byte[] tlv) { }, SSID_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readPassphraseSurrogateAttribute( + PassphraseSurrogateAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PASSPHRASE_SURROGATE_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PASSPHRASE_SURROGATE_ATTRIBUTE_ID, true); + } + + public void subscribePassphraseSurrogateAttribute( + PassphraseSurrogateAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PASSPHRASE_SURROGATE_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PASSPHRASE_SURROGATE_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); @@ -54875,6 +55096,9 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } + public void getOperationalDataset(OperationalDatasetResponseCallback callback, byte[] extendedPanID) { + getOperationalDataset(callback, extendedPanID, 0); + } public void getOperationalDataset(OperationalDatasetResponseCallback callback, byte[] extendedPanID, int timedInvokeTimeoutMs) { final long commandId = 2L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index e33980d8a6e7d9..7a7634b395cb38 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java @@ -236,6 +236,143 @@ public String toString() { return output.toString(); } } +public static class AccessControlClusterAccessRestrictionEntryChangedEvent { + public Integer fabricIndex; + private static final long FABRIC_INDEX_ID = 254L; + + public AccessControlClusterAccessRestrictionEntryChangedEvent( + Integer fabricIndex + ) { + this.fabricIndex = fabricIndex; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); + + return new StructType(values); + } + + public static AccessControlClusterAccessRestrictionEntryChangedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer fabricIndex = null; + for (StructElement element: ((StructType)tlvValue).value()) { + 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 AccessControlClusterAccessRestrictionEntryChangedEvent( + fabricIndex + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("AccessControlClusterAccessRestrictionEntryChangedEvent {\n"); + output.append("\tfabricIndex: "); + output.append(fabricIndex); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class AccessControlClusterFabricRestrictionReviewUpdateEvent { + public Long token; + public @Nullable String instruction; + public @Nullable String redirectURL; + public Integer fabricIndex; + private static final long TOKEN_ID = 0L; + private static final long INSTRUCTION_ID = 1L; + private static final long REDIRECT_U_R_L_ID = 2L; + private static final long FABRIC_INDEX_ID = 254L; + + public AccessControlClusterFabricRestrictionReviewUpdateEvent( + Long token, + @Nullable String instruction, + @Nullable String redirectURL, + Integer fabricIndex + ) { + this.token = token; + this.instruction = instruction; + this.redirectURL = redirectURL; + this.fabricIndex = fabricIndex; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(TOKEN_ID, new UIntType(token))); + values.add(new StructElement(INSTRUCTION_ID, instruction != null ? new StringType(instruction) : new NullType())); + values.add(new StructElement(REDIRECT_U_R_L_ID, redirectURL != null ? new StringType(redirectURL) : new NullType())); + values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); + + return new StructType(values); + } + + public static AccessControlClusterFabricRestrictionReviewUpdateEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long token = null; + @Nullable String instruction = null; + @Nullable String redirectURL = null; + Integer fabricIndex = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == TOKEN_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + token = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == INSTRUCTION_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + instruction = castingValue.value(String.class); + } + } else if (element.contextTagNum() == REDIRECT_U_R_L_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + redirectURL = castingValue.value(String.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 AccessControlClusterFabricRestrictionReviewUpdateEvent( + token, + instruction, + redirectURL, + fabricIndex + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("AccessControlClusterFabricRestrictionReviewUpdateEvent {\n"); + output.append("\ttoken: "); + output.append(token); + output.append("\n"); + output.append("\tinstruction: "); + output.append(instruction); + output.append("\n"); + output.append("\tredirectURL: "); + output.append(redirectURL); + output.append("\n"); + output.append("\tfabricIndex: "); + output.append(fabricIndex); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class ActionsClusterStateChangedEvent { public Integer actionID; public Long invokeID; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index 90330bbdee3ae6..df78372f96c945 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -282,6 +282,234 @@ public String toString() { return output.toString(); } } +public static class AccessControlClusterAccessRestrictionStruct { + public Integer type; + public @Nullable Long id; + private static final long TYPE_ID = 0L; + private static final long ID_ID = 1L; + + public AccessControlClusterAccessRestrictionStruct( + Integer type, + @Nullable Long id + ) { + this.type = type; + this.id = id; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(TYPE_ID, new UIntType(type))); + values.add(new StructElement(ID_ID, id != null ? new UIntType(id) : new NullType())); + + return new StructType(values); + } + + public static AccessControlClusterAccessRestrictionStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer type = null; + @Nullable Long id = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == TYPE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + type = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + id = castingValue.value(Long.class); + } + } + } + return new AccessControlClusterAccessRestrictionStruct( + type, + id + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("AccessControlClusterAccessRestrictionStruct {\n"); + output.append("\ttype: "); + output.append(type); + output.append("\n"); + output.append("\tid: "); + output.append(id); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class AccessControlClusterCommissioningAccessRestrictionEntryStruct { + public Integer endpoint; + public Long cluster; + public ArrayList restrictions; + private static final long ENDPOINT_ID = 0L; + private static final long CLUSTER_ID = 1L; + private static final long RESTRICTIONS_ID = 2L; + + public AccessControlClusterCommissioningAccessRestrictionEntryStruct( + Integer endpoint, + Long cluster, + ArrayList restrictions + ) { + this.endpoint = endpoint; + this.cluster = cluster; + this.restrictions = restrictions; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(ENDPOINT_ID, new UIntType(endpoint))); + values.add(new StructElement(CLUSTER_ID, new UIntType(cluster))); + values.add(new StructElement(RESTRICTIONS_ID, ArrayType.generateArrayType(restrictions, (elementrestrictions) -> elementrestrictions.encodeTlv()))); + + return new StructType(values); + } + + public static AccessControlClusterCommissioningAccessRestrictionEntryStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer endpoint = null; + Long cluster = null; + ArrayList restrictions = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == ENDPOINT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + endpoint = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == CLUSTER_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + cluster = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == RESTRICTIONS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + restrictions = castingValue.map((elementcastingValue) -> ChipStructs.AccessControlClusterAccessRestrictionStruct.decodeTlv(elementcastingValue)); + } + } + } + return new AccessControlClusterCommissioningAccessRestrictionEntryStruct( + endpoint, + cluster, + restrictions + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("AccessControlClusterCommissioningAccessRestrictionEntryStruct {\n"); + output.append("\tendpoint: "); + output.append(endpoint); + output.append("\n"); + output.append("\tcluster: "); + output.append(cluster); + output.append("\n"); + output.append("\trestrictions: "); + output.append(restrictions); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class AccessControlClusterAccessRestrictionEntryStruct { + public Integer endpoint; + public Long cluster; + public ArrayList restrictions; + public Integer fabricIndex; + private static final long ENDPOINT_ID = 0L; + private static final long CLUSTER_ID = 1L; + private static final long RESTRICTIONS_ID = 2L; + private static final long FABRIC_INDEX_ID = 254L; + + public AccessControlClusterAccessRestrictionEntryStruct( + Integer endpoint, + Long cluster, + ArrayList restrictions, + Integer fabricIndex + ) { + this.endpoint = endpoint; + this.cluster = cluster; + this.restrictions = restrictions; + this.fabricIndex = fabricIndex; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(ENDPOINT_ID, new UIntType(endpoint))); + values.add(new StructElement(CLUSTER_ID, new UIntType(cluster))); + values.add(new StructElement(RESTRICTIONS_ID, ArrayType.generateArrayType(restrictions, (elementrestrictions) -> elementrestrictions.encodeTlv()))); + values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); + + return new StructType(values); + } + + public static AccessControlClusterAccessRestrictionEntryStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer endpoint = null; + Long cluster = null; + ArrayList restrictions = null; + Integer fabricIndex = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == ENDPOINT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + endpoint = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == CLUSTER_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + cluster = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == RESTRICTIONS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + restrictions = castingValue.map((elementcastingValue) -> ChipStructs.AccessControlClusterAccessRestrictionStruct.decodeTlv(elementcastingValue)); + } + } 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 AccessControlClusterAccessRestrictionEntryStruct( + endpoint, + cluster, + restrictions, + fabricIndex + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("AccessControlClusterAccessRestrictionEntryStruct {\n"); + output.append("\tendpoint: "); + output.append(endpoint); + output.append("\n"); + output.append("\tcluster: "); + output.append(cluster); + output.append("\n"); + output.append("\trestrictions: "); + output.append(restrictions); + output.append("\n"); + output.append("\tfabricIndex: "); + output.append(fabricIndex); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class AccessControlClusterAccessControlTargetStruct { public @Nullable Long cluster; public @Nullable Integer endpoint; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index ab20bdcaa301e9..6c8fccf1cdeda1 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -1687,6 +1687,8 @@ public enum Attribute { SubjectsPerAccessControlEntry(2L), TargetsPerAccessControlEntry(3L), AccessControlEntriesPerFabric(4L), + CommissioningARL(5L), + Arl(6L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -1714,7 +1716,9 @@ public static Attribute value(long id) throws NoSuchFieldError { public enum Event { AccessControlEntryChanged(0L), - AccessControlExtensionChanged(1L),; + AccessControlExtensionChanged(1L), + AccessRestrictionEntryChanged(2L), + FabricRestrictionReviewUpdate(3L),; private final long id; Event(long id) { this.id = id; @@ -1734,7 +1738,8 @@ public static Event value(long id) throws NoSuchFieldError { } } - public enum Command {; + public enum Command { + ReviewFabricRestrictions(0L),; private final long id; Command(long id) { this.id = id; @@ -1752,7 +1757,24 @@ public static Command value(long id) throws NoSuchFieldError { } throw new NoSuchFieldError(); } - }@Override + }public enum ReviewFabricRestrictionsCommandField {Arl(0),; + private final int id; + ReviewFabricRestrictionsCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static ReviewFabricRestrictionsCommandField value(int id) throws NoSuchFieldError { + for (ReviewFabricRestrictionsCommandField field : ReviewFabricRestrictionsCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override public String getAttributeName(long id) throws NoSuchFieldError { return Attribute.value(id).toString(); } @@ -3064,6 +3086,10 @@ public enum Attribute { RegulatoryConfig(2L), LocationCapability(3L), SupportsConcurrentConnection(4L), + TCAcceptedVersion(5L), + TCMinRequiredVersion(6L), + TCAcknowledgements(7L), + TCAcknowledgementsRequired(8L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -3112,7 +3138,8 @@ public static Event value(long id) throws NoSuchFieldError { public enum Command { ArmFailSafe(0L), SetRegulatoryConfig(2L), - CommissioningComplete(4L),; + CommissioningComplete(4L), + SetTCAcknowledgements(6L),; private final long id; Command(long id) { this.id = id; @@ -3164,6 +3191,23 @@ public static SetRegulatoryConfigCommandField value(int id) throws NoSuchFieldEr } throw new NoSuchFieldError(); } + }public enum SetTCAcknowledgementsCommandField {TCVersion(0),TCUserResponse(1),; + private final int id; + SetTCAcknowledgementsCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static SetTCAcknowledgementsCommandField value(int id) throws NoSuchFieldError { + for (SetTCAcknowledgementsCommandField field : SetTCAcknowledgementsCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } }@Override public String getAttributeName(long id) throws NoSuchFieldError { return Attribute.value(id).toString(); @@ -4498,7 +4542,24 @@ public static Command value(long id) throws NoSuchFieldError { } throw new NoSuchFieldError(); } - }@Override + }public enum KeepActiveCommandField {StayActiveDuration(0),; + private final int id; + KeepActiveCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static KeepActiveCommandField value(int id) throws NoSuchFieldError { + for (KeepActiveCommandField field : KeepActiveCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override public String getAttributeName(long id) throws NoSuchFieldError { return Attribute.value(id).toString(); } @@ -11897,8 +11958,7 @@ public enum Attribute { Presets(80L), Schedules(81L), PresetsSchedulesEditable(82L), - TemperatureSetpointHoldPolicy(83L), - SetpointHoldExpiryTimestamp(84L), + SetpointHoldExpiryTimestamp(83L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -11953,8 +12013,7 @@ public enum Command { SetActivePresetRequest(6L), StartPresetsSchedulesEditRequest(7L), CancelPresetsSchedulesEditRequest(8L), - CommitPresetsSchedulesRequest(9L), - SetTemperatureSetpointHoldPolicy(11L),; + CommitPresetsSchedulesRequest(9L),; private final long id; Command(long id) { this.id = id; @@ -12074,23 +12133,6 @@ public static StartPresetsSchedulesEditRequestCommandField value(int id) throws } throw new NoSuchFieldError(); } - }public enum SetTemperatureSetpointHoldPolicyCommandField {TemperatureSetpointHoldPolicy(0),; - private final int id; - SetTemperatureSetpointHoldPolicyCommandField(int id) { - this.id = id; - } - - public int getID() { - return id; - } - public static SetTemperatureSetpointHoldPolicyCommandField value(int id) throws NoSuchFieldError { - for (SetTemperatureSetpointHoldPolicyCommandField field : SetTemperatureSetpointHoldPolicyCommandField.values()) { - if (field.getID() == id) { - return field; - } - } - throw new NoSuchFieldError(); - } }@Override public String getAttributeName(long id) throws NoSuchFieldError { return Attribute.value(id).toString(); @@ -14719,7 +14761,8 @@ public long getID() { } public enum Attribute { - Ssid(1L), + Ssid(0L), + PassphraseSurrogate(1L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index ca3d74f1ac3797..2ba2e50bb11ee8 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -1383,6 +1383,48 @@ public void onError(Exception ex) { } } + public static class DelegatedAccessControlClusterCommissioningARLAttributeCallback implements ChipClusters.AccessControlCluster.CommissioningARLAttributeCallback, 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 DelegatedAccessControlClusterArlAttributeCallback implements ChipClusters.AccessControlCluster.ArlAttributeCallback, 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 DelegatedAccessControlClusterGeneratedCommandListAttributeCallback implements ChipClusters.AccessControlCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -2796,6 +2838,28 @@ public void onError(Exception error) { callback.onFailure(error); } } + + public static class DelegatedGeneralCommissioningClusterSetTCAcknowledgementsResponseCallback implements ChipClusters.GeneralCommissioningCluster.SetTCAcknowledgementsResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer errorCode) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo errorCodeResponseValue = new CommandResponseInfo("errorCode", "Integer"); + responseValues.put(errorCodeResponseValue, errorCode); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } public static class DelegatedGeneralCommissioningClusterBasicCommissioningInfoAttributeCallback implements ChipClusters.GeneralCommissioningCluster.BasicCommissioningInfoAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -17855,6 +17919,27 @@ public void onError(Exception ex) { } } + public static class DelegatedWiFiNetworkManagementClusterPassphraseSurrogateAttributeCallback implements ChipClusters.WiFiNetworkManagementCluster.PassphraseSurrogateAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Long value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Long"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedWiFiNetworkManagementClusterGeneratedCommandListAttributeCallback implements ChipClusters.WiFiNetworkManagementCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -23164,6 +23249,21 @@ public Map> getCommandMap() { Map accessControlClusterInteractionInfoMap = new LinkedHashMap<>(); + Map accessControlreviewFabricRestrictionsCommandParams = new LinkedHashMap(); + + InteractionInfo accessControlreviewFabricRestrictionsInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.AccessControlCluster) cluster) + .reviewFabricRestrictions((DefaultClusterCallback) callback + , (ArrayList) + commandArguments.get("arl") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + accessControlreviewFabricRestrictionsCommandParams + ); + accessControlClusterInteractionInfoMap.put("reviewFabricRestrictions", accessControlreviewFabricRestrictionsInteractionInfo); + commandMap.put("accessControl", accessControlClusterInteractionInfoMap); Map actionsClusterInteractionInfoMap = new LinkedHashMap<>(); @@ -23714,6 +23814,30 @@ public Map> getCommandMap() { ); generalCommissioningClusterInteractionInfoMap.put("commissioningComplete", generalCommissioningcommissioningCompleteInteractionInfo); + Map generalCommissioningsetTCAcknowledgementsCommandParams = new LinkedHashMap(); + + CommandParameterInfo generalCommissioningsetTCAcknowledgementsTCVersionCommandParameterInfo = new CommandParameterInfo("TCVersion", Integer.class, Integer.class); + generalCommissioningsetTCAcknowledgementsCommandParams.put("TCVersion",generalCommissioningsetTCAcknowledgementsTCVersionCommandParameterInfo); + + CommandParameterInfo generalCommissioningsetTCAcknowledgementsTCUserResponseCommandParameterInfo = new CommandParameterInfo("TCUserResponse", Integer.class, Integer.class); + generalCommissioningsetTCAcknowledgementsCommandParams.put("TCUserResponse",generalCommissioningsetTCAcknowledgementsTCUserResponseCommandParameterInfo); + InteractionInfo generalCommissioningsetTCAcknowledgementsInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.GeneralCommissioningCluster) cluster) + .setTCAcknowledgements((ChipClusters.GeneralCommissioningCluster.SetTCAcknowledgementsResponseCallback) callback + , (Integer) + commandArguments.get("TCVersion") + + , (Integer) + commandArguments.get("TCUserResponse") + + ); + }, + () -> new DelegatedGeneralCommissioningClusterSetTCAcknowledgementsResponseCallback(), + generalCommissioningsetTCAcknowledgementsCommandParams + ); + generalCommissioningClusterInteractionInfoMap.put("setTCAcknowledgements", generalCommissioningsetTCAcknowledgementsInteractionInfo); + commandMap.put("generalCommissioning", generalCommissioningClusterInteractionInfoMap); Map networkCommissioningClusterInteractionInfoMap = new LinkedHashMap<>(); @@ -24181,10 +24305,15 @@ public Map> getCommandMap() { Map bridgedDeviceBasicInformationClusterInteractionInfoMap = new LinkedHashMap<>(); Map bridgedDeviceBasicInformationkeepActiveCommandParams = new LinkedHashMap(); + + CommandParameterInfo bridgedDeviceBasicInformationkeepActivestayActiveDurationCommandParameterInfo = new CommandParameterInfo("stayActiveDuration", Long.class, Long.class); + bridgedDeviceBasicInformationkeepActiveCommandParams.put("stayActiveDuration",bridgedDeviceBasicInformationkeepActivestayActiveDurationCommandParameterInfo); InteractionInfo bridgedDeviceBasicInformationkeepActiveInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { ((ChipClusters.BridgedDeviceBasicInformationCluster) cluster) .keepActive((DefaultClusterCallback) callback + , (Long) + commandArguments.get("stayActiveDuration") ); }, () -> new DelegatedDefaultClusterCallback(), @@ -26903,23 +27032,6 @@ public Map> getCommandMap() { ); thermostatClusterInteractionInfoMap.put("commitPresetsSchedulesRequest", thermostatcommitPresetsSchedulesRequestInteractionInfo); - Map thermostatsetTemperatureSetpointHoldPolicyCommandParams = new LinkedHashMap(); - - CommandParameterInfo thermostatsetTemperatureSetpointHoldPolicytemperatureSetpointHoldPolicyCommandParameterInfo = new CommandParameterInfo("temperatureSetpointHoldPolicy", Integer.class, Integer.class); - thermostatsetTemperatureSetpointHoldPolicyCommandParams.put("temperatureSetpointHoldPolicy",thermostatsetTemperatureSetpointHoldPolicytemperatureSetpointHoldPolicyCommandParameterInfo); - InteractionInfo thermostatsetTemperatureSetpointHoldPolicyInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.ThermostatCluster) cluster) - .setTemperatureSetpointHoldPolicy((DefaultClusterCallback) callback - , (Integer) - commandArguments.get("temperatureSetpointHoldPolicy") - ); - }, - () -> new DelegatedDefaultClusterCallback(), - thermostatsetTemperatureSetpointHoldPolicyCommandParams - ); - thermostatClusterInteractionInfoMap.put("setTemperatureSetpointHoldPolicy", thermostatsetTemperatureSetpointHoldPolicyInteractionInfo); - commandMap.put("thermostat", thermostatClusterInteractionInfoMap); Map fanControlClusterInteractionInfoMap = new LinkedHashMap<>(); @@ -27842,7 +27954,7 @@ public Map> getCommandMap() { , (byte[]) commandArguments.get("extendedPanID") - , 10000); + ); }, () -> new DelegatedThreadNetworkDirectoryClusterOperationalDatasetResponseCallback(), threadNetworkDirectorygetOperationalDatasetCommandParams diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 45d0e3037631fb..c6a6f189ba36eb 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -1140,6 +1140,28 @@ private static Map readAccessControlInteractionInfo() { readAccessControlAccessControlEntriesPerFabricCommandParams ); result.put("readAccessControlEntriesPerFabricAttribute", readAccessControlAccessControlEntriesPerFabricAttributeInteractionInfo); + Map readAccessControlCommissioningARLCommandParams = new LinkedHashMap(); + InteractionInfo readAccessControlCommissioningARLAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.AccessControlCluster) cluster).readCommissioningARLAttribute( + (ChipClusters.AccessControlCluster.CommissioningARLAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedAccessControlClusterCommissioningARLAttributeCallback(), + readAccessControlCommissioningARLCommandParams + ); + result.put("readCommissioningARLAttribute", readAccessControlCommissioningARLAttributeInteractionInfo); + Map readAccessControlArlCommandParams = new LinkedHashMap(); + InteractionInfo readAccessControlArlAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.AccessControlCluster) cluster).readArlAttribute( + (ChipClusters.AccessControlCluster.ArlAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedAccessControlClusterArlAttributeCallback(), + readAccessControlArlCommandParams + ); + result.put("readArlAttribute", readAccessControlArlAttributeInteractionInfo); Map readAccessControlGeneratedCommandListCommandParams = new LinkedHashMap(); InteractionInfo readAccessControlGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -2621,6 +2643,50 @@ private static Map readGeneralCommissioningInteractionI readGeneralCommissioningSupportsConcurrentConnectionCommandParams ); result.put("readSupportsConcurrentConnectionAttribute", readGeneralCommissioningSupportsConcurrentConnectionAttributeInteractionInfo); + Map readGeneralCommissioningTCAcceptedVersionCommandParams = new LinkedHashMap(); + InteractionInfo readGeneralCommissioningTCAcceptedVersionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.GeneralCommissioningCluster) cluster).readTCAcceptedVersionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readGeneralCommissioningTCAcceptedVersionCommandParams + ); + result.put("readTCAcceptedVersionAttribute", readGeneralCommissioningTCAcceptedVersionAttributeInteractionInfo); + Map readGeneralCommissioningTCMinRequiredVersionCommandParams = new LinkedHashMap(); + InteractionInfo readGeneralCommissioningTCMinRequiredVersionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.GeneralCommissioningCluster) cluster).readTCMinRequiredVersionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readGeneralCommissioningTCMinRequiredVersionCommandParams + ); + result.put("readTCMinRequiredVersionAttribute", readGeneralCommissioningTCMinRequiredVersionAttributeInteractionInfo); + Map readGeneralCommissioningTCAcknowledgementsCommandParams = new LinkedHashMap(); + InteractionInfo readGeneralCommissioningTCAcknowledgementsAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.GeneralCommissioningCluster) cluster).readTCAcknowledgementsAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readGeneralCommissioningTCAcknowledgementsCommandParams + ); + result.put("readTCAcknowledgementsAttribute", readGeneralCommissioningTCAcknowledgementsAttributeInteractionInfo); + Map readGeneralCommissioningTCAcknowledgementsRequiredCommandParams = new LinkedHashMap(); + InteractionInfo readGeneralCommissioningTCAcknowledgementsRequiredAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.GeneralCommissioningCluster) cluster).readTCAcknowledgementsRequiredAttribute( + (ChipClusters.BooleanAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedBooleanAttributeCallback(), + readGeneralCommissioningTCAcknowledgementsRequiredCommandParams + ); + result.put("readTCAcknowledgementsRequiredAttribute", readGeneralCommissioningTCAcknowledgementsRequiredAttributeInteractionInfo); Map readGeneralCommissioningGeneratedCommandListCommandParams = new LinkedHashMap(); InteractionInfo readGeneralCommissioningGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -12905,17 +12971,6 @@ private static Map readThermostatInteractionInfo() { readThermostatPresetsSchedulesEditableCommandParams ); result.put("readPresetsSchedulesEditableAttribute", readThermostatPresetsSchedulesEditableAttributeInteractionInfo); - Map readThermostatTemperatureSetpointHoldPolicyCommandParams = new LinkedHashMap(); - InteractionInfo readThermostatTemperatureSetpointHoldPolicyAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.ThermostatCluster) cluster).readTemperatureSetpointHoldPolicyAttribute( - (ChipClusters.IntegerAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), - readThermostatTemperatureSetpointHoldPolicyCommandParams - ); - result.put("readTemperatureSetpointHoldPolicyAttribute", readThermostatTemperatureSetpointHoldPolicyAttributeInteractionInfo); Map readThermostatSetpointHoldExpiryTimestampCommandParams = new LinkedHashMap(); InteractionInfo readThermostatSetpointHoldExpiryTimestampAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -16938,6 +16993,17 @@ private static Map readWiFiNetworkManagementInteraction readWiFiNetworkManagementSsidCommandParams ); result.put("readSsidAttribute", readWiFiNetworkManagementSsidAttributeInteractionInfo); + Map readWiFiNetworkManagementPassphraseSurrogateCommandParams = new LinkedHashMap(); + InteractionInfo readWiFiNetworkManagementPassphraseSurrogateAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WiFiNetworkManagementCluster) cluster).readPassphraseSurrogateAttribute( + (ChipClusters.WiFiNetworkManagementCluster.PassphraseSurrogateAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWiFiNetworkManagementClusterPassphraseSurrogateAttributeCallback(), + readWiFiNetworkManagementPassphraseSurrogateCommandParams + ); + result.put("readPassphraseSurrogateAttribute", readWiFiNetworkManagementPassphraseSurrogateAttributeInteractionInfo); Map readWiFiNetworkManagementGeneratedCommandListCommandParams = new LinkedHashMap(); InteractionInfo readWiFiNetworkManagementGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt new file mode 100644 index 00000000000000..56d9b39e1a005e --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt @@ -0,0 +1,55 @@ +/* + * + * 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 AccessControlClusterAccessRestrictionEntryChangedEvent(val fabricIndex: UInt) { + override fun toString(): String = buildString { + append("AccessControlClusterAccessRestrictionEntryChangedEvent {\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): AccessControlClusterAccessRestrictionEntryChangedEvent { + tlvReader.enterStructure(tlvTag) + val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return AccessControlClusterAccessRestrictionEntryChangedEvent(fabricIndex) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt new file mode 100644 index 00000000000000..92934af0a1b4e1 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt @@ -0,0 +1,97 @@ +/* + * + * 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 AccessControlClusterFabricRestrictionReviewUpdateEvent( + val token: ULong, + val instruction: String?, + val redirectURL: String?, + val fabricIndex: UInt, +) { + override fun toString(): String = buildString { + append("AccessControlClusterFabricRestrictionReviewUpdateEvent {\n") + append("\ttoken : $token\n") + append("\tinstruction : $instruction\n") + append("\tredirectURL : $redirectURL\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_TOKEN), token) + if (instruction != null) { + put(ContextSpecificTag(TAG_INSTRUCTION), instruction) + } else { + putNull(ContextSpecificTag(TAG_INSTRUCTION)) + } + if (redirectURL != null) { + put(ContextSpecificTag(TAG_REDIRECT_U_R_L), redirectURL) + } else { + putNull(ContextSpecificTag(TAG_REDIRECT_U_R_L)) + } + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_TOKEN = 0 + private const val TAG_INSTRUCTION = 1 + private const val TAG_REDIRECT_U_R_L = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): AccessControlClusterFabricRestrictionReviewUpdateEvent { + tlvReader.enterStructure(tlvTag) + val token = tlvReader.getULong(ContextSpecificTag(TAG_TOKEN)) + val instruction = + if (!tlvReader.isNull()) { + tlvReader.getString(ContextSpecificTag(TAG_INSTRUCTION)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_INSTRUCTION)) + null + } + val redirectURL = + if (!tlvReader.isNull()) { + tlvReader.getString(ContextSpecificTag(TAG_REDIRECT_U_R_L)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_REDIRECT_U_R_L)) + null + } + val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return AccessControlClusterFabricRestrictionReviewUpdateEvent( + token, + instruction, + redirectURL, + fabricIndex, + ) + } + } +} 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 35bec1ec2b451e..e101562093412c 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -5,6 +5,9 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessControlEntryStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessControlExtensionStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessControlTargetStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessRestrictionEntryStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessRestrictionStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterCommissioningAccessRestrictionEntryStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ActionsClusterActionStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ActionsClusterEndpointListStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ActivatedCarbonFilterMonitoringClusterReplacementProductStruct.kt", @@ -157,6 +160,8 @@ structs_sources = [ eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlEntryChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessControlExtensionChangedEvent.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/AccountLoginClusterLoggedOutEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ActionsClusterActionFailedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/ActionsClusterStateChangedEvent.kt", diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessRestrictionEntryStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessRestrictionEntryStruct.kt new file mode 100644 index 00000000000000..155295421d82d7 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessRestrictionEntryStruct.kt @@ -0,0 +1,89 @@ +/* + * + * 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 AccessControlClusterAccessRestrictionEntryStruct( + val endpoint: UInt, + val cluster: ULong, + val restrictions: List, + val fabricIndex: UInt, +) { + override fun toString(): String = buildString { + append("AccessControlClusterAccessRestrictionEntryStruct {\n") + append("\tendpoint : $endpoint\n") + append("\tcluster : $cluster\n") + append("\trestrictions : $restrictions\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_ENDPOINT), endpoint) + put(ContextSpecificTag(TAG_CLUSTER), cluster) + startArray(ContextSpecificTag(TAG_RESTRICTIONS)) + for (item in restrictions.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_ENDPOINT = 0 + private const val TAG_CLUSTER = 1 + private const val TAG_RESTRICTIONS = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): AccessControlClusterAccessRestrictionEntryStruct { + tlvReader.enterStructure(tlvTag) + val endpoint = tlvReader.getUInt(ContextSpecificTag(TAG_ENDPOINT)) + val cluster = tlvReader.getULong(ContextSpecificTag(TAG_CLUSTER)) + val restrictions = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_RESTRICTIONS)) + while (!tlvReader.isEndOfContainer()) { + add(AccessControlClusterAccessRestrictionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return AccessControlClusterAccessRestrictionEntryStruct( + endpoint, + cluster, + restrictions, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessRestrictionStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessRestrictionStruct.kt new file mode 100644 index 00000000000000..ae0cd7214cc140 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterAccessRestrictionStruct.kt @@ -0,0 +1,66 @@ +/* + * + * 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.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class AccessControlClusterAccessRestrictionStruct(val type: UInt, val id: ULong?) { + override fun toString(): String = buildString { + append("AccessControlClusterAccessRestrictionStruct {\n") + append("\ttype : $type\n") + append("\tid : $id\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_TYPE), type) + if (id != null) { + put(ContextSpecificTag(TAG_ID), id) + } else { + putNull(ContextSpecificTag(TAG_ID)) + } + endStructure() + } + } + + companion object { + private const val TAG_TYPE = 0 + private const val TAG_ID = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): AccessControlClusterAccessRestrictionStruct { + tlvReader.enterStructure(tlvTag) + val type = tlvReader.getUInt(ContextSpecificTag(TAG_TYPE)) + val id = + if (!tlvReader.isNull()) { + tlvReader.getULong(ContextSpecificTag(TAG_ID)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_ID)) + null + } + + tlvReader.exitContainer() + + return AccessControlClusterAccessRestrictionStruct(type, id) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterCommissioningAccessRestrictionEntryStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterCommissioningAccessRestrictionEntryStruct.kt new file mode 100644 index 00000000000000..c19d1e6c8a248a --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/AccessControlClusterCommissioningAccessRestrictionEntryStruct.kt @@ -0,0 +1,83 @@ +/* + * + * 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 AccessControlClusterCommissioningAccessRestrictionEntryStruct( + val endpoint: UInt, + val cluster: ULong, + val restrictions: List, +) { + override fun toString(): String = buildString { + append("AccessControlClusterCommissioningAccessRestrictionEntryStruct {\n") + append("\tendpoint : $endpoint\n") + append("\tcluster : $cluster\n") + append("\trestrictions : $restrictions\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_ENDPOINT), endpoint) + put(ContextSpecificTag(TAG_CLUSTER), cluster) + startArray(ContextSpecificTag(TAG_RESTRICTIONS)) + for (item in restrictions.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_ENDPOINT = 0 + private const val TAG_CLUSTER = 1 + private const val TAG_RESTRICTIONS = 2 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): AccessControlClusterCommissioningAccessRestrictionEntryStruct { + tlvReader.enterStructure(tlvTag) + val endpoint = tlvReader.getUInt(ContextSpecificTag(TAG_ENDPOINT)) + val cluster = tlvReader.getULong(ContextSpecificTag(TAG_CLUSTER)) + val restrictions = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_RESTRICTIONS)) + while (!tlvReader.isEndOfContainer()) { + add(AccessControlClusterAccessRestrictionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return AccessControlClusterCommissioningAccessRestrictionEntryStruct( + endpoint, + cluster, + restrictions, + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/AccessControlCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/AccessControlCluster.kt index 05caa07c4e9b3e..099162a899b419 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/AccessControlCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/AccessControlCluster.kt @@ -22,6 +22,8 @@ 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 @@ -34,7 +36,9 @@ 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 @@ -64,6 +68,31 @@ class AccessControlCluster( object SubscriptionEstablished : ExtensionAttributeSubscriptionState() } + class CommissioningARLAttribute( + val value: List? + ) + + sealed class CommissioningARLAttributeSubscriptionState { + data class Success( + val value: List? + ) : CommissioningARLAttributeSubscriptionState() + + data class Error(val exception: Exception) : CommissioningARLAttributeSubscriptionState() + + object SubscriptionEstablished : CommissioningARLAttributeSubscriptionState() + } + + class ArlAttribute(val value: List?) + + sealed class ArlAttributeSubscriptionState { + data class Success(val value: List?) : + ArlAttributeSubscriptionState() + + data class Error(val exception: Exception) : ArlAttributeSubscriptionState() + + object SubscriptionEstablished : ArlAttributeSubscriptionState() + } + class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -104,6 +133,34 @@ class AccessControlCluster( object SubscriptionEstablished : AttributeListAttributeSubscriptionState() } + suspend fun reviewFabricRestrictions( + arl: List, + timedInvokeTimeout: Duration? = null, + ) { + val commandId: UInt = 0u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_ARL_REQ: Int = 0 + tlvWriter.startArray(ContextSpecificTag(TAG_ARL_REQ)) + for (item in arl.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + 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 readAclAttribute(): AclAttribute { val ATTRIBUTE_ID: UInt = 0u @@ -654,6 +711,229 @@ class AccessControlCluster( } } + suspend fun readCommissioningARLAttribute(): CommissioningARLAttribute { + 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) { "Commissioningarl attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + AccessControlClusterCommissioningAccessRestrictionEntryStruct.fromTlv( + AnonymousTag, + tlvReader, + ) + ) + } + tlvReader.exitContainer() + } + } else { + null + } + + return CommissioningARLAttribute(decodedValue) + } + + suspend fun subscribeCommissioningARLAttribute( + 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( + CommissioningARLAttributeSubscriptionState.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) { + "Commissioningarl attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + AccessControlClusterCommissioningAccessRestrictionEntryStruct.fromTlv( + AnonymousTag, + tlvReader, + ) + ) + } + tlvReader.exitContainer() + } + } else { + null + } + + decodedValue?.let { emit(CommissioningARLAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(CommissioningARLAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readArlAttribute(): ArlAttribute { + val ATTRIBUTE_ID: UInt = 6u + + 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) { "Arl attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(AccessControlClusterAccessRestrictionEntryStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + } else { + null + } + + return ArlAttribute(decodedValue) + } + + suspend fun subscribeArlAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 6u + 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( + ArlAttributeSubscriptionState.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) { "Arl attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List? = + if (tlvReader.isNextTag(AnonymousTag)) { + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + AccessControlClusterAccessRestrictionEntryStruct.fromTlv( + AnonymousTag, + tlvReader, + ) + ) + } + tlvReader.exitContainer() + } + } else { + null + } + + decodedValue?.let { emit(ArlAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(ArlAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { val ATTRIBUTE_ID: UInt = 65528u diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt index 45adb1bb8f7820..64742323eec50c 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/BridgedDeviceBasicInformationCluster.kt @@ -40,6 +40,7 @@ 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 @@ -100,11 +101,14 @@ class BridgedDeviceBasicInformationCluster( object SubscriptionEstablished : AttributeListAttributeSubscriptionState() } - suspend fun keepActive(timedInvokeTimeout: Duration? = null) { + suspend fun keepActive(stayActiveDuration: UInt, timedInvokeTimeout: Duration? = null) { val commandId: UInt = 128u val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) + + val TAG_STAY_ACTIVE_DURATION_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STAY_ACTIVE_DURATION_REQ), stayActiveDuration) tlvWriter.endStructure() val request: InvokeRequest = diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/GeneralCommissioningCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/GeneralCommissioningCluster.kt index 22a2e64607f404..559a466d01924f 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/GeneralCommissioningCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/GeneralCommissioningCluster.kt @@ -55,6 +55,8 @@ class GeneralCommissioningCluster( class CommissioningCompleteResponse(val errorCode: UByte, val debugText: String) + class SetTCAcknowledgementsResponse(val errorCode: UByte) + class BasicCommissioningInfoAttribute( val value: GeneralCommissioningClusterBasicCommissioningInfo ) @@ -290,6 +292,57 @@ class GeneralCommissioningCluster( return CommissioningCompleteResponse(errorCode_decoded, debugText_decoded) } + suspend fun setTCAcknowledgements( + TCVersion: UShort, + TCUserResponse: UShort, + timedInvokeTimeout: Duration? = null, + ): SetTCAcknowledgementsResponse { + val commandId: UInt = 6u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_T_C_VERSION_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_T_C_VERSION_REQ), TCVersion) + + val TAG_T_C_USER_RESPONSE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_T_C_USER_RESPONSE_REQ), TCUserResponse) + 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_ERROR_CODE: Int = 0 + var errorCode_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_ERROR_CODE)) { + errorCode_decoded = tlvReader.getUByte(tag) + } else { + tlvReader.skipElement() + } + } + + if (errorCode_decoded == null) { + throw IllegalStateException("errorCode not found in TLV") + } + + tlvReader.exitContainer() + + return SetTCAcknowledgementsResponse(errorCode_decoded) + } + suspend fun readBreadcrumbAttribute(): ULong { val ATTRIBUTE_ID: UInt = 0u @@ -745,6 +798,378 @@ class GeneralCommissioningCluster( } } + suspend fun readTCAcceptedVersionAttribute(): UShort? { + 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) { "Tcacceptedversion 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 subscribeTCAcceptedVersionAttribute( + 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( + 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) { + "Tcacceptedversion 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 readTCMinRequiredVersionAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 6u + + 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) { "Tcminrequiredversion 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 subscribeTCMinRequiredVersionAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 6u + 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) { + "Tcminrequiredversion 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 readTCAcknowledgementsAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 7u + + 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) { "Tcacknowledgements 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 subscribeTCAcknowledgementsAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 7u + 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) { + "Tcacknowledgements 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 readTCAcknowledgementsRequiredAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 8u + + 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) { "Tcacknowledgementsrequired attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun subscribeTCAcknowledgementsRequiredAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 8u + 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( + BooleanSubscriptionState.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) { + "Tcacknowledgementsrequired attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(BooleanSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(BooleanSubscriptionState.SubscriptionEstablished) + } + } + } + } + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { val ATTRIBUTE_ID: UInt = 65528u diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt index ed9077402e96af..66db507eb79cd5 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThermostatCluster.kt @@ -582,33 +582,6 @@ class ThermostatCluster(private val controller: MatterController, private val en logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun setTemperatureSetpointHoldPolicy( - temperatureSetpointHoldPolicy: UByte, - timedInvokeTimeout: Duration? = null, - ) { - val commandId: UInt = 11u - - val tlvWriter = TlvWriter() - tlvWriter.startStructure(AnonymousTag) - - val TAG_TEMPERATURE_SETPOINT_HOLD_POLICY_REQ: Int = 0 - tlvWriter.put( - ContextSpecificTag(TAG_TEMPERATURE_SETPOINT_HOLD_POLICY_REQ), - temperatureSetpointHoldPolicy, - ) - 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 readLocalTemperatureAttribute(): LocalTemperatureAttribute { val ATTRIBUTE_ID: UInt = 0u @@ -7557,103 +7530,8 @@ class ThermostatCluster(private val controller: MatterController, private val en } } - suspend fun readTemperatureSetpointHoldPolicyAttribute(): UByte? { - val ATTRIBUTE_ID: UInt = 83u - - 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) { - "Temperaturesetpointholdpolicy 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 subscribeTemperatureSetpointHoldPolicyAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 83u - 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) { - "Temperaturesetpointholdpolicy 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 readSetpointHoldExpiryTimestampAttribute(): SetpointHoldExpiryTimestampAttribute { - val ATTRIBUTE_ID: UInt = 84u + val ATTRIBUTE_ID: UInt = 83u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -7697,7 +7575,7 @@ class ThermostatCluster(private val controller: MatterController, private val en minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 84u + val ATTRIBUTE_ID: UInt = 83u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt index e479f0c79ef0f2..b5af2b1db2895a 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ThreadNetworkDirectoryCluster.kt @@ -154,7 +154,7 @@ class ThreadNetworkDirectoryCluster( suspend fun getOperationalDataset( extendedPanID: ByteArray, - timedInvokeTimeout: Duration, + timedInvokeTimeout: Duration? = null, ): OperationalDatasetResponse { val commandId: UInt = 2u diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt index 32f8edab8d7b69..48efb1cea1f4b2 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt @@ -55,6 +55,16 @@ class WiFiNetworkManagementCluster( object SubscriptionEstablished : SsidAttributeSubscriptionState() } + class PassphraseSurrogateAttribute(val value: ULong?) + + sealed class PassphraseSurrogateAttributeSubscriptionState { + data class Success(val value: ULong?) : PassphraseSurrogateAttributeSubscriptionState() + + data class Error(val exception: Exception) : PassphraseSurrogateAttributeSubscriptionState() + + object SubscriptionEstablished : PassphraseSurrogateAttributeSubscriptionState() + } + class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -139,7 +149,7 @@ class WiFiNetworkManagementCluster( } suspend fun readSsidAttribute(): SsidAttribute { - val ATTRIBUTE_ID: UInt = 1u + val ATTRIBUTE_ID: UInt = 0u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -179,7 +189,7 @@ class WiFiNetworkManagementCluster( minInterval: Int, maxInterval: Int, ): Flow { - val ATTRIBUTE_ID: UInt = 1u + val ATTRIBUTE_ID: UInt = 0u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -231,6 +241,101 @@ class WiFiNetworkManagementCluster( } } + suspend fun readPassphraseSurrogateAttribute(): PassphraseSurrogateAttribute { + 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) { "Passphrasesurrogate attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return PassphraseSurrogateAttribute(decodedValue) + } + + suspend fun subscribePassphraseSurrogateAttribute( + 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( + PassphraseSurrogateAttributeSubscriptionState.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) { + "Passphrasesurrogate attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + tlvReader.getULong(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(PassphraseSurrogateAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(PassphraseSurrogateAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { val ATTRIBUTE_ID: UInt = 65528u diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt new file mode 100644 index 00000000000000..8a272f8854ae12 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt @@ -0,0 +1,55 @@ +/* + * + * 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 AccessControlClusterAccessRestrictionEntryChangedEvent(val fabricIndex: UByte) { + override fun toString(): String = buildString { + append("AccessControlClusterAccessRestrictionEntryChangedEvent {\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): AccessControlClusterAccessRestrictionEntryChangedEvent { + tlvReader.enterStructure(tlvTag) + val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return AccessControlClusterAccessRestrictionEntryChangedEvent(fabricIndex) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt new file mode 100644 index 00000000000000..2dca6ad48fbbe1 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt @@ -0,0 +1,97 @@ +/* + * + * 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 AccessControlClusterFabricRestrictionReviewUpdateEvent( + val token: ULong, + val instruction: String?, + val redirectURL: String?, + val fabricIndex: UByte, +) { + override fun toString(): String = buildString { + append("AccessControlClusterFabricRestrictionReviewUpdateEvent {\n") + append("\ttoken : $token\n") + append("\tinstruction : $instruction\n") + append("\tredirectURL : $redirectURL\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_TOKEN), token) + if (instruction != null) { + put(ContextSpecificTag(TAG_INSTRUCTION), instruction) + } else { + putNull(ContextSpecificTag(TAG_INSTRUCTION)) + } + if (redirectURL != null) { + put(ContextSpecificTag(TAG_REDIRECT_U_R_L), redirectURL) + } else { + putNull(ContextSpecificTag(TAG_REDIRECT_U_R_L)) + } + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_TOKEN = 0 + private const val TAG_INSTRUCTION = 1 + private const val TAG_REDIRECT_U_R_L = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): AccessControlClusterFabricRestrictionReviewUpdateEvent { + tlvReader.enterStructure(tlvTag) + val token = tlvReader.getULong(ContextSpecificTag(TAG_TOKEN)) + val instruction = + if (!tlvReader.isNull()) { + tlvReader.getString(ContextSpecificTag(TAG_INSTRUCTION)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_INSTRUCTION)) + null + } + val redirectURL = + if (!tlvReader.isNull()) { + tlvReader.getString(ContextSpecificTag(TAG_REDIRECT_U_R_L)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_REDIRECT_U_R_L)) + null + } + val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return AccessControlClusterFabricRestrictionReviewUpdateEvent( + token, + instruction, + redirectURL, + fabricIndex, + ) + } + } +} 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 fd3fafa315b932..dc0b4b09ec96f6 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -5,6 +5,9 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessControlEntryStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessControlExtensionStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessControlTargetStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessRestrictionEntryStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessRestrictionStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterCommissioningAccessRestrictionEntryStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ActionsClusterActionStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ActionsClusterEndpointListStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ActivatedCarbonFilterMonitoringClusterReplacementProductStruct.kt", @@ -157,6 +160,8 @@ matter_structs_sources = [ matter_eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessControlEntryChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessControlExtensionChangedEvent.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterAccessRestrictionEntryChangedEvent.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccessControlClusterFabricRestrictionReviewUpdateEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/AccountLoginClusterLoggedOutEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ActionsClusterActionFailedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/ActionsClusterStateChangedEvent.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessRestrictionEntryStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessRestrictionEntryStruct.kt new file mode 100644 index 00000000000000..6750b4fc80c401 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessRestrictionEntryStruct.kt @@ -0,0 +1,89 @@ +/* + * + * 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 AccessControlClusterAccessRestrictionEntryStruct( + val endpoint: UShort, + val cluster: UInt, + val restrictions: List, + val fabricIndex: UByte, +) { + override fun toString(): String = buildString { + append("AccessControlClusterAccessRestrictionEntryStruct {\n") + append("\tendpoint : $endpoint\n") + append("\tcluster : $cluster\n") + append("\trestrictions : $restrictions\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_ENDPOINT), endpoint) + put(ContextSpecificTag(TAG_CLUSTER), cluster) + startArray(ContextSpecificTag(TAG_RESTRICTIONS)) + for (item in restrictions.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_ENDPOINT = 0 + private const val TAG_CLUSTER = 1 + private const val TAG_RESTRICTIONS = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): AccessControlClusterAccessRestrictionEntryStruct { + tlvReader.enterStructure(tlvTag) + val endpoint = tlvReader.getUShort(ContextSpecificTag(TAG_ENDPOINT)) + val cluster = tlvReader.getUInt(ContextSpecificTag(TAG_CLUSTER)) + val restrictions = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_RESTRICTIONS)) + while (!tlvReader.isEndOfContainer()) { + add(AccessControlClusterAccessRestrictionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return AccessControlClusterAccessRestrictionEntryStruct( + endpoint, + cluster, + restrictions, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessRestrictionStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessRestrictionStruct.kt new file mode 100644 index 00000000000000..16452c2baa2919 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterAccessRestrictionStruct.kt @@ -0,0 +1,66 @@ +/* + * + * 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.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class AccessControlClusterAccessRestrictionStruct(val type: UByte, val id: UInt?) { + override fun toString(): String = buildString { + append("AccessControlClusterAccessRestrictionStruct {\n") + append("\ttype : $type\n") + append("\tid : $id\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_TYPE), type) + if (id != null) { + put(ContextSpecificTag(TAG_ID), id) + } else { + putNull(ContextSpecificTag(TAG_ID)) + } + endStructure() + } + } + + companion object { + private const val TAG_TYPE = 0 + private const val TAG_ID = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): AccessControlClusterAccessRestrictionStruct { + tlvReader.enterStructure(tlvTag) + val type = tlvReader.getUByte(ContextSpecificTag(TAG_TYPE)) + val id = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_ID)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_ID)) + null + } + + tlvReader.exitContainer() + + return AccessControlClusterAccessRestrictionStruct(type, id) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterCommissioningAccessRestrictionEntryStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterCommissioningAccessRestrictionEntryStruct.kt new file mode 100644 index 00000000000000..c2c9582400272a --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/AccessControlClusterCommissioningAccessRestrictionEntryStruct.kt @@ -0,0 +1,83 @@ +/* + * + * 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 AccessControlClusterCommissioningAccessRestrictionEntryStruct( + val endpoint: UShort, + val cluster: UInt, + val restrictions: List, +) { + override fun toString(): String = buildString { + append("AccessControlClusterCommissioningAccessRestrictionEntryStruct {\n") + append("\tendpoint : $endpoint\n") + append("\tcluster : $cluster\n") + append("\trestrictions : $restrictions\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_ENDPOINT), endpoint) + put(ContextSpecificTag(TAG_CLUSTER), cluster) + startArray(ContextSpecificTag(TAG_RESTRICTIONS)) + for (item in restrictions.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + endStructure() + } + } + + companion object { + private const val TAG_ENDPOINT = 0 + private const val TAG_CLUSTER = 1 + private const val TAG_RESTRICTIONS = 2 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): AccessControlClusterCommissioningAccessRestrictionEntryStruct { + tlvReader.enterStructure(tlvTag) + val endpoint = tlvReader.getUShort(ContextSpecificTag(TAG_ENDPOINT)) + val cluster = tlvReader.getUInt(ContextSpecificTag(TAG_CLUSTER)) + val restrictions = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_RESTRICTIONS)) + while (!tlvReader.isEndOfContainer()) { + add(AccessControlClusterAccessRestrictionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + tlvReader.exitContainer() + + return AccessControlClusterCommissioningAccessRestrictionEntryStruct( + endpoint, + cluster, + restrictions, + ) + } + } +} diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index b6702569d994d9..49af03e873c702 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -2496,6 +2496,242 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } + case Attributes::CommissioningARL::Id: { + using TypeInfo = Attributes::CommissioningARL::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_endpoint; + std::string newElement_0_endpointClassName = "java/lang/Integer"; + std::string newElement_0_endpointCtorSignature = "(I)V"; + jint jninewElement_0_endpoint = static_cast(entry_0.endpoint); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_endpointClassName.c_str(), + newElement_0_endpointCtorSignature.c_str(), + jninewElement_0_endpoint, newElement_0_endpoint); + jobject newElement_0_cluster; + std::string newElement_0_clusterClassName = "java/lang/Long"; + std::string newElement_0_clusterCtorSignature = "(J)V"; + jlong jninewElement_0_cluster = static_cast(entry_0.cluster); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_clusterClassName.c_str(), + newElement_0_clusterCtorSignature.c_str(), + jninewElement_0_cluster, newElement_0_cluster); + jobject newElement_0_restrictions; + chip::JniReferences::GetInstance().CreateArrayList(newElement_0_restrictions); + + auto iter_newElement_0_restrictions_2 = entry_0.restrictions.begin(); + while (iter_newElement_0_restrictions_2.Next()) + { + auto & entry_2 = iter_newElement_0_restrictions_2.GetValue(); + jobject newElement_2; + jobject newElement_2_type; + std::string newElement_2_typeClassName = "java/lang/Integer"; + std::string newElement_2_typeCtorSignature = "(I)V"; + jint jninewElement_2_type = static_cast(entry_2.type); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_2_typeClassName.c_str(), + newElement_2_typeCtorSignature.c_str(), + jninewElement_2_type, newElement_2_type); + jobject newElement_2_id; + if (entry_2.id.IsNull()) + { + newElement_2_id = nullptr; + } + else + { + std::string newElement_2_idClassName = "java/lang/Long"; + std::string newElement_2_idCtorSignature = "(J)V"; + jlong jninewElement_2_id = static_cast(entry_2.id.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_2_idClassName.c_str(), + newElement_2_idCtorSignature.c_str(), + jninewElement_2_id, newElement_2_id); + } + + jclass accessRestrictionStructStructClass_3; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$AccessControlClusterAccessRestrictionStruct", + accessRestrictionStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterAccessRestrictionStruct"); + return nullptr; + } + + jmethodID accessRestrictionStructStructCtor_3; + err = chip::JniReferences::GetInstance().FindMethod(env, accessRestrictionStructStructClass_3, "", + "(Ljava/lang/Integer;Ljava/lang/Long;)V", + &accessRestrictionStructStructCtor_3); + if (err != CHIP_NO_ERROR || accessRestrictionStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterAccessRestrictionStruct constructor"); + return nullptr; + } + + newElement_2 = env->NewObject(accessRestrictionStructStructClass_3, accessRestrictionStructStructCtor_3, + newElement_2_type, newElement_2_id); + chip::JniReferences::GetInstance().AddToList(newElement_0_restrictions, newElement_2); + } + + jclass commissioningAccessRestrictionEntryStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$AccessControlClusterCommissioningAccessRestrictionEntryStruct", + commissioningAccessRestrictionEntryStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, + "Could not find class ChipStructs$AccessControlClusterCommissioningAccessRestrictionEntryStruct"); + return nullptr; + } + + jmethodID commissioningAccessRestrictionEntryStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod(env, commissioningAccessRestrictionEntryStructStructClass_1, + "", + "(Ljava/lang/Integer;Ljava/lang/Long;Ljava/util/ArrayList;)V", + &commissioningAccessRestrictionEntryStructStructCtor_1); + if (err != CHIP_NO_ERROR || commissioningAccessRestrictionEntryStructStructCtor_1 == nullptr) + { + ChipLogError( + Zcl, + "Could not find ChipStructs$AccessControlClusterCommissioningAccessRestrictionEntryStruct constructor"); + return nullptr; + } + + newElement_0 = env->NewObject(commissioningAccessRestrictionEntryStructStructClass_1, + commissioningAccessRestrictionEntryStructStructCtor_1, newElement_0_endpoint, + newElement_0_cluster, newElement_0_restrictions); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::Arl::Id: { + using TypeInfo = Attributes::Arl::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_endpoint; + std::string newElement_0_endpointClassName = "java/lang/Integer"; + std::string newElement_0_endpointCtorSignature = "(I)V"; + jint jninewElement_0_endpoint = static_cast(entry_0.endpoint); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_endpointClassName.c_str(), + newElement_0_endpointCtorSignature.c_str(), + jninewElement_0_endpoint, newElement_0_endpoint); + jobject newElement_0_cluster; + std::string newElement_0_clusterClassName = "java/lang/Long"; + std::string newElement_0_clusterCtorSignature = "(J)V"; + jlong jninewElement_0_cluster = static_cast(entry_0.cluster); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_clusterClassName.c_str(), + newElement_0_clusterCtorSignature.c_str(), + jninewElement_0_cluster, newElement_0_cluster); + jobject newElement_0_restrictions; + chip::JniReferences::GetInstance().CreateArrayList(newElement_0_restrictions); + + auto iter_newElement_0_restrictions_2 = entry_0.restrictions.begin(); + while (iter_newElement_0_restrictions_2.Next()) + { + auto & entry_2 = iter_newElement_0_restrictions_2.GetValue(); + jobject newElement_2; + jobject newElement_2_type; + std::string newElement_2_typeClassName = "java/lang/Integer"; + std::string newElement_2_typeCtorSignature = "(I)V"; + jint jninewElement_2_type = static_cast(entry_2.type); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_2_typeClassName.c_str(), + newElement_2_typeCtorSignature.c_str(), + jninewElement_2_type, newElement_2_type); + jobject newElement_2_id; + if (entry_2.id.IsNull()) + { + newElement_2_id = nullptr; + } + else + { + std::string newElement_2_idClassName = "java/lang/Long"; + std::string newElement_2_idCtorSignature = "(J)V"; + jlong jninewElement_2_id = static_cast(entry_2.id.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_2_idClassName.c_str(), + newElement_2_idCtorSignature.c_str(), + jninewElement_2_id, newElement_2_id); + } + + jclass accessRestrictionStructStructClass_3; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$AccessControlClusterAccessRestrictionStruct", + accessRestrictionStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterAccessRestrictionStruct"); + return nullptr; + } + + jmethodID accessRestrictionStructStructCtor_3; + err = chip::JniReferences::GetInstance().FindMethod(env, accessRestrictionStructStructClass_3, "", + "(Ljava/lang/Integer;Ljava/lang/Long;)V", + &accessRestrictionStructStructCtor_3); + if (err != CHIP_NO_ERROR || accessRestrictionStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterAccessRestrictionStruct constructor"); + return nullptr; + } + + newElement_2 = env->NewObject(accessRestrictionStructStructClass_3, accessRestrictionStructStructCtor_3, + newElement_2_type, newElement_2_id); + chip::JniReferences::GetInstance().AddToList(newElement_0_restrictions, newElement_2); + } + jobject newElement_0_fabricIndex; + std::string newElement_0_fabricIndexClassName = "java/lang/Integer"; + std::string newElement_0_fabricIndexCtorSignature = "(I)V"; + jint jninewElement_0_fabricIndex = static_cast(entry_0.fabricIndex); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_fabricIndexClassName.c_str(), + newElement_0_fabricIndexCtorSignature.c_str(), + jninewElement_0_fabricIndex, newElement_0_fabricIndex); + + jclass accessRestrictionEntryStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$AccessControlClusterAccessRestrictionEntryStruct", + accessRestrictionEntryStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$AccessControlClusterAccessRestrictionEntryStruct"); + return nullptr; + } + + jmethodID accessRestrictionEntryStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod( + env, accessRestrictionEntryStructStructClass_1, "", + "(Ljava/lang/Integer;Ljava/lang/Long;Ljava/util/ArrayList;Ljava/lang/Integer;)V", + &accessRestrictionEntryStructStructCtor_1); + if (err != CHIP_NO_ERROR || accessRestrictionEntryStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$AccessControlClusterAccessRestrictionEntryStruct constructor"); + return nullptr; + } + + newElement_0 = env->NewObject(accessRestrictionEntryStructStructClass_1, accessRestrictionEntryStructStructCtor_1, + newElement_0_endpoint, newElement_0_cluster, newElement_0_restrictions, + newElement_0_fabricIndex); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } case Attributes::GeneratedCommandList::Id: { using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -5425,6 +5661,70 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jnivalue, value); return value; } + case Attributes::TCAcceptedVersion::Id: { + using TypeInfo = Attributes::TCAcceptedVersion::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::TCMinRequiredVersion::Id: { + using TypeInfo = Attributes::TCMinRequiredVersion::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::TCAcknowledgements::Id: { + using TypeInfo = Attributes::TCAcknowledgements::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::TCAcknowledgementsRequired::Id: { + using TypeInfo = Attributes::TCAcknowledgementsRequired::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Boolean"; + std::string valueCtorSignature = "(Z)V"; + jboolean 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; @@ -31025,22 +31325,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jnivalue, value); return value; } - case Attributes::TemperatureSetpointHoldPolicy::Id: { - using TypeInfo = Attributes::TemperatureSetpointHoldPolicy::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::SetpointHoldExpiryTimestamp::Id: { using TypeInfo = Attributes::SetpointHoldExpiryTimestamp::TypeInfo; TypeInfo::DecodableType cppValue; @@ -38400,6 +38684,29 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } + case Attributes::PassphraseSurrogate::Id: { + using TypeInfo = Attributes::PassphraseSurrogate::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue.Value()); + 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; diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 42868bfd0465b1..7f3c03f9e8ab05 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -500,6 +500,117 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return value; } + case Events::AccessRestrictionEntryChanged::Id: { + Events::AccessRestrictionEntryChanged::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + 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 accessRestrictionEntryChangedStructClass; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipEventStructs$AccessControlClusterAccessRestrictionEntryChangedEvent", + accessRestrictionEntryChangedStructClass); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipEventStructs$AccessControlClusterAccessRestrictionEntryChangedEvent"); + return nullptr; + } + + jmethodID accessRestrictionEntryChangedStructCtor; + err = chip::JniReferences::GetInstance().FindMethod(env, accessRestrictionEntryChangedStructClass, "", + "(Ljava/lang/Integer;)V", &accessRestrictionEntryChangedStructCtor); + if (err != CHIP_NO_ERROR || accessRestrictionEntryChangedStructCtor == nullptr) + { + ChipLogError(Zcl, + "Could not find ChipEventStructs$AccessControlClusterAccessRestrictionEntryChangedEvent constructor"); + return nullptr; + } + + jobject value = env->NewObject(accessRestrictionEntryChangedStructClass, accessRestrictionEntryChangedStructCtor, + value_fabricIndex); + + return value; + } + case Events::FabricRestrictionReviewUpdate::Id: { + Events::FabricRestrictionReviewUpdate::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value_token; + std::string value_tokenClassName = "java/lang/Long"; + std::string value_tokenCtorSignature = "(J)V"; + jlong jnivalue_token = static_cast(cppValue.token); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_tokenClassName.c_str(), value_tokenCtorSignature.c_str(), jnivalue_token, value_token); + + jobject value_instruction; + if (cppValue.instruction.IsNull()) + { + value_instruction = nullptr; + } + else + { + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(cppValue.instruction.Value(), value_instruction)); + } + + jobject value_redirectURL; + if (cppValue.redirectURL.IsNull()) + { + value_redirectURL = nullptr; + } + else + { + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(cppValue.redirectURL.Value(), value_redirectURL)); + } + + 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 fabricRestrictionReviewUpdateStructClass; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipEventStructs$AccessControlClusterFabricRestrictionReviewUpdateEvent", + fabricRestrictionReviewUpdateStructClass); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipEventStructs$AccessControlClusterFabricRestrictionReviewUpdateEvent"); + return nullptr; + } + + jmethodID fabricRestrictionReviewUpdateStructCtor; + err = chip::JniReferences::GetInstance().FindMethod( + env, fabricRestrictionReviewUpdateStructClass, "", + "(Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;)V", + &fabricRestrictionReviewUpdateStructCtor); + if (err != CHIP_NO_ERROR || fabricRestrictionReviewUpdateStructCtor == nullptr) + { + ChipLogError(Zcl, + "Could not find ChipEventStructs$AccessControlClusterFabricRestrictionReviewUpdateEvent constructor"); + return nullptr; + } + + jobject value = env->NewObject(fabricRestrictionReviewUpdateStructClass, fabricRestrictionReviewUpdateStructCtor, + value_token, value_instruction, value_redirectURL, value_fabricIndex); + + return value; + } default: *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; break; diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 6621bbc4bea2a6..275e2e6b63f099 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -867,6 +867,13 @@ class ChipClusters: "clusterName": "AccessControl", "clusterId": 0x0000001F, "commands": { + 0x00000000: { + "commandId": 0x00000000, + "commandName": "ReviewFabricRestrictions", + "args": { + "arl": "CommissioningAccessRestrictionEntryStruct", + }, + }, }, "attributes": { 0x00000000: { @@ -901,6 +908,18 @@ class ChipClusters: "type": "int", "reportable": True, }, + 0x00000005: { + "attributeName": "CommissioningARL", + "attributeId": 0x00000005, + "type": "", + "reportable": True, + }, + 0x00000006: { + "attributeName": "Arl", + "attributeId": 0x00000006, + "type": "", + "reportable": True, + }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, @@ -1932,6 +1951,14 @@ class ChipClusters: "args": { }, }, + 0x00000006: { + "commandId": 0x00000006, + "commandName": "SetTCAcknowledgements", + "args": { + "TCVersion": "int", + "TCUserResponse": "int", + }, + }, }, "attributes": { 0x00000000: { @@ -1965,6 +1992,30 @@ class ChipClusters: "type": "bool", "reportable": True, }, + 0x00000005: { + "attributeName": "TCAcceptedVersion", + "attributeId": 0x00000005, + "type": "int", + "reportable": True, + }, + 0x00000006: { + "attributeName": "TCMinRequiredVersion", + "attributeId": 0x00000006, + "type": "int", + "reportable": True, + }, + 0x00000007: { + "attributeName": "TCAcknowledgements", + "attributeId": 0x00000007, + "type": "int", + "reportable": True, + }, + 0x00000008: { + "attributeName": "TCAcknowledgementsRequired", + "attributeId": 0x00000008, + "type": "bool", + "reportable": True, + }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, @@ -3250,6 +3301,7 @@ class ChipClusters: "commandId": 0x00000080, "commandName": "KeepActive", "args": { + "stayActiveDuration": "int", }, }, }, @@ -8846,13 +8898,6 @@ class ChipClusters: "args": { }, }, - 0x0000000B: { - "commandId": 0x0000000B, - "commandName": "SetTemperatureSetpointHoldPolicy", - "args": { - "temperatureSetpointHoldPolicy": "int", - }, - }, }, "attributes": { 0x00000000: { @@ -9245,14 +9290,8 @@ class ChipClusters: "reportable": True, }, 0x00000053: { - "attributeName": "TemperatureSetpointHoldPolicy", - "attributeId": 0x00000053, - "type": "int", - "reportable": True, - }, - 0x00000054: { "attributeName": "SetpointHoldExpiryTimestamp", - "attributeId": 0x00000054, + "attributeId": 0x00000053, "type": "int", "reportable": True, }, @@ -11828,12 +11867,18 @@ class ChipClusters: }, }, "attributes": { - 0x00000001: { + 0x00000000: { "attributeName": "Ssid", - "attributeId": 0x00000001, + "attributeId": 0x00000000, "type": "bytes", "reportable": True, }, + 0x00000001: { + "attributeName": "PassphraseSurrogate", + "attributeId": 0x00000001, + "type": "int", + "reportable": True, + }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index fe9a008e11066e..9ef896538fb595 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -2535,6 +2535,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="subjectsPerAccessControlEntry", Tag=0x00000002, Type=uint), ClusterObjectFieldDescriptor(Label="targetsPerAccessControlEntry", Tag=0x00000003, Type=uint), ClusterObjectFieldDescriptor(Label="accessControlEntriesPerFabric", Tag=0x00000004, Type=uint), + ClusterObjectFieldDescriptor(Label="commissioningARL", Tag=0x00000005, Type=typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]]), + ClusterObjectFieldDescriptor(Label="arl", Tag=0x00000006, Type=typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]]), 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]), @@ -2548,6 +2550,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: subjectsPerAccessControlEntry: 'uint' = None targetsPerAccessControlEntry: 'uint' = None accessControlEntriesPerFabric: 'uint' = None + commissioningARL: 'typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]]' = None + arl: 'typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None eventList: 'typing.List[uint]' = None @@ -2578,6 +2582,17 @@ class AccessControlEntryPrivilegeEnum(MatterIntEnum): # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, + class AccessRestrictionTypeEnum(MatterIntEnum): + kAttributeAccessForbidden = 0x00 + kAttributeWriteForbidden = 0x01 + kCommandForbidden = 0x02 + kEventForbidden = 0x03 + # 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 an unknown + # enum value. This specific value should never be transmitted. + kUnknownEnumValue = 4, + class ChangeTypeEnum(MatterIntEnum): kChanged = 0x00 kAdded = 0x01 @@ -2588,7 +2603,57 @@ class ChangeTypeEnum(MatterIntEnum): # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, + class Bitmaps: + class Feature(IntFlag): + kExtension = 0x1 + kManagedDevice = 0x2 + class Structs: + @dataclass + class AccessRestrictionStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="type", Tag=0, Type=AccessControl.Enums.AccessRestrictionTypeEnum), + ClusterObjectFieldDescriptor(Label="id", Tag=1, Type=typing.Union[Nullable, uint]), + ]) + + type: 'AccessControl.Enums.AccessRestrictionTypeEnum' = 0 + id: 'typing.Union[Nullable, uint]' = NullValue + + @dataclass + class CommissioningAccessRestrictionEntryStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="endpoint", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="cluster", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="restrictions", Tag=2, Type=typing.List[AccessControl.Structs.AccessRestrictionStruct]), + ]) + + endpoint: 'uint' = 0 + cluster: 'uint' = 0 + restrictions: 'typing.List[AccessControl.Structs.AccessRestrictionStruct]' = field(default_factory=lambda: []) + + @dataclass + class AccessRestrictionEntryStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="endpoint", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="cluster", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="restrictions", Tag=2, Type=typing.List[AccessControl.Structs.AccessRestrictionStruct]), + ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), + ]) + + endpoint: 'uint' = 0 + cluster: 'uint' = 0 + restrictions: 'typing.List[AccessControl.Structs.AccessRestrictionStruct]' = field(default_factory=lambda: []) + fabricIndex: 'uint' = 0 + @dataclass class AccessControlTargetStruct(ClusterObject): @ChipUtility.classproperty @@ -2636,6 +2701,39 @@ def descriptor(cls) -> ClusterObjectDescriptor: data: 'bytes' = b"" fabricIndex: 'uint' = 0 + class Commands: + @dataclass + class ReviewFabricRestrictions(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x0000001F + 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="arl", Tag=0, Type=typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]), + ]) + + arl: 'typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]' = field(default_factory=lambda: []) + + @dataclass + class ReviewFabricRestrictionsResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x0000001F + 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="token", Tag=0, Type=uint), + ]) + + token: 'uint' = 0 + class Attributes: @dataclass class Acl(ClusterAttributeDescriptor): @@ -2717,6 +2815,38 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 + @dataclass + class CommissioningARL(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000001F + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000005 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]]) + + value: 'typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]]' = None + + @dataclass + class Arl(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000001F + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000006 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]]) + + value: 'typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]]' = None + @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -2868,6 +2998,50 @@ def descriptor(cls) -> ClusterObjectDescriptor: latestValue: 'typing.Union[Nullable, AccessControl.Structs.AccessControlExtensionStruct]' = NullValue fabricIndex: 'uint' = 0 + @dataclass + class AccessRestrictionEntryChanged(ClusterEvent): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000001F + + @ChipUtility.classproperty + def event_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), + ]) + + fabricIndex: 'uint' = 0 + + @dataclass + class FabricRestrictionReviewUpdate(ClusterEvent): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x0000001F + + @ChipUtility.classproperty + def event_id(cls) -> int: + return 0x00000003 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="token", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="instruction", Tag=1, Type=typing.Union[Nullable, str]), + ClusterObjectFieldDescriptor(Label="redirectURL", Tag=2, Type=typing.Union[Nullable, str]), + ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), + ]) + + token: 'uint' = 0 + instruction: 'typing.Union[Nullable, str]' = NullValue + redirectURL: 'typing.Union[Nullable, str]' = NullValue + fabricIndex: 'uint' = 0 + @dataclass class Actions(Cluster): @@ -6425,6 +6599,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="regulatoryConfig", Tag=0x00000002, Type=GeneralCommissioning.Enums.RegulatoryLocationTypeEnum), ClusterObjectFieldDescriptor(Label="locationCapability", Tag=0x00000003, Type=GeneralCommissioning.Enums.RegulatoryLocationTypeEnum), ClusterObjectFieldDescriptor(Label="supportsConcurrentConnection", Tag=0x00000004, Type=bool), + ClusterObjectFieldDescriptor(Label="TCAcceptedVersion", Tag=0x00000005, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="TCMinRequiredVersion", Tag=0x00000006, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="TCAcknowledgements", Tag=0x00000007, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="TCAcknowledgementsRequired", Tag=0x00000008, Type=typing.Optional[bool]), 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]), @@ -6438,6 +6616,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: regulatoryConfig: 'GeneralCommissioning.Enums.RegulatoryLocationTypeEnum' = None locationCapability: 'GeneralCommissioning.Enums.RegulatoryLocationTypeEnum' = None supportsConcurrentConnection: 'bool' = None + TCAcceptedVersion: 'typing.Optional[uint]' = None + TCMinRequiredVersion: 'typing.Optional[uint]' = None + TCAcknowledgements: 'typing.Optional[uint]' = None + TCAcknowledgementsRequired: 'typing.Optional[bool]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None eventList: 'typing.List[uint]' = None @@ -6452,11 +6634,14 @@ class CommissioningErrorEnum(MatterIntEnum): kInvalidAuthentication = 0x02 kNoFailSafe = 0x03 kBusyWithOtherAdmin = 0x04 + kRequiredTCNotAccepted = 0x05 + kTCAcknowledgementsNotReceived = 0x06 + kTCMinVersionNotMet = 0x07 # 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 an unknown # enum value. This specific value should never be transmitted. - kUnknownEnumValue = 5, + kUnknownEnumValue = 8, class RegulatoryLocationTypeEnum(MatterIntEnum): kIndoor = 0x00 @@ -6468,6 +6653,10 @@ class RegulatoryLocationTypeEnum(MatterIntEnum): # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, + class Bitmaps: + class Feature(IntFlag): + kTermsAndConditions = 0x1 + class Structs: @dataclass class BasicCommissioningInfo(ClusterObject): @@ -6588,6 +6777,40 @@ def descriptor(cls) -> ClusterObjectDescriptor: errorCode: 'GeneralCommissioning.Enums.CommissioningErrorEnum' = 0 debugText: 'str' = "" + @dataclass + class SetTCAcknowledgements(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000030 + command_id: typing.ClassVar[int] = 0x00000006 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'SetTCAcknowledgementsResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="TCVersion", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="TCUserResponse", Tag=1, Type=uint), + ]) + + TCVersion: 'uint' = 0 + TCUserResponse: 'uint' = 0 + + @dataclass + class SetTCAcknowledgementsResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000030 + command_id: typing.ClassVar[int] = 0x00000007 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="errorCode", Tag=0, Type=GeneralCommissioning.Enums.CommissioningErrorEnum), + ]) + + errorCode: 'GeneralCommissioning.Enums.CommissioningErrorEnum' = 0 + class Attributes: @dataclass class Breadcrumb(ClusterAttributeDescriptor): @@ -6669,6 +6892,70 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'bool' = False + @dataclass + class TCAcceptedVersion(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000030 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000005 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + + @dataclass + class TCMinRequiredVersion(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000030 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000006 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + + @dataclass + class TCAcknowledgements(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000030 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000007 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + + @dataclass + class TCAcknowledgementsRequired(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000030 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000008 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) + + value: 'typing.Optional[bool]' = None + @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -11489,8 +11776,11 @@ class KeepActive(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ + ClusterObjectFieldDescriptor(Label="stayActiveDuration", Tag=0, Type=uint), ]) + stayActiveDuration: 'uint' = 0 + class Attributes: @dataclass class VendorName(ClusterAttributeDescriptor): @@ -32116,8 +32406,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="presets", Tag=0x00000050, Type=typing.Optional[typing.List[Thermostat.Structs.PresetStruct]]), ClusterObjectFieldDescriptor(Label="schedules", Tag=0x00000051, Type=typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]]), ClusterObjectFieldDescriptor(Label="presetsSchedulesEditable", Tag=0x00000052, Type=typing.Optional[bool]), - ClusterObjectFieldDescriptor(Label="temperatureSetpointHoldPolicy", Tag=0x00000053, Type=typing.Optional[uint]), - ClusterObjectFieldDescriptor(Label="setpointHoldExpiryTimestamp", Tag=0x00000054, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="setpointHoldExpiryTimestamp", Tag=0x00000053, 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]), @@ -32186,7 +32475,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: presets: 'typing.Optional[typing.List[Thermostat.Structs.PresetStruct]]' = None schedules: 'typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]]' = None presetsSchedulesEditable: 'typing.Optional[bool]' = None - temperatureSetpointHoldPolicy: 'typing.Optional[uint]' = None setpointHoldExpiryTimestamp: 'typing.Union[None, Nullable, uint]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None @@ -32270,7 +32558,8 @@ class PresetScenarioEnum(MatterIntEnum): kSleep = 0x03 kWake = 0x04 kVacation = 0x05 - kUserDefined = 0x06 + kGoingToSleep = 0x06 + kUserDefined = 0xFE # 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 an unknown @@ -32415,10 +32704,6 @@ class ScheduleTypeFeaturesBitmap(IntFlag): kSupportsNames = 0x4 kSupportsOff = 0x8 - class TemperatureSetpointHoldPolicyBitmap(IntFlag): - kHoldDurationElapsed = 0x1 - kHoldDurationElapsedOrPresetChanged = 0x2 - class Structs: @dataclass class ScheduleTransitionStruct(ClusterObject): @@ -32696,22 +32981,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ]) - @dataclass - class SetTemperatureSetpointHoldPolicy(ClusterCommand): - cluster_id: typing.ClassVar[int] = 0x00000201 - command_id: typing.ClassVar[int] = 0x0000000B - is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None - - @ChipUtility.classproperty - def descriptor(cls) -> ClusterObjectDescriptor: - return ClusterObjectDescriptor( - Fields=[ - ClusterObjectFieldDescriptor(Label="temperatureSetpointHoldPolicy", Tag=0, Type=uint), - ]) - - temperatureSetpointHoldPolicy: 'uint' = 0 - class Attributes: @dataclass class LocalTemperature(ClusterAttributeDescriptor): @@ -33673,22 +33942,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Optional[bool]' = None - @dataclass - class TemperatureSetpointHoldPolicy(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000201 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000053 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - - value: 'typing.Optional[uint]' = None - @dataclass class SetpointHoldExpiryTimestamp(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -33697,7 +33950,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000054 + return 0x00000053 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -41593,7 +41846,8 @@ class WiFiNetworkManagement(Cluster): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="ssid", Tag=0x00000001, Type=typing.Union[Nullable, bytes]), + ClusterObjectFieldDescriptor(Label="ssid", Tag=0x00000000, Type=typing.Union[Nullable, bytes]), + ClusterObjectFieldDescriptor(Label="passphraseSurrogate", Tag=0x00000001, 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]), @@ -41603,6 +41857,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ]) ssid: 'typing.Union[Nullable, bytes]' = None + passphraseSurrogate: 'typing.Union[Nullable, uint]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None eventList: 'typing.List[uint]' = None @@ -41649,7 +41904,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000001 + return 0x00000000 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -41657,6 +41912,22 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Union[Nullable, bytes]' = NullValue + @dataclass + class PassphraseSurrogate(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000451 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) + + value: 'typing.Union[Nullable, uint]' = NullValue + @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -42148,10 +42419,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=bytes), ]) - @ChipUtility.classproperty - def must_use_timed_invoke(cls) -> bool: - return True - extendedPanID: 'bytes' = b"" @dataclass diff --git a/src/controller/python/chip/clusters/__init__.py b/src/controller/python/chip/clusters/__init__.py index 11b6f6e02bcf30..5fbb13dcc616a9 100644 --- a/src/controller/python/chip/clusters/__init__.py +++ b/src/controller/python/chip/clusters/__init__.py @@ -27,23 +27,23 @@ ApplicationBasic, ApplicationLauncher, AudioOutput, BallastConfiguration, BarrierControl, BasicInformation, BinaryInputBasic, Binding, BooleanState, BooleanStateConfiguration, BridgedDeviceBasicInformation, CarbonDioxideConcentrationMeasurement, CarbonMonoxideConcentrationMeasurement, Channel, ColorControl, - ContentControl, ContentLauncher, DemandResponseLoadControl, Descriptor, DeviceEnergyManagement, - DeviceEnergyManagementMode, DiagnosticLogs, DishwasherAlarm, DishwasherMode, DoorLock, EcosystemInformation, - ElectricalEnergyMeasurement, ElectricalMeasurement, ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, - EnergyPreference, EthernetNetworkDiagnostics, FanControl, FaultInjection, FixedLabel, FlowMeasurement, - FormaldehydeConcentrationMeasurement, GeneralCommissioning, GeneralDiagnostics, GroupKeyManagement, Groups, - HepaFilterMonitoring, IcdManagement, Identify, IlluminanceMeasurement, KeypadInput, LaundryDryerControls, - LaundryWasherControls, LaundryWasherMode, LevelControl, LocalizationConfiguration, LowPower, MediaInput, - MediaPlayback, MicrowaveOvenControl, MicrowaveOvenMode, ModeSelect, NetworkCommissioning, - NitrogenDioxideConcentrationMeasurement, OccupancySensing, OnOff, OnOffSwitchConfiguration, - OperationalCredentials, OperationalState, OtaSoftwareUpdateProvider, OtaSoftwareUpdateRequestor, - OvenCavityOperationalState, OvenMode, OzoneConcentrationMeasurement, Pm1ConcentrationMeasurement, - Pm10ConcentrationMeasurement, Pm25ConcentrationMeasurement, PowerSource, PowerSourceConfiguration, - PowerTopology, PressureMeasurement, ProxyConfiguration, ProxyDiscovery, ProxyValid, PulseWidthModulation, - PumpConfigurationAndControl, RadonConcentrationMeasurement, RefrigeratorAlarm, + CommissionerControl, ContentControl, ContentLauncher, DemandResponseLoadControl, Descriptor, + DeviceEnergyManagement, DeviceEnergyManagementMode, DiagnosticLogs, DishwasherAlarm, DishwasherMode, DoorLock, + EcosystemInformation, ElectricalEnergyMeasurement, ElectricalMeasurement, ElectricalPowerMeasurement, + EnergyEvse, EnergyEvseMode, EnergyPreference, EthernetNetworkDiagnostics, FanControl, FaultInjection, + FixedLabel, FlowMeasurement, FormaldehydeConcentrationMeasurement, GeneralCommissioning, GeneralDiagnostics, + GroupKeyManagement, Groups, HepaFilterMonitoring, IcdManagement, Identify, IlluminanceMeasurement, + KeypadInput, LaundryDryerControls, LaundryWasherControls, LaundryWasherMode, LevelControl, + LocalizationConfiguration, LowPower, MediaInput, MediaPlayback, MicrowaveOvenControl, MicrowaveOvenMode, + ModeSelect, NetworkCommissioning, NitrogenDioxideConcentrationMeasurement, OccupancySensing, OnOff, + OnOffSwitchConfiguration, OperationalCredentials, OperationalState, OtaSoftwareUpdateProvider, + OtaSoftwareUpdateRequestor, OvenCavityOperationalState, OvenMode, OzoneConcentrationMeasurement, + Pm1ConcentrationMeasurement, Pm10ConcentrationMeasurement, Pm25ConcentrationMeasurement, PowerSource, + PowerSourceConfiguration, PowerTopology, PressureMeasurement, ProxyConfiguration, ProxyDiscovery, ProxyValid, + PulseWidthModulation, PumpConfigurationAndControl, RadonConcentrationMeasurement, RefrigeratorAlarm, RefrigeratorAndTemperatureControlledCabinetMode, RelativeHumidityMeasurement, RvcCleanMode, - RvcOperationalState, RvcRunMode, ScenesManagement, SmokeCoAlarm, SoftwareDiagnostics, Switch, TargetNavigator, - TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, + RvcOperationalState, RvcRunMode, ScenesManagement, ServiceArea, SmokeCoAlarm, SoftwareDiagnostics, Switch, + TargetNavigator, TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, ThreadBorderRouterManagement, ThreadNetworkDiagnostics, ThreadNetworkDirectory, TimeFormatLocalization, TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, UnitTesting, UserLabel, ValveConfigurationAndControl, WakeOnLan, WaterHeaterManagement, WaterHeaterMode, @@ -52,8 +52,8 @@ __all__ = [Attribute, CHIPClusters, Command, AccessControl, AccountLogin, Actions, ActivatedCarbonFilterMonitoring, AdministratorCommissioning, AirQuality, ApplicationBasic, ApplicationLauncher, AudioOutput, BallastConfiguration, BarrierControl, BasicInformation, BinaryInputBasic, Binding, BooleanState, BooleanStateConfiguration, BridgedDeviceBasicInformation, CarbonDioxideConcentrationMeasurement, - CarbonMonoxideConcentrationMeasurement, Channel, - ColorControl, ContentControl, ContentLauncher, DemandResponseLoadControl, Descriptor, DeviceEnergyManagementMode, DeviceEnergyManagement, DeviceEnergyManagementMode, DiagnosticLogs, DishwasherAlarm, DishwasherMode, + CarbonMonoxideConcentrationMeasurement, Channel, ColorControl, CommissionerControl, + ContentControl, ContentLauncher, DemandResponseLoadControl, Descriptor, DeviceEnergyManagementMode, DeviceEnergyManagement, DeviceEnergyManagementMode, DiagnosticLogs, DishwasherAlarm, DishwasherMode, DoorLock, EcosystemInformation, ElectricalEnergyMeasurement, ElectricalMeasurement, ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, EnergyPreference, EthernetNetworkDiagnostics, FanControl, FaultInjection, FixedLabel, FlowMeasurement, FormaldehydeConcentrationMeasurement, GeneralCommissioning, GeneralDiagnostics, GroupKeyManagement, Groups, @@ -66,7 +66,7 @@ Pm25ConcentrationMeasurement, PowerSource, PowerSourceConfiguration, PowerTopology, PressureMeasurement, ProxyConfiguration, ProxyDiscovery, ProxyValid, PulseWidthModulation, PumpConfigurationAndControl, RadonConcentrationMeasurement, RefrigeratorAlarm, RefrigeratorAndTemperatureControlledCabinetMode, RelativeHumidityMeasurement, RvcCleanMode, - RvcOperationalState, RvcRunMode, ScenesManagement, SmokeCoAlarm, SoftwareDiagnostics, + RvcOperationalState, RvcRunMode, ScenesManagement, ServiceArea, SmokeCoAlarm, SoftwareDiagnostics, Switch, TargetNavigator, TemperatureControl, TemperatureMeasurement, Thermostat, ThermostatUserInterfaceConfiguration, ThreadBorderRouterManagement, ThreadNetworkDiagnostics, ThreadNetworkDirectory, TimeFormatLocalization, TimeSynchronization, TotalVolatileOrganicCompoundsConcentrationMeasurement, UnitLocalization, diff --git a/src/credentials/BUILD.gn b/src/credentials/BUILD.gn index df7afc0c1025ba..670cefcd209c10 100644 --- a/src/credentials/BUILD.gn +++ b/src/credentials/BUILD.gn @@ -13,6 +13,7 @@ # limitations under the License. import("//build_overrides/chip.gni") +import("//build_overrides/jsoncpp.gni") import("//build_overrides/nlassert.gni") import("${chip_root}/src/crypto/crypto.gni") import("${chip_root}/src/lib/core/core.gni") @@ -185,3 +186,17 @@ static_library("file_attestation_trust_store") { "${nlassert_root}:nlassert", ] } + +static_library("test_dac_revocation_delegate") { + output_name = "libTestDACRevocationDelegate" + + sources = [ + "attestation_verifier/TestDACRevocationDelegateImpl.cpp", + "attestation_verifier/TestDACRevocationDelegateImpl.h", + ] + + public_deps = [ + ":credentials", + jsoncpp_root, + ] +} diff --git a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp index f3444b0c303940..14759d850ffc40 100644 --- a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp +++ b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp @@ -610,11 +610,14 @@ CHIP_ERROR DefaultDACVerifier::VerifyNodeOperationalCSRInformation(const ByteSpa void DefaultDACVerifier::CheckForRevokedDACChain(const AttestationInfo & info, Callback::Callback * onCompletion) { - AttestationVerificationResult attestationError = AttestationVerificationResult::kSuccess; - - // TODO(#33124): Implement default version of CheckForRevokedDACChain - - onCompletion->mCall(onCompletion->mContext, info, attestationError); + if (mRevocationDelegate != nullptr) + { + mRevocationDelegate->CheckForRevokedDACChain(info, onCompletion); + } + else + { + onCompletion->mCall(onCompletion->mContext, info, AttestationVerificationResult::kSuccess); + } } bool CsaCdKeysTrustStore::IsCdTestKey(const ByteSpan & kid) const @@ -693,9 +696,10 @@ const AttestationTrustStore * GetTestAttestationTrustStore() return &gTestAttestationTrustStore.get(); } -DeviceAttestationVerifier * GetDefaultDACVerifier(const AttestationTrustStore * paaRootStore) +DeviceAttestationVerifier * GetDefaultDACVerifier(const AttestationTrustStore * paaRootStore, + DeviceAttestationRevocationDelegate * revocationDelegate) { - static DefaultDACVerifier defaultDACVerifier{ paaRootStore }; + static DefaultDACVerifier defaultDACVerifier{ paaRootStore, revocationDelegate }; return &defaultDACVerifier; } diff --git a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h index 346d098a58a337..7e0fc1c4378848 100644 --- a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h +++ b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.h @@ -59,6 +59,10 @@ class DefaultDACVerifier : public DeviceAttestationVerifier public: DefaultDACVerifier(const AttestationTrustStore * paaRootStore) : mAttestationTrustStore(paaRootStore) {} + DefaultDACVerifier(const AttestationTrustStore * paaRootStore, DeviceAttestationRevocationDelegate * revocationDelegate) : + mAttestationTrustStore(paaRootStore), mRevocationDelegate(revocationDelegate) + {} + void VerifyAttestationInformation(const DeviceAttestationVerifier::AttestationInfo & info, Callback::Callback * onCompletion) override; @@ -79,11 +83,17 @@ class DefaultDACVerifier : public DeviceAttestationVerifier CsaCdKeysTrustStore * GetCertificationDeclarationTrustStore() override { return &mCdKeysTrustStore; } + void SetRevocationDelegate(DeviceAttestationRevocationDelegate * revocationDelegate) + { + mRevocationDelegate = revocationDelegate; + } + protected: DefaultDACVerifier() {} CsaCdKeysTrustStore mCdKeysTrustStore; const AttestationTrustStore * mAttestationTrustStore; + DeviceAttestationRevocationDelegate * mRevocationDelegate = nullptr; }; /** @@ -112,7 +122,8 @@ const AttestationTrustStore * GetTestAttestationTrustStore(); * process lifetime. In particular, after the first call it's not * possible to change which AttestationTrustStore is used by this verifier. */ -DeviceAttestationVerifier * GetDefaultDACVerifier(const AttestationTrustStore * paaRootStore); +DeviceAttestationVerifier * GetDefaultDACVerifier(const AttestationTrustStore * paaRootStore, + DeviceAttestationRevocationDelegate * revocationDelegate = nullptr); } // namespace Credentials } // namespace chip diff --git a/src/credentials/attestation_verifier/DeviceAttestationVerifier.h b/src/credentials/attestation_verifier/DeviceAttestationVerifier.h index f45ceae06c23fe..e6915931a73b68 100644 --- a/src/credentials/attestation_verifier/DeviceAttestationVerifier.h +++ b/src/credentials/attestation_verifier/DeviceAttestationVerifier.h @@ -47,6 +47,7 @@ enum class AttestationVerificationResult : uint16_t kPaiVendorIdMismatch = 205, kPaiAuthorityNotFound = 206, kPaiMissing = 207, + kPaiAndDacRevoked = 208, kDacExpired = 300, kDacSignatureInvalid = 301, @@ -418,6 +419,28 @@ class DeviceAttestationVerifier bool mEnableCdTestKeySupport = true; }; +/** + * @brief Interface for checking the device attestation revocation status + * + */ +class DeviceAttestationRevocationDelegate +{ +public: + DeviceAttestationRevocationDelegate() = default; + virtual ~DeviceAttestationRevocationDelegate() = default; + + /** + * @brief Verify whether or not the given DAC chain is revoked. + * + * @param[in] info All of the information required to check for revoked DAC chain. + * @param[in] onCompletion Callback handler to provide Attestation Information Verification result to the caller of + * CheckForRevokedDACChain(). + */ + virtual void + CheckForRevokedDACChain(const DeviceAttestationVerifier::AttestationInfo & info, + Callback::Callback * onCompletion) = 0; +}; + /** * Instance getter for the global DeviceAttestationVerifier. * diff --git a/src/credentials/attestation_verifier/TestDACRevocationDelegateImpl.cpp b/src/credentials/attestation_verifier/TestDACRevocationDelegateImpl.cpp new file mode 100644 index 00000000000000..4e1978525e7327 --- /dev/null +++ b/src/credentials/attestation_verifier/TestDACRevocationDelegateImpl.cpp @@ -0,0 +1,219 @@ +/* + * + * 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 +#include +#include +#include +#include + +#include +#include +#include + +using namespace chip::Crypto; + +namespace chip { +namespace Credentials { + +namespace { +CHIP_ERROR BytesToHexStr(const ByteSpan & bytes, MutableCharSpan & outHexStr) +{ + Encoding::HexFlags flags = Encoding::HexFlags::kUppercase; + ReturnErrorOnFailure(BytesToHex(bytes.data(), bytes.size(), outHexStr.data(), outHexStr.size(), flags)); + outHexStr.reduce_size(2 * bytes.size()); + return CHIP_NO_ERROR; +} +} // anonymous namespace + +CHIP_ERROR TestDACRevocationDelegateImpl::SetDeviceAttestationRevocationSetPath(std::string_view path) +{ + VerifyOrReturnError(path.empty() != true, CHIP_ERROR_INVALID_ARGUMENT); + mDeviceAttestationRevocationSetPath = path; + return CHIP_NO_ERROR; +} + +void TestDACRevocationDelegateImpl::ClearDeviceAttestationRevocationSetPath() +{ + // clear the string_view + mDeviceAttestationRevocationSetPath = mDeviceAttestationRevocationSetPath.substr(0, 0); +} + +// This method parses the below JSON Scheme +// [ +// { +// "type": "revocation_set", +// "issuer_subject_key_id": "", +// "issuer_name": "", +// "revoked_serial_numbers: [ +// "serial1 bytes as base64", +// "serial2 bytes as base64" +// ] +// } +// ] +// +bool TestDACRevocationDelegateImpl::IsEntryInRevocationSet(const CharSpan & akidHexStr, const CharSpan & issuerNameBase64Str, + const CharSpan & serialNumberHexStr) +{ + std::ifstream file(mDeviceAttestationRevocationSetPath.data()); + if (!file.is_open()) + { + ChipLogError(NotSpecified, "Failed to open file: %s", mDeviceAttestationRevocationSetPath.data()); + return false; + } + + // Parse the JSON data incrementally + Json::CharReaderBuilder readerBuilder; + Json::Value jsonData; + std::string errs; + + bool parsingSuccessful = Json::parseFromStream(readerBuilder, file, &jsonData, &errs); + + // Close the file as it's no longer needed + file.close(); + + if (!parsingSuccessful) + { + ChipLogError(NotSpecified, "Failed to parse JSON: %s", errs.c_str()); + return false; + } + + std::string issuerName = std::string(issuerNameBase64Str.data(), issuerNameBase64Str.size()); + std::string serialNumber = std::string(serialNumberHexStr.data(), serialNumberHexStr.size()); + std::string akid = std::string(akidHexStr.data(), akidHexStr.size()); + + for (const auto & revokedSet : jsonData) + { + if (revokedSet["issuer_name"].asString() != issuerName) + { + continue; + } + if (revokedSet["issuer_subject_key_id"].asString() != akid) + { + continue; + } + for (const auto & revokedSerialNumber : revokedSet["revoked_serial_numbers"]) + { + if (revokedSerialNumber.asString() == serialNumber) + { + return true; + } + } + } + return false; +} + +CHIP_ERROR TestDACRevocationDelegateImpl::GetAKIDHexStr(const ByteSpan & certDer, MutableCharSpan & outAKIDHexStr) +{ + uint8_t akidBuf[kAuthorityKeyIdentifierLength]; + MutableByteSpan akid(akidBuf); + + ReturnErrorOnFailure(ExtractAKIDFromX509Cert(certDer, akid)); + + return BytesToHexStr(akid, outAKIDHexStr); +} + +CHIP_ERROR TestDACRevocationDelegateImpl::GetSerialNumberHexStr(const ByteSpan & certDer, MutableCharSpan & outSerialNumberHexStr) +{ + uint8_t serialNumberBuf[kMaxCertificateSerialNumberLength] = { 0 }; + MutableByteSpan serialNumber(serialNumberBuf); + + ReturnErrorOnFailure(ExtractSerialNumberFromX509Cert(certDer, serialNumber)); + return BytesToHexStr(serialNumber, outSerialNumberHexStr); +} + +CHIP_ERROR TestDACRevocationDelegateImpl::GetIssuerNameBase64Str(const ByteSpan & certDer, + MutableCharSpan & outIssuerNameBase64String) +{ + uint8_t issuerBuf[kMaxCertificateDistinguishedNameLength] = { 0 }; + MutableByteSpan issuer(issuerBuf); + + ReturnErrorOnFailure(ExtractIssuerFromX509Cert(certDer, issuer)); + VerifyOrReturnError(outIssuerNameBase64String.size() >= BASE64_ENCODED_LEN(issuer.size()), CHIP_ERROR_BUFFER_TOO_SMALL); + + uint16_t encodedLen = Base64Encode(issuer.data(), static_cast(issuer.size()), outIssuerNameBase64String.data()); + outIssuerNameBase64String.reduce_size(encodedLen); + return CHIP_NO_ERROR; +} + +bool TestDACRevocationDelegateImpl::IsCertificateRevoked(const ByteSpan & certDer) +{ + static constexpr uint32_t maxIssuerBase64Len = BASE64_ENCODED_LEN(kMaxCertificateDistinguishedNameLength); + + char issuerNameBuffer[maxIssuerBase64Len] = { 0 }; + char serialNumberHexStrBuffer[2 * kMaxCertificateSerialNumberLength] = { 0 }; + char akidHexStrBuffer[2 * kAuthorityKeyIdentifierLength] = { 0 }; + + MutableCharSpan issuerName(issuerNameBuffer); + MutableCharSpan serialNumber(serialNumberHexStrBuffer); + MutableCharSpan akid(akidHexStrBuffer); + + VerifyOrReturnValue(CHIP_NO_ERROR == GetIssuerNameBase64Str(certDer, issuerName), false); + ChipLogDetail(NotSpecified, "Issuer: %.*s", static_cast(issuerName.size()), issuerName.data()); + + VerifyOrReturnValue(CHIP_NO_ERROR == GetSerialNumberHexStr(certDer, serialNumber), false); + ChipLogDetail(NotSpecified, "Serial Number: %.*s", static_cast(serialNumber.size()), serialNumber.data()); + + VerifyOrReturnValue(CHIP_NO_ERROR == GetAKIDHexStr(certDer, akid), false); + ChipLogDetail(NotSpecified, "AKID: %.*s", static_cast(akid.size()), akid.data()); + + // TODO: Cross-validate the CRLSignerCertificate and CRLSignerDelegator per spec: #34587 + + return IsEntryInRevocationSet(akid, issuerName, serialNumber); +} + +void TestDACRevocationDelegateImpl::CheckForRevokedDACChain( + const DeviceAttestationVerifier::AttestationInfo & info, + Callback::Callback * onCompletion) +{ + AttestationVerificationResult attestationError = AttestationVerificationResult::kSuccess; + + if (mDeviceAttestationRevocationSetPath.empty()) + { + + onCompletion->mCall(onCompletion->mContext, info, attestationError); + } + + ChipLogDetail(NotSpecified, "Checking for revoked DAC in %s", mDeviceAttestationRevocationSetPath.data()); + + if (IsCertificateRevoked(info.dacDerBuffer)) + { + ChipLogProgress(NotSpecified, "Found revoked DAC in %s", mDeviceAttestationRevocationSetPath.data()); + attestationError = AttestationVerificationResult::kDacRevoked; + } + + ChipLogDetail(NotSpecified, "Checking for revoked PAI in %s", mDeviceAttestationRevocationSetPath.data()); + + if (IsCertificateRevoked(info.paiDerBuffer)) + { + ChipLogProgress(NotSpecified, "Found revoked PAI in %s", mDeviceAttestationRevocationSetPath.data()); + + if (attestationError == AttestationVerificationResult::kDacRevoked) + { + attestationError = AttestationVerificationResult::kPaiAndDacRevoked; + } + else + { + attestationError = AttestationVerificationResult::kPaiRevoked; + } + } + + onCompletion->mCall(onCompletion->mContext, info, attestationError); +} + +} // namespace Credentials +} // namespace chip diff --git a/src/credentials/attestation_verifier/TestDACRevocationDelegateImpl.h b/src/credentials/attestation_verifier/TestDACRevocationDelegateImpl.h new file mode 100644 index 00000000000000..c820e56f5f6ce3 --- /dev/null +++ b/src/credentials/attestation_verifier/TestDACRevocationDelegateImpl.h @@ -0,0 +1,65 @@ +/* + * + * 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. + */ + +#pragma once + +#include +#include +#include + +namespace chip { +namespace Credentials { + +class TestDACRevocationDelegateImpl : public DeviceAttestationRevocationDelegate +{ +public: + TestDACRevocationDelegateImpl() = default; + ~TestDACRevocationDelegateImpl() = default; + + /** + * @brief Verify whether or not the given DAC chain is revoked. + * + * @param[in] info All of the information required to check for revoked DAC chain. + * @param[in] onCompletion Callback handler to provide Attestation Information Verification result to the caller of + * CheckForRevokedDACChain(). + */ + void CheckForRevokedDACChain( + const DeviceAttestationVerifier::AttestationInfo & info, + Callback::Callback * onCompletion) override; + + // Set the path to the device attestation revocation set JSON file. + // revocation set can be generated using credentials/generate-revocation-set.py script + // This API returns CHIP_ERROR_INVALID_ARGUMENT if the path is null. + CHIP_ERROR SetDeviceAttestationRevocationSetPath(std::string_view path); + + // Clear the path to the device attestation revocation set JSON file. + // This can be used to skip the revocation check + void ClearDeviceAttestationRevocationSetPath(); + +private: + CHIP_ERROR GetAKIDHexStr(const ByteSpan & certDer, MutableCharSpan & outAKIDHexStr); + CHIP_ERROR GetSerialNumberHexStr(const ByteSpan & certDer, MutableCharSpan & outSerialNumberHexStr); + CHIP_ERROR GetIssuerNameBase64Str(const ByteSpan & certDer, MutableCharSpan & outIssuerNameBase64String); + bool IsEntryInRevocationSet(const CharSpan & akidHexStr, const CharSpan & issuerNameBase64Str, + const CharSpan & serialNumberHexStr); + bool IsCertificateRevoked(const ByteSpan & certDer); + + std::string_view mDeviceAttestationRevocationSetPath; +}; + +} // namespace Credentials +} // namespace chip diff --git a/src/credentials/tests/BUILD.gn b/src/credentials/tests/BUILD.gn index 99cb1e8e20d322..393b246ef20ee3 100644 --- a/src/credentials/tests/BUILD.gn +++ b/src/credentials/tests/BUILD.gn @@ -68,6 +68,7 @@ chip_test_suite("tests") { "${chip_root}/src/controller:controller", "${chip_root}/src/credentials", "${chip_root}/src/credentials:default_attestation_verifier", + "${chip_root}/src/credentials:test_dac_revocation_delegate", "${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/TestDeviceAttestationCredentials.cpp b/src/credentials/tests/TestDeviceAttestationCredentials.cpp index 85a5d4edfa58a2..0f80df9fa9f6f4 100644 --- a/src/credentials/tests/TestDeviceAttestationCredentials.cpp +++ b/src/credentials/tests/TestDeviceAttestationCredentials.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,8 @@ #include "CHIPAttCert_test_vectors.h" +#include + using namespace chip; using namespace chip::Crypto; using namespace chip::Credentials; @@ -413,3 +416,160 @@ TEST_F(TestDeviceAttestationCredentials, TestAttestationTrustStore) } } } + +static void WriteTestRevokedData(const char * jsonData, const char * fileName) +{ + // TODO: Add option to load test data from the test without using file. #34588 + + // write data to /tmp/sample_revoked_set.json using fstream APIs + std::ofstream file; + file.open(fileName, std::ofstream::out | std::ofstream::trunc); + file << jsonData; + file.close(); +} + +TEST_F(TestDeviceAttestationCredentials, TestDACRevocationDelegateImpl) +{ + uint8_t attestationElementsTestVector[] = { 0 }; + uint8_t attestationChallengeTestVector[] = { 0 }; + uint8_t attestationSignatureTestVector[] = { 0 }; + uint8_t attestationNonceTestVector[] = { 0 }; + + // Details for TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert + // Issuer: MEYxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBSTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDAQ4MDAw + // AKID: AF42B7094DEBD515EC6ECF33B81115225F325288 + // Serial Number: 0C694F7F866067B2 + // + // Details for TestCerts::sTestCert_PAI_FFF1_8000_Cert + // Issuer: MDAxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBQTEUMBIGCisGAQQBgqJ8AgEMBEZGRjE= + // AKID: 6AFD22771F511FECBF1641976710DCDC31A1717E + // Serial Number: 3E6CE6509AD840CD1 + Credentials::DeviceAttestationVerifier::AttestationInfo info( + ByteSpan(attestationElementsTestVector), ByteSpan(attestationChallengeTestVector), ByteSpan(attestationSignatureTestVector), + TestCerts::sTestCert_PAI_FFF1_8000_Cert, TestCerts::sTestCert_DAC_FFF1_8000_0004_Cert, ByteSpan(attestationNonceTestVector), + static_cast(0xFFF1), 0x8000); + + AttestationVerificationResult attestationResult = AttestationVerificationResult::kNotImplemented; + + Callback::Callback attestationInformationVerificationCallback( + OnAttestationInformationVerificationCallback, &attestationResult); + + TestDACRevocationDelegateImpl revocationDelegateImpl; + + // Test without revocation set + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess); + + const char * tmpJsonFile = "/tmp/sample_revoked_set.json"; + revocationDelegateImpl.SetDeviceAttestationRevocationSetPath(tmpJsonFile); + + // Test empty json + WriteTestRevokedData("", tmpJsonFile); + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess); + + // Test DAC is revoked + const char * jsonData = R"( + [{ + "type": "revocation_set", + "issuer_subject_key_id": "AF42B7094DEBD515EC6ECF33B81115225F325288", + "issuer_name": "MEYxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBSTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDAQ4MDAw", + "revoked_serial_numbers": ["0C694F7F866067B2"] + }] + )"; + WriteTestRevokedData(jsonData, tmpJsonFile); + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kDacRevoked); + + // Test PAI is revoked + jsonData = R"( + [{ + "type": "revocation_set", + "issuer_subject_key_id": "6AFD22771F511FECBF1641976710DCDC31A1717E", + "issuer_name": "MDAxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBQTEUMBIGCisGAQQBgqJ8AgEMBEZGRjE=", + "revoked_serial_numbers": ["3E6CE6509AD840CD"] + }] + )"; + WriteTestRevokedData(jsonData, tmpJsonFile); + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kPaiRevoked); + + // Test DAC and PAI both revoked + jsonData = R"( + [{ + "type": "revocation_set", + "issuer_subject_key_id": "AF42B7094DEBD515EC6ECF33B81115225F325288", + "issuer_name": "MEYxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBSTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDAQ4MDAw", + "revoked_serial_numbers": ["0C694F7F866067B2"] + }, + { + "type": "revocation_set", + "issuer_subject_key_id": "6AFD22771F511FECBF1641976710DCDC31A1717E", + "issuer_name": "MDAxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBQTEUMBIGCisGAQQBgqJ8AgEMBEZGRjE=", + "revoked_serial_numbers": ["3E6CE6509AD840CD"] + }] + )"; + WriteTestRevokedData(jsonData, tmpJsonFile); + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kPaiAndDacRevoked); + + // Test with another test DAC and PAI + Credentials::DeviceAttestationVerifier::AttestationInfo FFF2_8001_info( + ByteSpan(attestationElementsTestVector), ByteSpan(attestationChallengeTestVector), ByteSpan(attestationSignatureTestVector), + TestCerts::sTestCert_PAI_FFF2_8001_Cert, TestCerts::sTestCert_DAC_FFF2_8001_0008_Cert, ByteSpan(attestationNonceTestVector), + static_cast(0xFFF2), 0x8001); + revocationDelegateImpl.CheckForRevokedDACChain(FFF2_8001_info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess); + + // Test issuer does not match + jsonData = R"( + [{ + "type": "revocation_set", + "issuer_subject_key_id": "BF42B7094DEBD515EC6ECF33B81115225F325289", + "issuer_name": "MEYxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBSTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDAQ4MDAw", + "revoked_serial_numbers": ["0C694F7F866067B2"] + }] + )"; + WriteTestRevokedData(jsonData, tmpJsonFile); + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess); + + // Test subject key ID does not match + jsonData = R"( + [{ + "type": "revocation_set", + "issuer_subject_key_id": "BF42B7094DEBD515EC6ECF33B81115225F325289", + "issuer_name": "MEYxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBSTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDAQ4MDAw", + "revoked_serial_numbers": ["0C694F7F866067B2"] + }] + )"; + WriteTestRevokedData(jsonData, tmpJsonFile); + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess); + + // Test serial number does not match + jsonData = R"( + [{ + "type": "revocation_set", + "issuer_subject_key_id": "AF42B7094DEBD515EC6ECF33B81115225F325288", + "issuer_name": "MEYxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBSTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDAQ4MDAw", + "revoked_serial_numbers": ["3E6CE6509AD840CD1", "BC694F7F866067B1"] + }] + )"; + WriteTestRevokedData(jsonData, tmpJsonFile); + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess); + + // Test starting serial number bytes match but not all + jsonData = R"( + [{ + "type": "revocation_set", + "issuer_subject_key_id": "AF42B7094DEBD515EC6ECF33B81115225F325288", + "issuer_name": "MEYxGDAWBgNVBAMMD01hdHRlciBUZXN0IFBBSTEUMBIGCisGAQQBgqJ8AgEMBEZGRjExFDASBgorBgEEAYKifAICDAQ4MDAw", + "revoked_serial_numbers": ["0C694F7F866067B21234"] + }] + )"; + WriteTestRevokedData(jsonData, tmpJsonFile); + revocationDelegateImpl.CheckForRevokedDACChain(info, &attestationInformationVerificationCallback); + EXPECT_EQ(attestationResult, AttestationVerificationResult::kSuccess); +} diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index 98d9588260a460..aed4d52a4c4b3c 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -9699,6 +9699,12 @@ # Targeting 1.4 - HoldTime - HoldTimeLimits + GeneralCommissioning: + # Targeting 1.4 + - TCAcceptedVersion + - TCMinRequiredVersion + - TCAcknowledgements + - TCAcknowledgementsRequired commands: BridgedDeviceBasicInformation: # Targeting 1.4 @@ -9708,6 +9714,10 @@ # for now just start doing that for new additions to it. - StringEchoRequest - StringEchoResponse + GeneralCommissioning: + # Targeting 1.4 + - SetTCAcknowledgements + - SetTCAcknowledgementsResponse structs: Globals: # Test-only value @@ -9723,6 +9733,13 @@ Globals: # Test-only value - TestGlobalEnum + enum values: + GeneralCommissioning: + # Targeting 1.4 + CommissioningErrorEnum: + - RequiredTCNotAccepted + - TCAcknowledgementsNotReceived + - TCMinVersionNotMet bitmaps: BridgedDeviceBasicInformation: # Targeting 1.4 @@ -9730,6 +9747,9 @@ OccupancySensing: # Targeting 1.4 - Feature + GeneralCommissioning: + # Targeting 1.4 + - Feature bitmap values: Switch: Feature: diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 204d15937b23ca..241c006a7074fd 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -402,6 +402,12 @@ static BOOL AttributeIsSpecifiedInAccessControlCluster(AttributeId aAttributeId) case Attributes::AccessControlEntriesPerFabric::Id: { return YES; } + case Attributes::CommissioningARL::Id: { + return YES; + } + case Attributes::Arl::Id: { + return YES; + } case Attributes::GeneratedCommandList::Id: { return YES; } @@ -894,6 +900,18 @@ static BOOL AttributeIsSpecifiedInGeneralCommissioningCluster(AttributeId aAttri case Attributes::SupportsConcurrentConnection::Id: { return YES; } + case Attributes::TCAcceptedVersion::Id: { + return YES; + } + case Attributes::TCMinRequiredVersion::Id: { + return YES; + } + case Attributes::TCAcknowledgements::Id: { + return YES; + } + case Attributes::TCAcknowledgementsRequired::Id: { + return YES; + } case Attributes::GeneratedCommandList::Id: { return YES; } @@ -4161,9 +4179,6 @@ static BOOL AttributeIsSpecifiedInThermostatCluster(AttributeId aAttributeId) case Attributes::PresetsSchedulesEditable::Id: { return YES; } - case Attributes::TemperatureSetpointHoldPolicy::Id: { - return YES; - } case Attributes::SetpointHoldExpiryTimestamp::Id: { return YES; } @@ -5430,6 +5445,9 @@ static BOOL AttributeIsSpecifiedInWiFiNetworkManagementCluster(AttributeId aAttr case Attributes::Ssid::Id: { return YES; } + case Attributes::PassphraseSurrogate::Id: { + return YES; + } case Attributes::GeneratedCommandList::Id: { return YES; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index ca3cc6c5e620eb..a13bd2f3f40433 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -1034,6 +1034,107 @@ static id _Nullable DecodeAttributeValueForAccessControlCluster(AttributeId aAtt value = [NSNumber numberWithUnsignedShort:cppValue]; return value; } + case Attributes::CommissioningARL::Id: { + using TypeInfo = Attributes::CommissioningARL::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(); + MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct * newElement_0; + newElement_0 = [MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct new]; + newElement_0.endpoint = [NSNumber numberWithUnsignedShort:entry_0.endpoint]; + newElement_0.cluster = [NSNumber numberWithUnsignedInt:entry_0.cluster]; + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.restrictions.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + MTRAccessControlClusterAccessRestrictionStruct * newElement_2; + newElement_2 = [MTRAccessControlClusterAccessRestrictionStruct new]; + newElement_2.type = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.type)]; + if (entry_2.id.IsNull()) { + newElement_2.id = nil; + } else { + newElement_2.id = [NSNumber numberWithUnsignedInt:entry_2.id.Value()]; + } + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + newElement_0.restrictions = 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::Arl::Id: { + using TypeInfo = Attributes::Arl::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(); + MTRAccessControlClusterAccessRestrictionEntryStruct * newElement_0; + newElement_0 = [MTRAccessControlClusterAccessRestrictionEntryStruct new]; + newElement_0.endpoint = [NSNumber numberWithUnsignedShort:entry_0.endpoint]; + newElement_0.cluster = [NSNumber numberWithUnsignedInt:entry_0.cluster]; + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.restrictions.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + MTRAccessControlClusterAccessRestrictionStruct * newElement_2; + newElement_2 = [MTRAccessControlClusterAccessRestrictionStruct new]; + newElement_2.type = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.type)]; + if (entry_2.id.IsNull()) { + newElement_2.id = nil; + } else { + newElement_2.id = [NSNumber numberWithUnsignedInt:entry_2.id.Value()]; + } + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + newElement_0.restrictions = array_2; + } + newElement_0.fabricIndex = [NSNumber numberWithUnsignedChar:entry_0.fabricIndex]; + [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; + } default: { break; } @@ -2297,6 +2398,50 @@ static id _Nullable DecodeAttributeValueForGeneralCommissioningCluster(Attribute value = [NSNumber numberWithBool:cppValue]; return value; } + case Attributes::TCAcceptedVersion::Id: { + using TypeInfo = Attributes::TCAcceptedVersion::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::TCMinRequiredVersion::Id: { + using TypeInfo = Attributes::TCMinRequiredVersion::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::TCAcknowledgements::Id: { + using TypeInfo = Attributes::TCAcknowledgements::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::TCAcknowledgementsRequired::Id: { + using TypeInfo = Attributes::TCAcknowledgementsRequired::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithBool:cppValue]; + return value; + } default: { break; } @@ -12470,17 +12615,6 @@ static id _Nullable DecodeAttributeValueForThermostatCluster(AttributeId aAttrib value = [NSNumber numberWithBool:cppValue]; return value; } - case Attributes::TemperatureSetpointHoldPolicy::Id: { - using TypeInfo = Attributes::TemperatureSetpointHoldPolicy::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::SetpointHoldExpiryTimestamp::Id: { using TypeInfo = Attributes::SetpointHoldExpiryTimestamp::TypeInfo; TypeInfo::DecodableType cppValue; @@ -15670,6 +15804,21 @@ static id _Nullable DecodeAttributeValueForWiFiNetworkManagementCluster(Attribut } return value; } + case Attributes::PassphraseSurrogate::Id: { + using TypeInfo = Attributes::PassphraseSurrogate::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 numberWithUnsignedLongLong:cppValue.Value()]; + } + return value; + } default: { break; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 2bcdb3fbc3919e..615dbceadcdf57 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -1007,6 +1007,13 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRBaseClusterAccessControl : MTRGenericBaseCluster +/** + * Command ReviewFabricRestrictions + * + * This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. + */ +- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeACLWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeACLWithValue:(NSArray * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeACLWithValue:(NSArray * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -1041,6 +1048,18 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAccessControlEntriesPerFabricWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)readAttributeCommissioningARLWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeCommissioningARLWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeCommissioningARLWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeARLWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeARLWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeARLWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -2211,6 +2230,12 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissioningCompleteParams * _Nullable)params completion:(void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)commissioningCompleteWithCompletion:(void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +/** + * Command SetTCAcknowledgements + * + * This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. + */ +- (void)setTCAcknowledgementsWithParams:(MTRGeneralCommissioningClusterSetTCAcknowledgementsParams *)params completion:(void (^)(MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeBreadcrumbWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeBreadcrumbWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -2244,6 +2269,30 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeSupportsConcurrentConnectionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)readAttributeTCAcceptedVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeTCAcceptedVersionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeTCAcceptedVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeTCMinRequiredVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeTCMinRequiredVersionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeTCMinRequiredVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeTCAcknowledgementsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeTCAcknowledgementsWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeTCAcknowledgementsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeTCAcknowledgementsRequiredWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeTCAcknowledgementsRequiredWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeTCAcknowledgementsRequiredWithClusterStateCache:(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_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3675,9 +3724,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) * * The server SHALL attempt to keep the devices specified active for StayActiveDuration milliseconds when they are next active. */ -- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)keepActiveWithCompletion:(MTRStatusCompletion)completion - MTR_PROVISIONALLY_AVAILABLE; +- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeVendorNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeVendorNameWithParams:(MTRSubscribeParams *)params @@ -10021,12 +10068,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPresetsSchedulesRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)commitPresetsSchedulesRequestWithCompletion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -/** - * Command SetTemperatureSetpointHoldPolicy - * - * This command sets the set point hold policy. - */ -- (void)setTemperatureSetpointHoldPolicyWithParams:(MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeLocalTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeLocalTemperatureWithParams:(MTRSubscribeParams *)params @@ -10446,12 +10487,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributePresetsSchedulesEditableWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeTemperatureSetpointHoldPolicyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeTemperatureSetpointHoldPolicyWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeTemperatureSetpointHoldPolicyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeSetpointHoldExpiryTimestampWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeSetpointHoldExpiryTimestampWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13348,6 +13383,12 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSData * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeSSIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSData * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)readAttributePassphraseSurrogateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributePassphraseSurrogateWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributePassphraseSurrogateWithClusterStateCache:(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 @@ -17264,12 +17305,24 @@ typedef NS_ENUM(uint8_t, MTRAccessControlPrivilege) { MTRAccessControlPrivilegeAdminister MTR_DEPRECATED("Please use MTRAccessControlEntryPrivilegeAdminister", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) = 0x05, } MTR_DEPRECATED("Please use MTRAccessControlEntryPrivilege", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)); +typedef NS_ENUM(uint8_t, MTRAccessControlAccessRestrictionType) { + MTRAccessControlAccessRestrictionTypeAttributeAccessForbidden MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRAccessControlAccessRestrictionTypeAttributeWriteForbidden MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRAccessControlAccessRestrictionTypeCommandForbidden MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRAccessControlAccessRestrictionTypeEventForbidden MTR_PROVISIONALLY_AVAILABLE = 0x03, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRAccessControlChangeType) { MTRAccessControlChangeTypeChanged MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x00, MTRAccessControlChangeTypeAdded MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x01, MTRAccessControlChangeTypeRemoved MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x02, } MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); +typedef NS_OPTIONS(uint32_t, MTRAccessControlFeature) { + MTRAccessControlFeatureExtension MTR_PROVISIONALLY_AVAILABLE = 0x1, + MTRAccessControlFeatureManagedDevice MTR_PROVISIONALLY_AVAILABLE = 0x2, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRActionsActionError) { MTRActionsActionErrorUnknown MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x00, MTRActionsActionErrorInterrupted MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x01, @@ -17671,6 +17724,9 @@ typedef NS_ENUM(uint8_t, MTRGeneralCommissioningCommissioningError) { MTRGeneralCommissioningCommissioningErrorInvalidAuthentication MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x02, MTRGeneralCommissioningCommissioningErrorNoFailSafe MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x03, MTRGeneralCommissioningCommissioningErrorBusyWithOtherAdmin MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x04, + MTRGeneralCommissioningCommissioningErrorRequiredTCNotAccepted MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRGeneralCommissioningCommissioningErrorTCAcknowledgementsNotReceived MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRGeneralCommissioningCommissioningErrorTCMinVersionNotMet MTR_PROVISIONALLY_AVAILABLE = 0x07, } MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); typedef NS_ENUM(uint8_t, MTRGeneralCommissioningRegulatoryLocationType) { @@ -17679,6 +17735,10 @@ typedef NS_ENUM(uint8_t, MTRGeneralCommissioningRegulatoryLocationType) { MTRGeneralCommissioningRegulatoryLocationTypeIndoorOutdoor MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x02, } MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); +typedef NS_OPTIONS(uint32_t, MTRGeneralCommissioningFeature) { + MTRGeneralCommissioningFeatureTermsAndConditions MTR_PROVISIONALLY_AVAILABLE = 0x1, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRNetworkCommissioningStatus) { MTRNetworkCommissioningStatusSuccess MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x00, MTRNetworkCommissioningStatusOutOfRange MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x01, @@ -19852,7 +19912,8 @@ typedef NS_ENUM(uint8_t, MTRThermostatPresetScenario) { MTRThermostatPresetScenarioSleep MTR_PROVISIONALLY_AVAILABLE = 0x03, MTRThermostatPresetScenarioWake MTR_PROVISIONALLY_AVAILABLE = 0x04, MTRThermostatPresetScenarioVacation MTR_PROVISIONALLY_AVAILABLE = 0x05, - MTRThermostatPresetScenarioUserDefined MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRThermostatPresetScenarioGoingToSleep MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRThermostatPresetScenarioUserDefined MTR_PROVISIONALLY_AVAILABLE = 0xFE, } MTR_PROVISIONALLY_AVAILABLE; typedef NS_ENUM(uint8_t, MTRThermostatSetpointChangeSource) { @@ -20009,11 +20070,6 @@ typedef NS_OPTIONS(uint16_t, MTRThermostatScheduleTypeFeaturesBitmap) { MTRThermostatScheduleTypeFeaturesBitmapSupportsOff MTR_PROVISIONALLY_AVAILABLE = 0x8, } MTR_PROVISIONALLY_AVAILABLE; -typedef NS_OPTIONS(uint8_t, MTRThermostatTemperatureSetpointHoldPolicyBitmap) { - MTRThermostatTemperatureSetpointHoldPolicyBitmapHoldDurationElapsed MTR_PROVISIONALLY_AVAILABLE = 0x1, - MTRThermostatTemperatureSetpointHoldPolicyBitmapHoldDurationElapsedOrPresetChanged MTR_PROVISIONALLY_AVAILABLE = 0x2, -} MTR_PROVISIONALLY_AVAILABLE; - typedef NS_ENUM(uint8_t, MTRFanControlAirflowDirection) { MTRFanControlAirflowDirectionForward MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00, MTRFanControlAirflowDirectionReverse MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x01, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 641fea65515da4..ddbcc431e5dd86 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -7742,6 +7742,31 @@ - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device @implementation MTRBaseClusterAccessControl +- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRAccessControlClusterReviewFabricRestrictionsParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = AccessControl::Commands::ReviewFabricRestrictions::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)readAttributeACLWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = AccessControl::Attributes::Acl::TypeInfo; @@ -8094,6 +8119,78 @@ + (void)readAttributeAccessControlEntriesPerFabricWithClusterStateCache:(MTRClus completion:completion]; } +- (void)readAttributeCommissioningARLWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = AccessControl::Attributes::CommissioningARL::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeCommissioningARLWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = AccessControl::Attributes::CommissioningARL::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeCommissioningARLWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = AccessControl::Attributes::CommissioningARL::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeARLWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = AccessControl::Attributes::Arl::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeARLWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = AccessControl::Attributes::Arl::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeARLWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = AccessControl::Attributes::Arl::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 = AccessControl::Attributes::GeneratedCommandList::TypeInfo; @@ -18015,6 +18112,30 @@ - (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissio queue:self.callbackQueue completion:responseHandler]; } +- (void)setTCAcknowledgementsWithParams:(MTRGeneralCommissioningClusterSetTCAcknowledgementsParams *)params completion:(void (^)(MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRGeneralCommissioningClusterSetTCAcknowledgementsParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = GeneralCommissioning::Commands::SetTCAcknowledgements::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} - (void)readAttributeBreadcrumbWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { @@ -18224,6 +18345,150 @@ + (void)readAttributeSupportsConcurrentConnectionWithClusterStateCache:(MTRClust completion:completion]; } +- (void)readAttributeTCAcceptedVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcceptedVersion::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeTCAcceptedVersionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcceptedVersion::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeTCAcceptedVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcceptedVersion::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeTCMinRequiredVersionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = GeneralCommissioning::Attributes::TCMinRequiredVersion::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeTCMinRequiredVersionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = GeneralCommissioning::Attributes::TCMinRequiredVersion::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeTCMinRequiredVersionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = GeneralCommissioning::Attributes::TCMinRequiredVersion::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeTCAcknowledgementsWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcknowledgements::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeTCAcknowledgementsWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcknowledgements::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeTCAcknowledgementsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcknowledgements::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeTCAcknowledgementsRequiredWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcknowledgementsRequired::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeTCAcknowledgementsRequiredWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcknowledgementsRequired::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeTCAcknowledgementsRequiredWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = GeneralCommissioning::Attributes::TCAcknowledgementsRequired::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 = GeneralCommissioning::Attributes::GeneratedCommandList::TypeInfo; @@ -30658,11 +30923,7 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterBridgedDeviceBasicInformation -- (void)keepActiveWithCompletion:(MTRStatusCompletion)completion -{ - [self keepActiveWithParams:nil completion:completion]; -} -- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams * _Nullable)params completion:(MTRStatusCompletion)completion +- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams *)params completion:(MTRStatusCompletion)completion { if (params == nil) { params = [[MTRBridgedDeviceBasicInformationClusterKeepActiveParams @@ -67977,30 +68238,6 @@ - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPrese queue:self.callbackQueue completion:responseHandler]; } -- (void)setTemperatureSetpointHoldPolicyWithParams:(MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams *)params completion:(MTRStatusCompletion)completion -{ - if (params == nil) { - params = [[MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams - alloc] init]; - } - - auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); - }; - - auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - - using RequestType = Thermostat::Commands::SetTemperatureSetpointHoldPolicy::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)readAttributeLocalTemperatureWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { @@ -71122,42 +71359,6 @@ + (void)readAttributePresetsSchedulesEditableWithClusterStateCache:(MTRClusterSt completion:completion]; } -- (void)readAttributeTemperatureSetpointHoldPolicyWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldPolicy::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeTemperatureSetpointHoldPolicyWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldPolicy::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeTemperatureSetpointHoldPolicyWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Thermostat::Attributes::TemperatureSetpointHoldPolicy::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeSetpointHoldExpiryTimestampWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Thermostat::Attributes::SetpointHoldExpiryTimestamp::TypeInfo; @@ -94495,6 +94696,42 @@ + (void)readAttributeSSIDWithClusterStateCache:(MTRClusterStateCacheContainer *) completion:completion]; } +- (void)readAttributePassphraseSurrogateWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::PassphraseSurrogate::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributePassphraseSurrogateWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WiFiNetworkManagement::Attributes::PassphraseSurrogate::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributePassphraseSurrogateWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WiFiNetworkManagement::Attributes::PassphraseSurrogate::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 = WiFiNetworkManagement::Attributes::GeneratedCommandList::TypeInfo; @@ -95286,9 +95523,6 @@ - (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOper }; auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - if (timedInvokeTimeoutMs == nil) { - timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS); - } using RequestType = ThreadNetworkDirectory::Commands::GetOperationalDataset::Type; [self.device _invokeKnownCommandWithEndpointID:self.endpointID diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 2178edd403cfe4..caec13ea1b284f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -658,6 +658,8 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterAccessControlAttributeSubjectsPerAccessControlEntryID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterAccessControlAttributeTargetsPerAccessControlEntryID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRAttributeIDTypeClusterAccessControlAttributeAccessControlEntriesPerFabricID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000004, + MTRAttributeIDTypeClusterAccessControlAttributeCommissioningARLID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRAttributeIDTypeClusterAccessControlAttributeARLID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, MTRAttributeIDTypeClusterAccessControlAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterAccessControlAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterAccessControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -1192,6 +1194,10 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterGeneralCommissioningAttributeRegulatoryConfigID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterGeneralCommissioningAttributeLocationCapabilityID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRAttributeIDTypeClusterGeneralCommissioningAttributeSupportsConcurrentConnectionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000004, + MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcceptedVersionID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCMinRequiredVersionID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, + MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcknowledgementsID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, + MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcknowledgementsRequiredID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, MTRAttributeIDTypeClusterGeneralCommissioningAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterGeneralCommissioningAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterGeneralCommissioningAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -3487,8 +3493,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterThermostatAttributePresetsID MTR_PROVISIONALLY_AVAILABLE = 0x00000050, MTRAttributeIDTypeClusterThermostatAttributeSchedulesID MTR_PROVISIONALLY_AVAILABLE = 0x00000051, MTRAttributeIDTypeClusterThermostatAttributePresetsSchedulesEditableID MTR_PROVISIONALLY_AVAILABLE = 0x00000052, - MTRAttributeIDTypeClusterThermostatAttributeTemperatureSetpointHoldPolicyID MTR_PROVISIONALLY_AVAILABLE = 0x00000053, - MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000054, + MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000053, MTRAttributeIDTypeClusterThermostatAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterThermostatAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterThermostatAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -4412,7 +4417,8 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, // Cluster WiFiNetworkManagement attributes - MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeSSIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeSSIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterWiFiNetworkManagementAttributePassphraseSurrogateID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -5939,6 +5945,12 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterLevelControlCommandStopWithOnOffID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000007, MTRCommandIDTypeClusterLevelControlCommandMoveToClosestFrequencyID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000008, + // Cluster AccessControl deprecated command id names + + // Cluster AccessControl commands + MTRCommandIDTypeClusterAccessControlCommandReviewFabricRestrictionsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterAccessControlCommandReviewFabricRestrictionsResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster Actions deprecated command id names MTRClusterActionsCommandInstantActionID MTR_DEPRECATED("Please use MTRCommandIDTypeClusterActionsCommandInstantActionID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -6057,6 +6069,8 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterGeneralCommissioningCommandSetRegulatoryConfigResponseID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRCommandIDTypeClusterGeneralCommissioningCommandCommissioningCompleteID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000004, MTRCommandIDTypeClusterGeneralCommissioningCommandCommissioningCompleteResponseID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000005, + MTRCommandIDTypeClusterGeneralCommissioningCommandSetTCAcknowledgementsID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, + MTRCommandIDTypeClusterGeneralCommissioningCommandSetTCAcknowledgementsResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, // Cluster NetworkCommissioning deprecated command id names MTRClusterNetworkCommissioningCommandScanNetworksID @@ -6609,7 +6623,6 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterThermostatCommandStartPresetsSchedulesEditRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, MTRCommandIDTypeClusterThermostatCommandCancelPresetsSchedulesEditRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, MTRCommandIDTypeClusterThermostatCommandCommitPresetsSchedulesRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000009, - MTRCommandIDTypeClusterThermostatCommandSetTemperatureSetpointHoldPolicyID MTR_PROVISIONALLY_AVAILABLE = 0x0000000B, // Cluster FanControl deprecated command id names @@ -7123,6 +7136,8 @@ typedef NS_ENUM(uint32_t, MTREventIDType) { // Cluster AccessControl events MTREventIDTypeClusterAccessControlEventAccessControlEntryChangedID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTREventIDTypeClusterAccessControlEventAccessControlExtensionChangedID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, + MTREventIDTypeClusterAccessControlEventAccessRestrictionEntryChangedID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTREventIDTypeClusterAccessControlEventFabricRestrictionReviewUpdateID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, // Cluster Actions deprecated event names MTRClusterActionsEventStateChangedID diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 575661bfa078bd..406d253ba5fb00 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -897,6 +897,14 @@ result = @"AccessControlEntriesPerFabric"; break; + case MTRAttributeIDTypeClusterAccessControlAttributeCommissioningARLID: + result = @"CommissioningARL"; + break; + + case MTRAttributeIDTypeClusterAccessControlAttributeARLID: + result = @"ARL"; + break; + case MTRAttributeIDTypeClusterAccessControlAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -1533,6 +1541,22 @@ result = @"SupportsConcurrentConnection"; break; + case MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcceptedVersionID: + result = @"TCAcceptedVersion"; + break; + + case MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCMinRequiredVersionID: + result = @"TCMinRequiredVersion"; + break; + + case MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcknowledgementsID: + result = @"TCAcknowledgements"; + break; + + case MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcknowledgementsRequiredID: + result = @"TCAcknowledgementsRequired"; + break; + case MTRAttributeIDTypeClusterGeneralCommissioningAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -5769,10 +5793,6 @@ result = @"PresetsSchedulesEditable"; break; - case MTRAttributeIDTypeClusterThermostatAttributeTemperatureSetpointHoldPolicyID: - result = @"TemperatureSetpointHoldPolicy"; - break; - case MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID: result = @"SetpointHoldExpiryTimestamp"; break; @@ -7419,6 +7439,10 @@ result = @"SSID"; break; + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributePassphraseSurrogateID: + result = @"PassphraseSurrogate"; + break; + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index cefb92935beab4..eb27ead337eda9 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -510,6 +510,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterAccessControl : MTRGenericCluster +- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeACLWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeACLWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeACLWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -524,6 +526,10 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAccessControlEntriesPerFabricWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); +- (NSDictionary * _Nullable)readAttributeCommissioningARLWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeARLWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -544,8 +550,8 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRClusterAccessControl (Availability) /** - * The queue is currently unused, but may be used in the future for calling completions - * for command invocations if commands are added to this cluster. + * 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 @@ -1073,6 +1079,7 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissioningCompleteParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)commissioningCompleteWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRGeneralCommissioningClusterCommissioningCompleteResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)setTCAcknowledgementsWithParams:(MTRGeneralCommissioningClusterSetTCAcknowledgementsParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeBreadcrumbWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (void)writeAttributeBreadcrumbWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1086,6 +1093,14 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeSupportsConcurrentConnectionWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); +- (NSDictionary * _Nullable)readAttributeTCAcceptedVersionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeTCMinRequiredVersionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeTCAcknowledgementsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeTCAcknowledgementsRequiredWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1699,9 +1714,7 @@ MTR_PROVISIONALLY_AVAILABLE MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRClusterBridgedDeviceBasicInformation : MTRGenericCluster -- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)keepActiveWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion - MTR_PROVISIONALLY_AVAILABLE; +- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeVendorNameWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -4653,7 +4666,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPresetsSchedulesRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)commitPresetsSchedulesRequestWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)setTemperatureSetpointHoldPolicyWithParams:(MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeLocalTemperatureWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -4833,8 +4845,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributePresetsSchedulesEditableWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeTemperatureSetpointHoldPolicyWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeSetpointHoldExpiryTimestampWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6169,6 +6179,8 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeSSIDWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributePassphraseSurrogateWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 8c38a6c584b79e..fe261fb6825dc8 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -1617,6 +1617,33 @@ - (instancetype)initWithDevice:(MTRDevice *)device endpoint:(uint16_t)endpoint q @implementation MTRClusterAccessControl +- (void)reviewFabricRestrictionsWithParams:(MTRAccessControlClusterReviewFabricRestrictionsParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRAccessControlClusterReviewFabricRestrictionsParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = AccessControl::Commands::ReviewFabricRestrictions::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)readAttributeACLWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccessControlID) attributeID:@(MTRAttributeIDTypeClusterAccessControlAttributeACLID) params:params]; @@ -1664,6 +1691,16 @@ - (void)writeAttributeExtensionWithValue:(NSDictionary *)dataVal return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccessControlID) attributeID:@(MTRAttributeIDTypeClusterAccessControlAttributeAccessControlEntriesPerFabricID) params:params]; } +- (NSDictionary * _Nullable)readAttributeCommissioningARLWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccessControlID) attributeID:@(MTRAttributeIDTypeClusterAccessControlAttributeCommissioningARLID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeARLWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccessControlID) attributeID:@(MTRAttributeIDTypeClusterAccessControlAttributeARLID) params:params]; +} + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccessControlID) attributeID:@(MTRAttributeIDTypeClusterAccessControlAttributeGeneratedCommandListID) params:params]; @@ -3200,6 +3237,33 @@ - (void)commissioningCompleteWithParams:(MTRGeneralCommissioningClusterCommissio completion:responseHandler]; } +- (void)setTCAcknowledgementsWithParams:(MTRGeneralCommissioningClusterSetTCAcknowledgementsParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRGeneralCommissioningClusterSetTCAcknowledgementsParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = GeneralCommissioning::Commands::SetTCAcknowledgements::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + - (NSDictionary * _Nullable)readAttributeBreadcrumbWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeBreadcrumbID) params:params]; @@ -3236,6 +3300,26 @@ - (void)writeAttributeBreadcrumbWithValue:(NSDictionary *)dataVa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeSupportsConcurrentConnectionID) params:params]; } +- (NSDictionary * _Nullable)readAttributeTCAcceptedVersionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcceptedVersionID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeTCMinRequiredVersionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCMinRequiredVersionID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeTCAcknowledgementsWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcknowledgementsID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeTCAcknowledgementsRequiredWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCAcknowledgementsRequiredID) params:params]; +} + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeGeneratedCommandListID) params:params]; @@ -4944,11 +5028,7 @@ - (void)setDefaultNTPWithParams:(MTRTimeSynchronizationClusterSetDefaultNTPParam @implementation MTRClusterBridgedDeviceBasicInformation -- (void)keepActiveWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion -{ - [self keepActiveWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; -} -- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion { if (params == nil) { params = [[MTRBridgedDeviceBasicInformationClusterKeepActiveParams @@ -13331,33 +13411,6 @@ - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPrese completion:responseHandler]; } -- (void)setTemperatureSetpointHoldPolicyWithParams:(MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion -{ - if (params == nil) { - params = [[MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams - alloc] init]; - } - - auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); - }; - - auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - - using RequestType = Thermostat::Commands::SetTemperatureSetpointHoldPolicy::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)readAttributeLocalTemperatureWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeLocalTemperatureID) params:params]; @@ -13977,11 +14030,6 @@ - (void)writeAttributeSchedulesWithValue:(NSDictionary *)dataVal return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributePresetsSchedulesEditableID) params:params]; } -- (NSDictionary * _Nullable)readAttributeTemperatureSetpointHoldPolicyWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeTemperatureSetpointHoldPolicyID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeSetpointHoldExpiryTimestampWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID) params:params]; @@ -17174,6 +17222,11 @@ - (void)networkPassphraseRequestWithParams:(MTRWiFiNetworkManagementClusterNetwo return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeSSIDID) params:params]; } +- (NSDictionary * _Nullable)readAttributePassphraseSurrogateWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributePassphraseSurrogateID) params:params]; +} + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeGeneratedCommandListID) params:params]; @@ -17455,9 +17508,6 @@ - (void)getOperationalDatasetWithParams:(MTRThreadNetworkDirectoryClusterGetOper }; auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - if (timedInvokeTimeoutMs == nil) { - timedInvokeTimeoutMs = @(MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS); - } using RequestType = ThreadNetworkDirectory::Commands::GetOperationalDataset::Type; [self.device _invokeKnownCommandWithEndpointID:self.endpointID diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 3746227a4f9d21..54073ac579e846 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -942,6 +942,55 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRAccessControlClusterReviewFabricRestrictionsParams : NSObject + +@property (nonatomic, copy) NSArray * _Nonnull arl 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 MTRAccessControlClusterReviewFabricRestrictionsResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull token MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRAccessControlClusterReviewFabricRestrictionsResponseParams 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 MTRActionsClusterInstantActionParams : NSObject @@ -2006,6 +2055,57 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) error:(NSError * __autoreleasing *)error MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0)); @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRGeneralCommissioningClusterSetTCAcknowledgementsParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull tcVersion MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull tcUserResponse 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 MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull errorCode MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams 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 MTRNetworkCommissioningClusterScanNetworksParams : NSObject @@ -2917,6 +3017,8 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRBridgedDeviceBasicInformationClusterKeepActiveParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull stayActiveDuration MTR_PROVISIONALLY_AVAILABLE; /** * Controls whether the command is a timed command (using Timed Invoke). * @@ -7948,36 +8050,6 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end -MTR_PROVISIONALLY_AVAILABLE -@interface MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams : NSObject - -@property (nonatomic, copy) NSNumber * _Nonnull temperatureSetpointHoldPolicy 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_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) @interface MTRFanControlClusterStepParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 8d18518670e808..c49195ce1016eb 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -2511,6 +2511,214 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end +@implementation MTRAccessControlClusterReviewFabricRestrictionsParams +- (instancetype)init +{ + if (self = [super init]) { + + _arl = [NSArray array]; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRAccessControlClusterReviewFabricRestrictionsParams alloc] init]; + + other.arl = self.arl; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: arl:%@; >", NSStringFromClass([self class]), _arl]; + return descriptionString; +} + +@end + +@implementation MTRAccessControlClusterReviewFabricRestrictionsParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictions::Type encodableStruct; + ListFreer listFreer; + { + { + using ListType_0 = std::remove_reference_t; + using ListMemberType_0 = ListMemberTypeGetter::Type; + if (self.arl.count != 0) { + auto * listHolder_0 = new ListHolder(self.arl.count); + if (listHolder_0 == nullptr || listHolder_0->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_0); + for (size_t i_0 = 0; i_0 < self.arl.count; ++i_0) { + if (![self.arl[i_0] isKindOfClass:[MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_0 = (MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct *) self.arl[i_0]; + listHolder_0->mList[i_0].endpoint = element_0.endpoint.unsignedShortValue; + listHolder_0->mList[i_0].cluster = element_0.cluster.unsignedIntValue; + { + using ListType_2 = std::remove_reference_tmList[i_0].restrictions)>; + using ListMemberType_2 = ListMemberTypeGetter::Type; + if (element_0.restrictions.count != 0) { + auto * listHolder_2 = new ListHolder(element_0.restrictions.count); + if (listHolder_2 == nullptr || listHolder_2->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_2); + for (size_t i_2 = 0; i_2 < element_0.restrictions.count; ++i_2) { + if (![element_0.restrictions[i_2] isKindOfClass:[MTRAccessControlClusterAccessRestrictionStruct class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_2 = (MTRAccessControlClusterAccessRestrictionStruct *) element_0.restrictions[i_2]; + listHolder_2->mList[i_2].type = static_castmList[i_2].type)>>(element_2.type.unsignedCharValue); + if (element_2.id == nil) { + listHolder_2->mList[i_2].id.SetNull(); + } else { + auto & nonNullValue_4 = listHolder_2->mList[i_2].id.SetNonNull(); + nonNullValue_4 = element_2.id.unsignedIntValue; + } + } + listHolder_0->mList[i_0].restrictions = ListType_2(listHolder_2->mList, element_0.restrictions.count); + } else { + listHolder_0->mList[i_0].restrictions = ListType_2(); + } + } + } + encodableStruct.arl = ListType_0(listHolder_0->mList, self.arl.count); + } else { + encodableStruct.arl = ListType_0(); + } + } + } + + 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 MTRAccessControlClusterReviewFabricRestrictionsResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _token = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRAccessControlClusterReviewFabricRestrictionsResponseParams alloc] init]; + + other.token = self.token; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: token:%@; >", NSStringFromClass([self class]), _token]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictionsResponse::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 MTRAccessControlClusterReviewFabricRestrictionsResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictionsResponse::DecodableType &)decodableStruct +{ + { + self.token = [NSNumber numberWithUnsignedLongLong:decodableStruct.token]; + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRActionsClusterInstantActionParams - (instancetype)init { @@ -4919,6 +5127,170 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::GeneralC @end +@implementation MTRGeneralCommissioningClusterSetTCAcknowledgementsParams +- (instancetype)init +{ + if (self = [super init]) { + + _tcVersion = @(0); + + _tcUserResponse = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRGeneralCommissioningClusterSetTCAcknowledgementsParams alloc] init]; + + other.tcVersion = self.tcVersion; + other.tcUserResponse = self.tcUserResponse; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: tcVersion:%@; tcUserResponse:%@; >", NSStringFromClass([self class]), _tcVersion, _tcUserResponse]; + return descriptionString; +} + +@end + +@implementation MTRGeneralCommissioningClusterSetTCAcknowledgementsParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgements::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.TCVersion = self.tcVersion.unsignedShortValue; + } + { + encodableStruct.TCUserResponse = self.tcUserResponse.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 MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _errorCode = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams alloc] init]; + + other.errorCode = self.errorCode; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: errorCode:%@; >", NSStringFromClass([self class]), _errorCode]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::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 MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType &)decodableStruct +{ + { + self.errorCode = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.errorCode)]; + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRNetworkCommissioningClusterScanNetworksParams - (instancetype)init { @@ -7560,6 +7932,8 @@ @implementation MTRBridgedDeviceBasicInformationClusterKeepActiveParams - (instancetype)init { if (self = [super init]) { + + _stayActiveDuration = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -7570,6 +7944,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; { auto other = [[MTRBridgedDeviceBasicInformationClusterKeepActiveParams alloc] init]; + other.stayActiveDuration = self.stayActiveDuration; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -7578,7 +7953,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: stayActiveDuration:%@; >", NSStringFromClass([self class]), _stayActiveDuration]; return descriptionString; } @@ -7590,6 +7965,9 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { chip::app::Clusters::BridgedDeviceBasicInformation::Commands::KeepActive::Type encodableStruct; ListFreer listFreer; + { + encodableStruct.stayActiveDuration = self.stayActiveDuration.unsignedIntValue; + } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); if (buffer.IsNull()) { @@ -22650,85 +23028,6 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams -- (instancetype)init -{ - if (self = [super init]) { - - _temperatureSetpointHoldPolicy = @(0); - _timedInvokeTimeoutMs = nil; - _serverSideProcessingTimeout = nil; - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone; -{ - auto other = [[MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams alloc] init]; - - other.temperatureSetpointHoldPolicy = self.temperatureSetpointHoldPolicy; - other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; - other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: temperatureSetpointHoldPolicy:%@; >", NSStringFromClass([self class]), _temperatureSetpointHoldPolicy]; - return descriptionString; -} - -@end - -@implementation MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams (InternalMethods) - -- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader -{ - chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Type encodableStruct; - ListFreer listFreer; - { - encodableStruct.temperatureSetpointHoldPolicy = static_cast>(self.temperatureSetpointHoldPolicy.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 MTRFanControlClusterStepParams - (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 67c37229a00dcc..d3058d649ee710 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -184,6 +184,18 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRAccessControlClusterReviewFabricRestrictionsParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRAccessControlClusterReviewFabricRestrictionsResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictionsResponse::DecodableType &)decodableStruct; + +@end + @interface MTRActionsClusterInstantActionParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @@ -328,6 +340,18 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRGeneralCommissioningClusterSetTCAcknowledgementsParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType &)decodableStruct; + +@end + @interface MTRNetworkCommissioningClusterScanNetworksParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @@ -1492,12 +1516,6 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams (InternalMethods) - -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; - -@end - @interface MTRFanControlClusterStepParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index 6fdc015ad0aac3..6dc2c38f8447ef 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -1011,9 +1011,6 @@ static BOOL CommandNeedsTimedInvokeInThreadNetworkDirectoryCluster(AttributeId a case Commands::RemoveNetwork::Id: { return YES; } - case Commands::GetOperationalDataset::Id: { - return YES; - } default: { return NO; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index fd2bee34f1aafa..4d70a00ee32937 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -304,6 +304,73 @@ static id _Nullable DecodeEventPayloadForAccessControlCluster(EventId aEventId, return value; } + case Events::AccessRestrictionEntryChanged::Id: { + Events::AccessRestrictionEntryChanged::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + + __auto_type * value = [MTRAccessControlClusterAccessRestrictionEntryChangedEvent new]; + + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedChar:cppValue.fabricIndex]; + value.fabricIndex = memberValue; + } while (0); + + return value; + } + case Events::FabricRestrictionReviewUpdate::Id: { + Events::FabricRestrictionReviewUpdate::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + + __auto_type * value = [MTRAccessControlClusterFabricRestrictionReviewUpdateEvent new]; + + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedLongLong:cppValue.token]; + value.token = memberValue; + } while (0); + do { + NSString * _Nullable memberValue; + if (cppValue.instruction.IsNull()) { + memberValue = nil; + } else { + memberValue = AsString(cppValue.instruction.Value()); + if (memberValue == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + } + value.instruction = memberValue; + } while (0); + do { + NSString * _Nullable memberValue; + if (cppValue.redirectURL.IsNull()) { + memberValue = nil; + } else { + memberValue = AsString(cppValue.redirectURL.Value()); + if (memberValue == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + } + value.redirectURL = memberValue; + } while (0); + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedChar:cppValue.fabricIndex]; + value.fabricIndex = memberValue; + } while (0); + + return value; + } default: { break; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 2ce1e1707d2987..3a11fc91e44536 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -55,6 +55,27 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRAccessControlClusterAccessRestrictionStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull type MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable id MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull endpoint MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull cluster MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull restrictions MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRAccessControlClusterAccessRestrictionEntryStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull endpoint MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull cluster MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull restrictions MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0)) @interface MTRAccessControlClusterAccessControlTargetStruct : NSObject @property (nonatomic, copy) NSNumber * _Nullable cluster MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0)); @@ -117,6 +138,19 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRAccessControlClusterAccessRestrictionEntryChangedEvent : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRAccessControlClusterFabricRestrictionReviewUpdateEvent : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull token MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable instruction MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable redirectURL MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRActionsClusterActionStruct : NSObject @property (nonatomic, copy) NSNumber * _Nonnull actionID MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index 5b0eacb0ff3edb..94a6b90dfeac88 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -171,6 +171,105 @@ - (NSString *)description @end +@implementation MTRAccessControlClusterAccessRestrictionStruct +- (instancetype)init +{ + if (self = [super init]) { + + _type = @(0); + + _id = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRAccessControlClusterAccessRestrictionStruct alloc] init]; + + other.type = self.type; + other.id = self.id; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: type:%@; id:%@; >", NSStringFromClass([self class]), _type, _id]; + return descriptionString; +} + +@end + +@implementation MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct +- (instancetype)init +{ + if (self = [super init]) { + + _endpoint = @(0); + + _cluster = @(0); + + _restrictions = [NSArray array]; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct alloc] init]; + + other.endpoint = self.endpoint; + other.cluster = self.cluster; + other.restrictions = self.restrictions; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: endpoint:%@; cluster:%@; restrictions:%@; >", NSStringFromClass([self class]), _endpoint, _cluster, _restrictions]; + return descriptionString; +} + +@end + +@implementation MTRAccessControlClusterAccessRestrictionEntryStruct +- (instancetype)init +{ + if (self = [super init]) { + + _endpoint = @(0); + + _cluster = @(0); + + _restrictions = [NSArray array]; + + _fabricIndex = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRAccessControlClusterAccessRestrictionEntryStruct alloc] init]; + + other.endpoint = self.endpoint; + other.cluster = self.cluster; + other.restrictions = self.restrictions; + other.fabricIndex = self.fabricIndex; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: endpoint:%@; cluster:%@; restrictions:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _endpoint, _cluster, _restrictions, _fabricIndex]; + return descriptionString; +} + +@end + @implementation MTRAccessControlClusterAccessControlTargetStruct - (instancetype)init { @@ -370,6 +469,69 @@ - (NSString *)description @end +@implementation MTRAccessControlClusterAccessRestrictionEntryChangedEvent +- (instancetype)init +{ + if (self = [super init]) { + + _fabricIndex = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRAccessControlClusterAccessRestrictionEntryChangedEvent alloc] init]; + + other.fabricIndex = self.fabricIndex; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: fabricIndex:%@; >", NSStringFromClass([self class]), _fabricIndex]; + return descriptionString; +} + +@end + +@implementation MTRAccessControlClusterFabricRestrictionReviewUpdateEvent +- (instancetype)init +{ + if (self = [super init]) { + + _token = @(0); + + _instruction = nil; + + _redirectURL = nil; + + _fabricIndex = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRAccessControlClusterFabricRestrictionReviewUpdateEvent alloc] init]; + + other.token = self.token; + other.instruction = self.instruction; + other.redirectURL = self.redirectURL; + other.fabricIndex = self.fabricIndex; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: token:%@; instruction:%@; redirectURL:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _token, _instruction, _redirectURL, _fabricIndex]; + return descriptionString; +} + +@end + @implementation MTRActionsClusterActionStruct - (instancetype)init { diff --git a/src/include/platform/CHIPDeviceConfig.h b/src/include/platform/CHIPDeviceConfig.h index 49a94d75c23fcc..bc13696c8c36a2 100644 --- a/src/include/platform/CHIPDeviceConfig.h +++ b/src/include/platform/CHIPDeviceConfig.h @@ -425,6 +425,15 @@ #define CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME "wlan0" #endif +/** + * CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + * + * Enable support for commissioning using Wi-Fi Public Action Frame as the transport. + */ +#ifndef CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#define CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF 0 +#endif + // -------------------- WiFi AP Configuration -------------------- /** diff --git a/src/include/platform/CHIPDeviceEvent.h b/src/include/platform/CHIPDeviceEvent.h index 437b20e670284f..09f4c46b652920 100644 --- a/src/include/platform/CHIPDeviceEvent.h +++ b/src/include/platform/CHIPDeviceEvent.h @@ -281,7 +281,9 @@ enum InternalEventTypes * This event should populate CHIPoBLEConnectionError structure. */ kCHIPoBLEConnectionError, - kCHIPoBLENotifyConfirm + kCHIPoBLENotifyConfirm, + kCHIPoWiFiPAFWriteReceived, + kCHIPoWiFiPAFConnected, }; static_assert(kEventTypeNotSet == 0, "kEventTypeNotSet must be defined as 0"); @@ -491,6 +493,12 @@ struct ChipDeviceEvent final { BLE_CONNECTION_OBJECT ConId; } CHIPoBLENotifyConfirm; +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + struct + { + chip::System::PacketBuffer * Data; + } CHIPoWiFiPAFWriteReceived; +#endif struct { bool RoleChanged : 1; diff --git a/src/include/platform/ConnectivityManager.h b/src/include/platform/ConnectivityManager.h index 817019b3c1c63c..209d7484b92bda 100644 --- a/src/include/platform/ConnectivityManager.h +++ b/src/include/platform/ConnectivityManager.h @@ -35,6 +35,9 @@ #if INET_CONFIG_ENABLE_TCP_ENDPOINT #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#include +#endif namespace chip { @@ -171,6 +174,19 @@ class ConnectivityManager bool IsWiFiStationProvisioned(); void ClearWiFiStationProvision(); CHIP_ERROR GetAndLogWiFiStatsCounters(); +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + struct WiFiPAFAdvertiseParam; + + CHIP_ERROR SetWiFiPAFAdvertisingEnabled(WiFiPAFAdvertiseParam & args); + typedef void (*OnConnectionCompleteFunct)(void * appState); + typedef void (*OnConnectionErrorFunct)(void * appState, CHIP_ERROR err); + CHIP_ERROR WiFiPAFConnect(const SetupDiscriminator & connDiscriminator, void * appState, OnConnectionCompleteFunct onSuccess, + OnConnectionErrorFunct onError); + CHIP_ERROR WiFiPAFCancelConnect(); + CHIP_ERROR WiFiPAFSend(System::PacketBufferHandle && msgBuf); + Transport::WiFiPAFBase * GetWiFiPAF(); + void SetWiFiPAF(Transport::WiFiPAFBase * pmWiFiPAF); +#endif // WiFi AP methods WiFiAPMode GetWiFiAPMode(); @@ -268,6 +284,16 @@ struct ConnectivityManager::SEDIntervalsConfig System::Clock::Milliseconds32 IdleIntervalMS; }; +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +struct ConnectivityManager::WiFiPAFAdvertiseParam +{ + /* To enable/disable WiFiPAF Commissioning */ + bool enable; + /* The optional commands */ + const char * ExtCmds; +}; +#endif + /** * Returns a reference to the public interface of the ConnectivityManager singleton object. * @@ -407,6 +433,29 @@ inline CHIP_ERROR ConnectivityManager::GetAndLogWiFiStatsCounters() return static_cast(this)->_GetAndLogWiFiStatsCounters(); } +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +inline CHIP_ERROR ConnectivityManager::SetWiFiPAFAdvertisingEnabled(WiFiPAFAdvertiseParam & args) +{ + return static_cast(this)->_SetWiFiPAFAdvertisingEnabled(args); +} + +inline CHIP_ERROR ConnectivityManager::WiFiPAFConnect(const SetupDiscriminator & connDiscriminator, void * appState, + OnConnectionCompleteFunct onSuccess, OnConnectionErrorFunct onError) +{ + return static_cast(this)->_WiFiPAFConnect(connDiscriminator, appState, onSuccess, onError); +} + +inline CHIP_ERROR ConnectivityManager::WiFiPAFCancelConnect() +{ + return static_cast(this)->_WiFiPAFCancelConnect(); +} + +inline CHIP_ERROR ConnectivityManager::WiFiPAFSend(chip::System::PacketBufferHandle && msgBuf) +{ + return static_cast(this)->_WiFiPAFSend(std::move(msgBuf)); +} +#endif + inline bool ConnectivityManager::IsThreadEnabled() { return static_cast(this)->_IsThreadEnabled(); @@ -451,6 +500,18 @@ inline void ConnectivityManager::ResetThreadNetworkDiagnosticsCounts() static_cast(this)->_ResetThreadNetworkDiagnosticsCounts(); } +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +inline Transport::WiFiPAFBase * ConnectivityManager::GetWiFiPAF() +{ + return static_cast(this)->_GetWiFiPAF(); +} + +inline void ConnectivityManager::SetWiFiPAF(Transport::WiFiPAFBase * pWiFiPAF) +{ + return static_cast(this)->_SetWiFiPAF(pWiFiPAF); +} +#endif + inline Ble::BleLayer * ConnectivityManager::GetBleLayer() { return static_cast(this)->_GetBleLayer(); diff --git a/src/lib/shell/MainLoopZephyr.cpp b/src/lib/shell/MainLoopZephyr.cpp index 84fca4ef9d29af..108ed2e4385ad7 100644 --- a/src/lib/shell/MainLoopZephyr.cpp +++ b/src/lib/shell/MainLoopZephyr.cpp @@ -91,7 +91,7 @@ int ExecCommandInShellThread(const struct shell * shell, size_t argc, char ** ar return error == CHIP_NO_ERROR ? 0 : -ENOEXEC; } -int RegisterCommands() +int RegisterMatterCommands() { Shell::Engine::Root().RegisterDefaultCommands(); return 0; @@ -99,7 +99,7 @@ int RegisterCommands() } // namespace -SYS_INIT(RegisterCommands, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(RegisterMatterCommands, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); SHELL_CMD_ARG_REGISTER(matter, NULL, "Matter commands", ExecCommandInShellThread, 1, CHIP_SHELL_MAX_TOKENS); namespace chip { diff --git a/src/lib/shell/commands/OnboardingCodes.cpp b/src/lib/shell/commands/OnboardingCodes.cpp index 1e17812d183a3f..a08a63be68770f 100644 --- a/src/lib/shell/commands/OnboardingCodes.cpp +++ b/src/lib/shell/commands/OnboardingCodes.cpp @@ -128,6 +128,13 @@ static CHIP_ERROR RendezvousStringToFlag(char * str, chip::RendezvousInformation *aRendezvousFlags = chip::RendezvousInformationFlag::kOnNetwork; return CHIP_NO_ERROR; } +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + if (strcmp(str, "wifipaf") == 0) + { + *aRendezvousFlags = chip::RendezvousInformationFlag::kWiFiPAF; + return CHIP_NO_ERROR; + } +#endif return CHIP_ERROR_INVALID_ARGUMENT; } diff --git a/src/messaging/ExchangeMgr.cpp b/src/messaging/ExchangeMgr.cpp index 0e41593b08afea..b328be5df82dd5 100644 --- a/src/messaging/ExchangeMgr.cpp +++ b/src/messaging/ExchangeMgr.cpp @@ -223,15 +223,15 @@ void ExchangeManager::OnMessageReceived(const PacketHeader & packetHeader, const // // 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 %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())); + 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() + packetHeader.MICTagLength() + + payloadHeader.EncodeSizeBytes())); #endif MessageFlags msgFlags; diff --git a/src/messaging/tests/java/BUILD.gn b/src/messaging/tests/java/BUILD.gn index b04e48c2224060..2a1ae118670852 100644 --- a/src/messaging/tests/java/BUILD.gn +++ b/src/messaging/tests/java/BUILD.gn @@ -36,7 +36,11 @@ shared_library("jni") { defines = [ "JAVA_MATTER_CONTROLLER_TEST" ] include_dirs = java_matter_controller_dependent_paths - deps += [ "${chip_root}/src/platform/Linux" ] + if (current_os == "mac") { + deps += [ "${chip_root}/src/platform/Darwin" ] + } else { + deps += [ "${chip_root}/src/platform/Linux" ] + } cflags = [ "-Wno-unknown-pragmas" ] diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index 474e3c17ce284b..38becc7ede7471 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -140,6 +140,7 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { "CHIP_USE_TRANSITIONAL_COMMISSIONABLE_DATA_PROVIDER=${chip_use_transitional_commissionable_data_provider}", "CHIP_USE_TRANSITIONAL_DEVICE_INSTANCE_INFO_PROVIDER=${chip_use_transitional_device_instance_info_provider}", "CHIP_DEVICE_CONFIG_ENABLE_DYNAMIC_MRP_CONFIG=${chip_device_config_enable_dynamic_mrp_config}", + "CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF=${chip_device_config_enable_wifipaf}", ] if (chip_device_platform == "linux" || chip_device_platform == "darwin" || diff --git a/src/platform/ESP32/BUILD.gn b/src/platform/ESP32/BUILD.gn index e835896fb59092..587388e3f969be 100644 --- a/src/platform/ESP32/BUILD.gn +++ b/src/platform/ESP32/BUILD.gn @@ -172,6 +172,12 @@ static_library("ESP32") { "../OpenThread/OpenThreadDnssdImpl.h", ] } + if (chip_openthread_border_router) { + sources += [ + "../OpenThread/GenericThreadBorderRouterDelegate.cpp", + "../OpenThread/GenericThreadBorderRouterDelegate.h", + ] + } configs -= [ "${chip_root}/build/config/compiler:warnings_default" ] } diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index cd3922baaf2b02..0ba16f90d874a9 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +65,9 @@ #include #include #include +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#include +#endif #endif using namespace ::chip; @@ -152,6 +156,22 @@ void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) #if CHIP_DEVICE_CONFIG_ENABLE_THREAD GenericConnectivityManagerImpl_Thread::_OnPlatformEvent(event); #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + switch (event->Type) + { + case DeviceEventType::kCHIPoWiFiPAFWriteReceived: + ChipLogProgress(DeviceLayer, "WiFi-PAF: event: kCHIPoWiFiPAFWriteReceived"); + _GetWiFiPAF()->OnWiFiPAFMessageReceived(System::PacketBufferHandle::Adopt(event->CHIPoWiFiPAFWriteReceived.Data)); + break; + case DeviceEventType::kCHIPoWiFiPAFConnected: + ChipLogProgress(DeviceLayer, "WiFi-PAF: event: kCHIPoWiFiPAFConnected"); + if (mOnPafSubscribeComplete != nullptr) + { + mOnPafSubscribeComplete(mAppState); + } + break; + } +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF } #if CHIP_DEVICE_CONFIG_ENABLE_WPA @@ -797,6 +817,113 @@ bool ConnectivityManagerImpl::IsWiFiManagementStarted() return ret; } +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +const char srv_name[] = "_matterc._udp"; +/* + NAN-USD Service Protocol Type: ref: Table 58 of Wi-Fi Aware Specificaiton +*/ +#define MAX_PAF_PUBLISH_SSI_BUFLEN 512 +#define MAX_PAF_TX_SSI_BUFLEN 2048 +#define NAN_SRV_PROTO_MATTER 3 +#define NAM_PUBLISH_PERIOD 300u +#define NAN_PUBLISH_SSI_TAG " ssi=" + +#pragma pack(push, 1) +struct PAFPublishSSI +{ + uint8_t DevOpCode; + uint16_t DevInfo; + uint16_t ProductId; + uint16_t VendorId; +}; +#pragma pack(pop) +CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFPublish(ConnectivityManager::WiFiPAFAdvertiseParam & InArgs) +{ + CHIP_ERROR ret; + GAutoPtr err; + gchar args[MAX_PAF_PUBLISH_SSI_BUFLEN]; + gint publish_id; + size_t req_len; + + snprintf(args, sizeof(args), "service_name=%s srv_proto_type=%u ttl=%u ", srv_name, NAN_SRV_PROTO_MATTER, NAM_PUBLISH_PERIOD); + req_len = strlen(args) + strlen(InArgs.ExtCmds); + if ((InArgs.ExtCmds != nullptr) && (MAX_PAF_PUBLISH_SSI_BUFLEN > req_len)) + { + strcat(args, InArgs.ExtCmds); + } + else + { + ChipLogError(DeviceLayer, "Input cmd is too long: limit:%d, req: %lu", MAX_PAF_PUBLISH_SSI_BUFLEN, req_len); + } + + struct PAFPublishSSI PafPublish_ssi; + VerifyOrReturnError( + (strlen(args) + strlen(NAN_PUBLISH_SSI_TAG) + (sizeof(struct PAFPublishSSI) * 2) < MAX_PAF_PUBLISH_SSI_BUFLEN), + CHIP_ERROR_BUFFER_TOO_SMALL); + PafPublish_ssi.DevOpCode = 0; + VerifyOrDie(DeviceLayer::GetCommissionableDataProvider()->GetSetupDiscriminator(PafPublish_ssi.DevInfo) == CHIP_NO_ERROR); + if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetProductId(PafPublish_ssi.ProductId) != CHIP_NO_ERROR) + { + PafPublish_ssi.ProductId = 0; + } + if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(PafPublish_ssi.VendorId) != CHIP_NO_ERROR) + { + PafPublish_ssi.VendorId = 0; + } + if (MAX_PAF_PUBLISH_SSI_BUFLEN > strlen(args) + strlen(NAN_PUBLISH_SSI_TAG)) + { + strcat(args, NAN_PUBLISH_SSI_TAG); + } + ret = Encoding::BytesToUppercaseHexString((uint8_t *) &PafPublish_ssi, sizeof(PafPublish_ssi), &args[strlen(args)], + MAX_PAF_PUBLISH_SSI_BUFLEN - strlen(args)); + VerifyOrReturnError(ret == CHIP_NO_ERROR, ret); + ChipLogProgress(DeviceLayer, "WiFi-PAF: publish: [%s]", args); + wpa_fi_w1_wpa_supplicant1_interface_call_nanpublish_sync(mWpaSupplicant.iface, args, &publish_id, nullptr, &err.GetReceiver()); + ChipLogProgress(DeviceLayer, "WiFi-PAF: publish_id: %d ! ", publish_id); + + g_signal_connect(mWpaSupplicant.iface, "nan-receive", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * obj, ConnectivityManagerImpl * self) { + return self->OnNanReceive(obj); + }), + this); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFCancelPublish() +{ + GAutoPtr err; + gchar args[MAX_PAF_PUBLISH_SSI_BUFLEN]; + + ChipLogProgress(DeviceLayer, "WiFi-PAF: cancel publish_id: %d ! ", mpaf_info.peer_publish_id); + snprintf(args, sizeof(args), "publish_id=%d", mpaf_info.peer_publish_id); + wpa_fi_w1_wpa_supplicant1_interface_call_nancancel_publish_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConnectivityManagerImpl::_SetWiFiPAFAdvertisingEnabled(WiFiPAFAdvertiseParam & args) +{ + if (args.enable == true) + { + return _WiFiPAFPublish(args); + } + else + { + return _WiFiPAFCancelPublish(); + } +} + +Transport::WiFiPAFBase * ConnectivityManagerImpl::_GetWiFiPAF() +{ + return pmWiFiPAF; +} + +void ConnectivityManagerImpl::_SetWiFiPAF(Transport::WiFiPAFBase * pWiFiPAF) +{ + pmWiFiPAF = pWiFiPAF; + return; +} +#endif + void ConnectivityManagerImpl::StartNonConcurrentWiFiManagement() { StartWiFiManagement(); @@ -1226,6 +1353,229 @@ CHIP_ERROR ConnectivityManagerImpl::ConnectWiFiNetworkWithPDCAsync( return _ConnectWiFiNetworkAsync(args, connectCallback); } #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +/* + NAN-USD Service Protocol Type: ref: Table 58 of Wi-Fi Aware Specificaiton +*/ +#define MAX_PAF_SUBSCRIBE_SSI_BUFLEN 128 +#define NAN_SRV_PROTO_MATTER 3 +#define NAM_SUBSCRIBE_PERIOD 30u +void ConnectivityManagerImpl::OnDiscoveryResult(gboolean success, GVariant * discov_info) +{ + ChipLogProgress(Controller, "WiFi-PAF: OnDiscoveryResult, %d", success); + + std::lock_guard lock(mWpaSupplicantMutex); + if (g_variant_n_children(discov_info) == 0) + { + return; + } + + if (success == true) + { + GAutoPtr dataValue(g_variant_lookup_value(discov_info, "discov_info", G_VARIANT_TYPE_BYTESTRING)); + size_t bufferLen; + auto buffer = g_variant_get_fixed_array(dataValue.get(), &bufferLen, sizeof(uint8_t)); + if (((struct wpa_dbus_discov_info *) buffer)->subscribe_id == mpaf_info.subscribe_id) + { + return; + } + memcpy(&mpaf_info, buffer, sizeof(struct wpa_dbus_discov_info)); + ChipLogProgress(DeviceLayer, "WiFi-PAF: subscribe_id: %u", mpaf_info.subscribe_id); + ChipLogProgress(DeviceLayer, "WiFi-PAF: peer_publish_id: %u", mpaf_info.peer_publish_id); + ChipLogProgress(DeviceLayer, "WiFi-PAF: peer_addr: [%02x:%02x:%02x:%02x:%02x:%02x]", mpaf_info.peer_addr[0], + mpaf_info.peer_addr[1], mpaf_info.peer_addr[2], mpaf_info.peer_addr[3], mpaf_info.peer_addr[4], + mpaf_info.peer_addr[5]); + GetWiFiPAF()->SetWiFiPAFState(Transport::WiFiPAFBase::State::kConnected); + + // Read the ssi + GAutoPtr ssiValue(g_variant_lookup_value(discov_info, "ssi", G_VARIANT_TYPE_BYTESTRING)); + size_t ssiBufLen; + g_variant_get_fixed_array(ssiValue.get(), &ssiBufLen, sizeof(uint8_t)); + + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoWiFiPAFConnected; + PlatformMgr().PostEventOrDie(&event); + } + else + { + GetWiFiPAF()->SetWiFiPAFState(Transport::WiFiPAFBase::State::kInitialized); + if (mOnPafSubscribeError != nullptr) + { + mOnPafSubscribeError(mAppState, CHIP_ERROR_TIMEOUT); + } + } + + return; +} + +void ConnectivityManagerImpl::OnNanReceive(GVariant * obj) +{ + if (g_variant_n_children(obj) == 0) + { + return; + } + // Read the rx_info + GAutoPtr dataValueInfo(g_variant_lookup_value(obj, "nanrx_info", G_VARIANT_TYPE_BYTESTRING)); + size_t infoBufferLen; + auto infoBuffer = g_variant_get_fixed_array(dataValueInfo.get(), &infoBufferLen, sizeof(uint8_t)); + + memcpy(&mpaf_nanrx_info, infoBuffer, sizeof(struct wpa_dbus_nanrx_info)); + mpaf_info.subscribe_id = mpaf_nanrx_info.id; + mpaf_info.peer_publish_id = mpaf_nanrx_info.peer_id; + memcpy(mpaf_info.peer_addr, mpaf_nanrx_info.peer_addr, 6); + if (mpaf_nanrx_info.ssi_len == 0) + { + return; + } + // Read the rx_data + GAutoPtr dataValue(g_variant_lookup_value(obj, "ssi", G_VARIANT_TYPE_BYTESTRING)); + size_t bufferLen; + System::PacketBufferHandle buf; + auto rxbuf = g_variant_get_fixed_array(dataValue.get(), &bufferLen, sizeof(uint8_t)); + ChipLogProgress(DeviceLayer, "WiFi-PAF: wpa_supplicant: nan-rx: [len: %lu]", bufferLen); + buf = System::PacketBufferHandle::NewWithData(rxbuf, bufferLen); + + // Post an event to the Chip queue to deliver the data into the Chip stack. + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoWiFiPAFWriteReceived; + event.CHIPoWiFiPAFWriteReceived.Data = std::move(buf).UnsafeRelease(); + PlatformMgr().PostEventOrDie(&event); + + return; +} + +void ConnectivityManagerImpl::OnNanSubscribeTerminated(gint term_subscribe_id, gint reason) +{ + ChipLogProgress(Controller, "WiFi-PAF: Subscription terminated (%d, %d)", term_subscribe_id, reason); + if (mpresubscribe_id == (uint32_t) term_subscribe_id) + { + mpresubscribe_id = 0; + } + if (mpaf_info.subscribe_id == (uint32_t) term_subscribe_id) + { + mpaf_info.subscribe_id = 0; + } + return; +} + +CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFConnect(const SetupDiscriminator & connDiscriminator, void * appState, + OnConnectionCompleteFunct onSuccess, OnConnectionErrorFunct onError) +{ + ChipLogProgress(Controller, "WiFi-PAF: Try to subscribe the NAN-USD devices"); + gchar args[MAX_PAF_SUBSCRIBE_SSI_BUFLEN]; + gint subscribe_id; + snprintf(args, sizeof(args), "service_name=%s srv_proto_type=%u ttl=%u ", srv_name, NAN_SRV_PROTO_MATTER, NAM_SUBSCRIBE_PERIOD); + GAutoPtr err; + CHIP_ERROR ret; + struct PAFPublishSSI PafPublish_ssi; + + VerifyOrReturnError( + (strlen(args) + strlen(NAN_PUBLISH_SSI_TAG) + (sizeof(struct PAFPublishSSI) * 2) < MAX_PAF_PUBLISH_SSI_BUFLEN), + CHIP_ERROR_BUFFER_TOO_SMALL); + mAppState = appState; + PafPublish_ssi.DevOpCode = 0; + PafPublish_ssi.DevInfo = connDiscriminator.GetLongValue(); + if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetProductId(PafPublish_ssi.ProductId) != CHIP_NO_ERROR) + { + PafPublish_ssi.ProductId = 0; + } + if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(PafPublish_ssi.VendorId) != CHIP_NO_ERROR) + { + PafPublish_ssi.VendorId = 0; + } + strcat(args, NAN_PUBLISH_SSI_TAG); + ret = Encoding::BytesToUppercaseHexString((uint8_t *) &PafPublish_ssi, sizeof(PafPublish_ssi), &args[strlen(args)], + MAX_PAF_PUBLISH_SSI_BUFLEN - strlen(args)); + VerifyOrReturnError(ret == CHIP_NO_ERROR, ret); + ChipLogProgress(DeviceLayer, "WiFi-PAF: subscribe: [%s]", args); + + wpa_fi_w1_wpa_supplicant1_interface_call_nansubscribe_sync(mWpaSupplicant.iface, args, &subscribe_id, nullptr, + &err.GetReceiver()); + ChipLogProgress(DeviceLayer, "WiFi-PAF: subscribe_id: [%d]", subscribe_id); + mpresubscribe_id = subscribe_id; + mOnPafSubscribeComplete = onSuccess; + mOnPafSubscribeError = onError; + g_signal_connect(mWpaSupplicant.iface, "nan-discoveryresult", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success, GVariant * obj, + ConnectivityManagerImpl * self) { return self->OnDiscoveryResult(success, obj); }), + this); + + g_signal_connect(mWpaSupplicant.iface, "nan-receive", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * obj, ConnectivityManagerImpl * self) { + return self->OnNanReceive(obj); + }), + this); + + g_signal_connect( + mWpaSupplicant.iface, "nan-subscribeterminated", + G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, gint term_subscribe_id, gint reason, + ConnectivityManagerImpl * self) { return self->OnNanSubscribeTerminated(term_subscribe_id, reason); }), + this); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFCancelConnect() +{ + if (mpresubscribe_id == 0) + { + return CHIP_NO_ERROR; + } + GAutoPtr err; + gchar args[MAX_PAF_PUBLISH_SSI_BUFLEN]; + + snprintf(args, sizeof(args), "subscribe_id=%d", mpresubscribe_id); + wpa_fi_w1_wpa_supplicant1_interface_call_nancancel_subscribe_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFSend(System::PacketBufferHandle && msgBuf) +{ + ChipLogProgress(Controller, "WiFi-PAF: sending PAF Follow-up packets, (%lu)", msgBuf->DataLength()); + CHIP_ERROR ret = CHIP_NO_ERROR; + + if (msgBuf.IsNull()) + { + ChipLogError(Controller, "WiFi-PAF: Invalid Packet (%lu)", msgBuf->DataLength()); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Ensure outgoing message fits in a single contiguous packet buffer, as currently required by the + // message fragmentation and reassembly engine. + if (msgBuf->HasChainedBuffer()) + { + msgBuf->CompactHead(); + + if (msgBuf->HasChainedBuffer()) + { + ret = CHIP_ERROR_OUTBOUND_MESSAGE_TOO_BIG; + ChipLogError(Controller, "WiFi-PAF: Outbound message too big (%lu), skip temporally", msgBuf->DataLength()); + return ret; + } + } + + // ================================================================================================================ + // Send the packets + GAutoPtr err; + gchar args[MAX_PAF_TX_SSI_BUFLEN]; + + snprintf(args, sizeof(args), "handle=%u req_instance_id=%u address=%02x:%02x:%02x:%02x:%02x:%02x ssi=", mpaf_info.subscribe_id, + mpaf_info.peer_publish_id, mpaf_info.peer_addr[0], mpaf_info.peer_addr[1], mpaf_info.peer_addr[2], + mpaf_info.peer_addr[3], mpaf_info.peer_addr[4], mpaf_info.peer_addr[5]); + + ChipLogProgress(Controller, "===> %s(), (%lu, %u)", __FUNCTION__, (strlen(args) + msgBuf->DataLength()), MAX_PAF_TX_SSI_BUFLEN) + VerifyOrReturnError((strlen(args) + msgBuf->DataLength() < MAX_PAF_TX_SSI_BUFLEN), CHIP_ERROR_BUFFER_TOO_SMALL); + + ret = chip::Encoding::BytesToUppercaseHexString(msgBuf->Start(), msgBuf->DataLength(), &args[strlen(args)], + MAX_PAF_TX_SSI_BUFLEN - strlen(args)); + VerifyOrReturnError(ret == CHIP_NO_ERROR, ret); + ChipLogProgress(DeviceLayer, "WiFi-PAF: ssi: [%s]", args); + wpa_fi_w1_wpa_supplicant1_interface_call_nantransmit_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); + ChipLogProgress(Controller, "WiFi-PAF: Outbound message (%lu) done", msgBuf->DataLength()); + return ret; +} + +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * sourceObject, GAsyncResult * res) { @@ -1471,7 +1821,7 @@ CHIP_ERROR ConnectivityManagerImpl::GetConfiguredNetwork(NetworkCommissioning::N const gchar * networkPath = wpa_fi_w1_wpa_supplicant1_interface_get_current_network(mWpaSupplicant.iface); // wpa_supplicant DBus API: if network path of current network is "/", means no networks is currently selected. - if (strcmp(networkPath, "/") == 0) + if ((networkPath == nullptr) || (strcmp(networkPath, "/") == 0)) { return CHIP_ERROR_KEY_NOT_FOUND; } diff --git a/src/platform/Linux/ConnectivityManagerImpl.h b/src/platform/Linux/ConnectivityManagerImpl.h index ee5978faf6ff70..2025f228532961 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.h +++ b/src/platform/Linux/ConnectivityManagerImpl.h @@ -48,6 +48,9 @@ #include #include +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#include +#endif #endif #include @@ -137,6 +140,17 @@ class ConnectivityManagerImpl final : public ConnectivityManager, const Crypto::P256Keypair & clientIdentityKeypair, NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * connectCallback); #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + CHIP_ERROR _WiFiPAFConnect(const SetupDiscriminator & connDiscriminator, void * appState, OnConnectionCompleteFunct onSuccess, + OnConnectionErrorFunct onError); + CHIP_ERROR _WiFiPAFCancelConnect(); + void OnDiscoveryResult(gboolean success, GVariant * obj); + void OnNanReceive(GVariant * obj); + void OnNanSubscribeTerminated(gint term_subscribe_id, gint reason); + CHIP_ERROR _WiFiPAFSend(chip::System::PacketBufferHandle && msgBuf); + Transport::WiFiPAFBase * _GetWiFiPAF(); + void _SetWiFiPAF(Transport::WiFiPAFBase * pWiFiPAF); +#endif void PostNetworkConnect(); CHIP_ERROR CommitConfig(); @@ -215,6 +229,33 @@ class ConnectivityManagerImpl final : public ConnectivityManager, void _OnWpaInterfaceReady(GObject * sourceObject, GAsyncResult * res); void _OnWpaInterfaceProxyReady(GObject * sourceObject, GAsyncResult * res); void _OnWpaBssProxyReady(GObject * sourceObject, GAsyncResult * res); +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + struct wpa_dbus_discov_info + { + uint32_t subscribe_id; + uint32_t peer_publish_id; + uint8_t peer_addr[6]; + uint32_t ssi_len; + }; + uint32_t mpresubscribe_id; + struct wpa_dbus_discov_info mpaf_info; + struct wpa_dbus_nanrx_info + { + uint32_t id; + uint32_t peer_id; + uint8_t peer_addr[6]; + uint32_t ssi_len; + }; + struct wpa_dbus_nanrx_info mpaf_nanrx_info; + + OnConnectionCompleteFunct mOnPafSubscribeComplete; + OnConnectionErrorFunct mOnPafSubscribeError; + Transport::WiFiPAFBase * pmWiFiPAF; + void * mAppState; + CHIP_ERROR _SetWiFiPAFAdvertisingEnabled(WiFiPAFAdvertiseParam & args); + CHIP_ERROR _WiFiPAFPublish(WiFiPAFAdvertiseParam & args); + CHIP_ERROR _WiFiPAFCancelPublish(); +#endif bool _GetBssInfo(const gchar * bssPath, NetworkCommissioning::WiFiScanResponse & result); diff --git a/src/platform/Linux/dbus/wpa/DBusWpaInterface.xml b/src/platform/Linux/dbus/wpa/DBusWpaInterface.xml index ef86bdd3b17032..721ca0033cca09 100644 --- a/src/platform/Linux/dbus/wpa/DBusWpaInterface.xml +++ b/src/platform/Linux/dbus/wpa/DBusWpaInterface.xml @@ -56,6 +56,23 @@ + + + + + + + + + + + + + + + + + @@ -92,6 +109,21 @@ + + + + + + + + + + + + + + + diff --git a/src/platform/OpenThread/GenericThreadBorderRouterDelegate.cpp b/src/platform/OpenThread/GenericThreadBorderRouterDelegate.cpp new file mode 100644 index 00000000000000..e1efc5357520af --- /dev/null +++ b/src/platform/OpenThread/GenericThreadBorderRouterDelegate.cpp @@ -0,0 +1,224 @@ +/* + * + * 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 "GenericThreadBorderRouterDelegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace ThreadBorderRouterManagement { + +class ScopedThreadLock +{ +public: + ScopedThreadLock() { DeviceLayer::ThreadStackMgr().LockThreadStack(); } + ~ScopedThreadLock() { DeviceLayer::ThreadStackMgr().UnlockThreadStack(); } +}; + +CHIP_ERROR GenericOpenThreadBorderRouterDelegate::Init(AttributeChangeCallback * callback) +{ + mpActivateDatasetCallback = nullptr; + mpAttributeChangeCallback = callback; + ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(OnPlatformEventHandler, reinterpret_cast(this))); + // When the Thread Border Router is reboot during SetActiveDataset, we need to revert the active dateset. + RevertActiveDataset(); + return CHIP_NO_ERROR; +} + +CHIP_ERROR GenericOpenThreadBorderRouterDelegate::GetBorderAgentId(MutableByteSpan & borderAgentIdSpan) +{ + otInstance * otInst = DeviceLayer::ThreadStackMgrImpl().OTInstance(); + VerifyOrReturnError(otInst, CHIP_ERROR_INCORRECT_STATE); + otBorderAgentId borderAgentId; + if (borderAgentIdSpan.size() != sizeof(borderAgentId.mId)) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + otError otErr = OT_ERROR_NONE; + { + ScopedThreadLock threadLock; + otErr = otBorderAgentGetId(otInst, &borderAgentId); + } + if (otErr == OT_ERROR_NONE) + { + CopySpanToMutableSpan(ByteSpan(borderAgentId.mId), borderAgentIdSpan); + return CHIP_NO_ERROR; + } + return DeviceLayer::Internal::MapOpenThreadError(otErr); +} + +uint16_t GenericOpenThreadBorderRouterDelegate::GetThreadVersion() +{ + return otThreadGetVersion(); +} + +bool GenericOpenThreadBorderRouterDelegate::GetInterfaceEnabled() +{ + otInstance * otInst = DeviceLayer::ThreadStackMgrImpl().OTInstance(); + VerifyOrReturnValue(otInst, false); + ScopedThreadLock threadLock; + return otIp6IsEnabled(otInst); +} + +CHIP_ERROR GenericOpenThreadBorderRouterDelegate::GetDataset(Thread::OperationalDataset & dataset, DatasetType type) +{ + otInstance * otInst = DeviceLayer::ThreadStackMgrImpl().OTInstance(); + VerifyOrReturnError(otInst, CHIP_ERROR_INCORRECT_STATE); + + otError otErr = OT_ERROR_NONE; + otOperationalDatasetTlvs datasetTlvs; + { + ScopedThreadLock threadLock; + if (type == DatasetType::kActive) + { + otErr = otDatasetGetActiveTlvs(otInst, &datasetTlvs); + } + else + { + otErr = otDatasetGetPendingTlvs(otInst, &datasetTlvs); + } + } + if (otErr == OT_ERROR_NONE) + { + return dataset.Init(ByteSpan(datasetTlvs.mTlvs, datasetTlvs.mLength)); + } + return DeviceLayer::Internal::MapOpenThreadError(otErr); +} + +void GenericOpenThreadBorderRouterDelegate::SetActiveDataset(const Thread::OperationalDataset & activeDataset, uint32_t sequenceNum, + ActivateDatasetCallback * callback) +{ + // This function will never be invoked when there is an Active Dataset already configured. + CHIP_ERROR err = SaveActiveDatasetConfigured(false); + if (err == CHIP_NO_ERROR) + { + err = DeviceLayer::ThreadStackMgrImpl().AttachToThreadNetwork(activeDataset, nullptr); + } + if (err != CHIP_NO_ERROR) + { + callback->OnActivateDatasetComplete(sequenceNum, err); + return; + } + mSequenceNum = sequenceNum; + mpActivateDatasetCallback = callback; +} + +void GenericOpenThreadBorderRouterDelegate::OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) +{ + GenericOpenThreadBorderRouterDelegate * delegate = reinterpret_cast(arg); + if (delegate) + { + if ((event->Type == DeviceLayer::DeviceEventType::kThreadConnectivityChange) && + (event->ThreadConnectivityChange.Result == DeviceLayer::kConnectivity_Established) && + delegate->mpActivateDatasetCallback) + { + delegate->mpActivateDatasetCallback->OnActivateDatasetComplete(delegate->mSequenceNum, CHIP_NO_ERROR); + delegate->mpActivateDatasetCallback = nullptr; + } + } + if (event->Type == DeviceLayer::DeviceEventType::kThreadStateChange) + { + if (event->ThreadStateChange.OpenThread.Flags & OT_CHANGED_THREAD_NETIF_STATE) + { + DeviceLayer::SystemLayer().ScheduleLambda( + [delegate]() { delegate->mpAttributeChangeCallback->ReportAttributeChanged(Attributes::InterfaceEnabled::Id); }); + } + if (event->ThreadStateChange.OpenThread.Flags & OT_CHANGED_ACTIVE_DATASET) + { + DeviceLayer::SystemLayer().ScheduleLambda([delegate]() { + delegate->mpAttributeChangeCallback->ReportAttributeChanged(Attributes::ActiveDatasetTimestamp::Id); + }); + } + } +} + +CHIP_ERROR GenericOpenThreadBorderRouterDelegate::SaveActiveDatasetConfigured(bool configured) +{ + VerifyOrReturnError(mStorage, CHIP_ERROR_INTERNAL); + return mStorage->SyncSetKeyValue(kFailsafeActiveDatasetConfigured, &configured, sizeof(bool)); +} + +CHIP_ERROR GenericOpenThreadBorderRouterDelegate::CommitActiveDataset() +{ + return SaveActiveDatasetConfigured(DeviceLayer::ThreadStackMgrImpl().IsThreadAttached()); +} + +CHIP_ERROR GenericOpenThreadBorderRouterDelegate::RevertActiveDataset() +{ + // The FailSafe Timer is triggered and the previous command request should be handled, so reset the callback. + mpActivateDatasetCallback = nullptr; + bool activeDatasetConfigured = true; + uint16_t activeDatasetConfiguredLen = sizeof(bool); + VerifyOrReturnError(mStorage, CHIP_ERROR_INTERNAL); + mStorage->SyncGetKeyValue(kFailsafeActiveDatasetConfigured, &activeDatasetConfigured, activeDatasetConfiguredLen); + VerifyOrDie(activeDatasetConfiguredLen == sizeof(bool)); + if (!activeDatasetConfigured) + { + // The active dataset should be no configured after calling this function, so we will try to attach an empty Thread dataset + // and that will clear the one stored in the Thread stack since the SetActiveDataset operation fails and FailSafe timer is + // triggered. + Thread::OperationalDataset emptyDataset = {}; + CHIP_ERROR err = DeviceLayer::ThreadStackMgrImpl().AttachToThreadNetwork(emptyDataset, nullptr); + SaveActiveDatasetConfigured(false); + return err; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR GenericOpenThreadBorderRouterDelegate::SetPendingDataset(const Thread::OperationalDataset & pendingDataset) +{ + otInstance * otInst = DeviceLayer::ThreadStackMgrImpl().OTInstance(); + VerifyOrReturnError(otInst, CHIP_ERROR_INCORRECT_STATE); + + otOperationalDatasetTlvs datasetTlvs; + memcpy(datasetTlvs.mTlvs, pendingDataset.AsByteSpan().data(), pendingDataset.AsByteSpan().size()); + datasetTlvs.mLength = pendingDataset.AsByteSpan().size(); + { + ScopedThreadLock threadLock; + ReturnErrorCodeIf(otDatasetSetPendingTlvs(otInst, &datasetTlvs) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + } + return CHIP_NO_ERROR; +} + +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/platform/OpenThread/GenericThreadBorderRouterDelegate.h b/src/platform/OpenThread/GenericThreadBorderRouterDelegate.h new file mode 100644 index 00000000000000..079f1bd6e38edd --- /dev/null +++ b/src/platform/OpenThread/GenericThreadBorderRouterDelegate.h @@ -0,0 +1,104 @@ +/* + * + * 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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace ThreadBorderRouterManagement { + +class GenericOpenThreadBorderRouterDelegate : public Delegate +{ +public: + static constexpr char kFailsafeActiveDatasetConfigured[] = "g/fs/tbradc"; + GenericOpenThreadBorderRouterDelegate(PersistentStorageDelegate * storage) : mStorage(storage) {} + ~GenericOpenThreadBorderRouterDelegate() = default; + + CHIP_ERROR Init(AttributeChangeCallback * callback) override; + + bool GetPanChangeSupported() override { return true; } + + void GetBorderRouterName(MutableCharSpan & borderRouterName) override + { + CopyCharSpanToMutableCharSpan(CharSpan(mThreadBorderRouterName, strlen(mThreadBorderRouterName)), borderRouterName); + } + + CHIP_ERROR GetBorderAgentId(MutableByteSpan & borderAgentId) override; + + uint16_t GetThreadVersion() override; + + bool GetInterfaceEnabled() override; + + CHIP_ERROR GetDataset(Thread::OperationalDataset & dataset, DatasetType type) override; + + void SetActiveDataset(const Thread::OperationalDataset & activeDataset, uint32_t sequenceNum, + ActivateDatasetCallback * callback) override; + + CHIP_ERROR CommitActiveDataset() override; + + CHIP_ERROR RevertActiveDataset() override; + + CHIP_ERROR SetPendingDataset(const Thread::OperationalDataset & pendingDataset) override; + + static void OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg); + + void SetThreadBorderRouterName(const CharSpan & name) + { + MutableCharSpan borderRouterName(mThreadBorderRouterName); + CopyCharSpanToMutableCharSpan(name, borderRouterName); + if (mpAttributeChangeCallback) + { + DeviceLayer::SystemLayer().ScheduleLambda( + [this]() { mpAttributeChangeCallback->ReportAttributeChanged(Attributes::BorderRouterName::Id); }); + } + } + + void NotifyBorderAgentIdChanged() + { + if (mpAttributeChangeCallback) + { + // OpenThread doesn't have callback or event for BorderAgentId change, we can only change the BorderAgentId with + // otBorderAgentSetId(). Please call this function with otBorderAgentSetId(). + DeviceLayer::SystemLayer().ScheduleLambda( + [this]() { mpAttributeChangeCallback->ReportAttributeChanged(Attributes::BorderAgentID::Id); }); + } + } + +private: + CHIP_ERROR SaveActiveDatasetConfigured(bool configured); + ActivateDatasetCallback * mpActivateDatasetCallback = nullptr; + uint32_t mSequenceNum = 0; + char mThreadBorderRouterName[kBorderRouterNameMaxLength + 1]; + PersistentStorageDelegate * mStorage; + AttributeChangeCallback * mpAttributeChangeCallback = nullptr; +}; +} // namespace ThreadBorderRouterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/platform/Zephyr/SysHeapMalloc.cpp b/src/platform/Zephyr/SysHeapMalloc.cpp index d4f65b05459615..fbd7ba09fc2493 100644 --- a/src/platform/Zephyr/SysHeapMalloc.cpp +++ b/src/platform/Zephyr/SysHeapMalloc.cpp @@ -30,9 +30,6 @@ extern "C" { #include #include -// Construct name of the given function wrapped with the `--wrap=symbol` GCC option. -#define WRAP(f) __wrap_##f - using namespace chip; namespace { @@ -67,7 +64,7 @@ LockGuard::~LockGuard() } } -int initHeap() +int InitSysHeapMalloc() { sys_heap_init(&sHeap, sHeapMemory, sizeof(sHeapMemory)); return 0; @@ -77,7 +74,7 @@ int initHeap() // Initialize the heap in the POST_KERNEL phase to make sure that it is ready even before // C++ static constructors are called (which happens prior to the APPLICATION initialization phase). -SYS_INIT(initHeap, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); +SYS_INIT(InitSysHeapMalloc, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); namespace chip { namespace DeviceLayer { @@ -99,7 +96,7 @@ void * Calloc(size_t num, size_t size) return nullptr; } - void * mem = malloc(totalSize); + void * mem = Malloc(totalSize); if (mem) { @@ -156,27 +153,37 @@ void ResetMaxStats() extern "C" { -void * WRAP(malloc)(size_t size) __attribute((alias("_ZN4chip11DeviceLayer6Malloc6MallocEj"))); -void * WRAP(calloc)(size_t num, size_t size) __attribute((alias("_ZN4chip11DeviceLayer6Malloc6CallocEjj"))); -void * WRAP(realloc)(void * mem, size_t size) __attribute((alias("_ZN4chip11DeviceLayer6Malloc7ReallocEPvj"))); -void WRAP(free)(void * mem) __attribute((alias("_ZN4chip11DeviceLayer6Malloc4FreeEPv"))); +// Construct the name of a function wrapped with the `--wrap=symbol` GCC option. +#define WRAP(f) __wrap_##f + +// Define a function as an alias of another function. +#define ALIAS(f) __attribute((alias(f))) + +// Mark a function as externally visible so that it is not optimized-away even +// if LTO or whole-program optimization is enabled. +#define EXTERNALLY_VISIBLE __attribute((externally_visible)) + +EXTERNALLY_VISIBLE void * WRAP(malloc)(size_t size) ALIAS("_ZN4chip11DeviceLayer6Malloc6MallocEj"); +EXTERNALLY_VISIBLE void * WRAP(calloc)(size_t num, size_t size) ALIAS("_ZN4chip11DeviceLayer6Malloc6CallocEjj"); +EXTERNALLY_VISIBLE void * WRAP(realloc)(void * mem, size_t size) ALIAS("_ZN4chip11DeviceLayer6Malloc7ReallocEPvj"); +EXTERNALLY_VISIBLE void WRAP(free)(void * mem) ALIAS("_ZN4chip11DeviceLayer6Malloc4FreeEPv"); -void * WRAP(_malloc_r)(_reent *, size_t size) +EXTERNALLY_VISIBLE void * WRAP(_malloc_r)(_reent *, size_t size) { return WRAP(malloc)(size); } -void * WRAP(_calloc_r)(_reent *, size_t num, size_t size) +EXTERNALLY_VISIBLE void * WRAP(_calloc_r)(_reent *, size_t num, size_t size) { return WRAP(calloc)(num, size); } -void * WRAP(_realloc_r)(_reent *, void * mem, size_t size) +EXTERNALLY_VISIBLE void * WRAP(_realloc_r)(_reent *, void * mem, size_t size) { return WRAP(realloc)(mem, size); } -void WRAP(_free_r)(_reent *, void * mem) +EXTERNALLY_VISIBLE void WRAP(_free_r)(_reent *, void * mem) { WRAP(free)(mem); } diff --git a/src/platform/device.gni b/src/platform/device.gni index 332b4b3ee85716..87e2eb12e8d0d2 100644 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -23,6 +23,9 @@ declare_args() { # Substitute fake platform when building with chip_device_platform=auto. chip_fake_platform = false + + # Include wifi-paf to commission the device or not + chip_device_config_enable_wifipaf = false } if (chip_device_platform == "auto") { diff --git a/src/platform/telink/wifi/WiFiManager.cpp b/src/platform/telink/wifi/WiFiManager.cpp index 50ea5cf5682089..dfbfcfec354227 100644 --- a/src/platform/telink/wifi/WiFiManager.cpp +++ b/src/platform/telink/wifi/WiFiManager.cpp @@ -31,6 +31,7 @@ #include #include #include +#include namespace chip { namespace DeviceLayer { @@ -399,21 +400,6 @@ void WiFiManager::ScanDoneHandler(Platform::UniquePtr data, size_t leng } } -void WiFiManager::SendRouterSolicitation(System::Layer * layer, void * param) -{ - net_if_start_rs(Instance().mNetIf); - Instance().mRouterSolicitationCounter++; - if (Instance().mRouterSolicitationCounter < kRouterSolicitationMaxCount) - { - DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(kRouterSolicitationIntervalMs), SendRouterSolicitation, - nullptr); - } - else - { - Instance().mRouterSolicitationCounter = 0; - } -} - void WiFiManager::ConnectHandler(Platform::UniquePtr data, size_t length) { // Validate that input data size matches the expected one. @@ -436,10 +422,8 @@ void WiFiManager::ConnectHandler(Platform::UniquePtr data, size_t lengt } else // The connection has been established successfully. { - // Workaround needed until sending Router Solicitation after connect will be done by the driver. - DeviceLayer::SystemLayer().StartTimer( - System::Clock::Milliseconds32(chip::Crypto::GetRandU16() % kMaxInitialRouterSolicitationDelayMs), - SendRouterSolicitation, nullptr); + // Now we can send/receive data via WiFi + net_if_up(InetUtils::GetWiFiInterface()); ChipLogProgress(DeviceLayer, "Connected to WiFi network"); Instance().mWiFiState = WIFI_STATE_COMPLETED; @@ -491,6 +475,9 @@ void WiFiManager::DisconnectHandler(Platform::UniquePtr data, size_t le void WiFiManager::IPv6AddressChangeHandler(const void * data) { const in6_addr * addr = reinterpret_cast(data); + char buf[INET6_ADDRSTRLEN]; + + ChipLogProgress(DeviceLayer, "IP6 address %s", inet_ntop(AF_INET6, addr, buf, INET6_ADDRSTRLEN)); // Filter out link-local addresses that are not routable outside of a local network. if (!net_ipv6_is_ll_addr(addr)) @@ -504,6 +491,10 @@ void WiFiManager::IPv6AddressChangeHandler(const void * data) { ChipLogError(DeviceLayer, "Cannot post event: %" CHIP_ERROR_FORMAT, error.Format()); } + else + { + ChipLogProgress(DeviceLayer, "kDnssdRestartNeeded"); + } } } diff --git a/src/python_testing/TCP_Tests.py b/src/python_testing/TCP_Tests.py new file mode 100644 index 00000000000000..cc2f48c86419d9 --- /dev/null +++ b/src/python_testing/TCP_Tests.py @@ -0,0 +1,150 @@ +# +# 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. +# +# === 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 chip import ChipDeviceCtrl +from chip.interaction_model import InteractionModelError +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TCP_Tests(MatterBaseTest): + + @async_test_body + async def test_TCPConnectionEstablishment(self): + + try: + device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except TimeoutError: + asserts.fail("Unable to establish a CASE session over TCP to the device") + asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") + + @async_test_body + async def test_LargePayloadSessionEstablishment(self): + + try: + device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except TimeoutError: + asserts.fail("Unable to establish a CASE session over TCP to the device") + asserts.assert_equal(device.sessionAllowsLargePayload, True, "Session does not have associated TCP connection") + + @async_test_body + async def test_SessionInactiveAfterTCPDisconnect(self): + + try: + device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except TimeoutError: + asserts.fail("Unable to establish a CASE session over TCP to the device") + asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + + device.closeTCPConnectionWithPeer() + asserts.assert_equal(device.isActiveSession, False, + "Large Payload Session should not be active after TCP connection closure") + + @async_test_body + async def test_TCPConnectDisconnectThenConnectAgain(self): + + try: + device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except TimeoutError: + asserts.fail("Unable to establish a CASE session over TCP to the device") + asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + + device.closeTCPConnectionWithPeer() + asserts.assert_equal(device.isActiveSession, False, + "Large Payload Session should not be active after TCP connection closure") + + # Connect again + try: + device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except TimeoutError: + asserts.fail("Unable to establish a CASE session over TCP to the device") + asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") + + @async_test_body + async def test_OnOffToggleCommandOverTCPSession(self): + + try: + device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except TimeoutError: + asserts.fail("Unable to establish a CASE session over TCP to the device") + asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") + asserts.assert_equal(device.sessionAllowsLargePayload, True, "Session does not have associated TCP connection") + + commands = Clusters.Objects.OnOff.Commands + try: + await self.send_single_cmd(cmd=commands.Toggle(), endpoint=1, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except InteractionModelError: + asserts.fail("Unexpected error returned by DUT") + + @async_test_body + async def test_WildCardReadOverTCPSession(self): + + try: + device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except TimeoutError: + asserts.fail("Unable to establish a CASE session over TCP to the device") + asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") + asserts.assert_equal(device.sessionAllowsLargePayload, True, "Session does not have associated TCP connection") + + try: + await self.default_controller.Read(self.dut_node_id, [()], payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except InteractionModelError: + asserts.fail("Unexpected error returned by DUT") + + @async_test_body + async def test_UseTCPSessionIfAvailableForMRPInteraction(self): + + try: + device = await self.default_controller.GetConnectedDevice(nodeid=self.dut_node_id, allowPASE=False, timeoutMs=1000, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.LARGE_PAYLOAD) + except TimeoutError: + asserts.fail("Unable to establish a CASE session over TCP to the device") + asserts.assert_equal(device.isSessionOverTCPConnection, True, "Session does not have associated TCP connection") + asserts.assert_equal(device.isActiveSession, True, "Large Payload Session should be active over TCP connection") + asserts.assert_equal(device.sessionAllowsLargePayload, True, "Session does not have associated TCP connection") + + commands = Clusters.Objects.OnOff.Commands + try: + await self.send_single_cmd(cmd=commands.Toggle(), endpoint=1, + payloadCapability=ChipDeviceCtrl.TransportPayloadCapability.MRP_OR_TCP_PAYLOAD) + except InteractionModelError: + asserts.fail("Unexpected error returned by DUT") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_CCTRL_2_1.py b/src/python_testing/TC_CCTRL_2_1.py new file mode 100644 index 00000000000000..7822d101b16e02 --- /dev/null +++ b/src/python_testing/TC_CCTRL_2_1.py @@ -0,0 +1,44 @@ +# +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, default_matter_test_main, has_cluster, per_endpoint_test +from mobly import asserts + + +class TC_CCTRL_2_1(MatterBaseTest): + + def steps_TC_CCTRL_2_1(self) -> list[TestStep]: + steps = [TestStep(1, "Read MCORE.FS PICS code", is_commissioning=True), + TestStep(2, "Validate SupportedDeviceCategories is set accordingly based on MCORE.FS")] + return steps + + @per_endpoint_test(has_cluster(Clusters.CommissionerControl)) + async def test_TC_CCTRL_2_1(self): + self.step(1) + is_fabric_sync_pics_enabled = self.check_pics("MCORE.FS") + + self.step(2) + supported_device_categories = await self.read_single_attribute_check_success(cluster=Clusters.CommissionerControl, attribute=Clusters.CommissionerControl.Attributes.SupportedDeviceCategories) + is_fabric_sync_bit_set = bool(supported_device_categories & + Clusters.CommissionerControl.Bitmaps.SupportedDeviceCategoryBitmap.kFabricSynchronization) + asserts.assert_equal(is_fabric_sync_bit_set, is_fabric_sync_pics_enabled, + "Mismatch between PICS MCORE.FS value and what attribute indicates") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_CCTRL_2_2.py b/src/python_testing/TC_CCTRL_2_2.py new file mode 100644 index 00000000000000..edba3eec60ebfd --- /dev/null +++ b/src/python_testing/TC_CCTRL_2_2.py @@ -0,0 +1,299 @@ +# +# 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. +# + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# TODO: Skip CI for now, we don't have any way to run this. Needs setup. See test_TC_CCTRL.py + +# This test requires a TH_SERVER application. Please specify with --string-arg th_server_app_path: + +import ipaddress +import logging +import os +import random +import signal +import subprocess +import time +import uuid + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.interaction_model import InteractionModelError, Status +from matter_testing_support import (MatterBaseTest, TestStep, async_test_body, default_matter_test_main, has_cluster, + per_endpoint_test) +from mobly import asserts + + +class TC_CCTRL_2_2(MatterBaseTest): + + @async_test_body + async def setup_class(self): + super().setup_class() + # TODO: confirm whether we can open processes like this on the TH + app = self.matter_test_config.user_params.get("th_server_app_path", None) + if not app: + asserts.fail('This test requires a TH_SERVER app. Specify app path with --string-arg th_server_app_path:') + + self.kvs = f'kvs_{str(uuid.uuid4())}' + self.port = 5543 + discriminator = random.randint(0, 4095) + passcode = 20202021 + app_args = f'--secured-device-port {self.port} --discriminator {discriminator} --passcode {passcode} --KVS {self.kvs}' + cmd = f'{app} {app_args}' + # TODO: Determine if we want these logs cooked or pushed to somewhere else + logging.info("Starting TH_SERVER") + self.app_process = subprocess.Popen(cmd, bufsize=0, shell=True) + logging.info("TH_SERVER started") + time.sleep(3) + + logging.info("Commissioning from separate fabric") + + # Create a second controller on a new fabric to communicate to the server + new_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority() + new_fabric_admin = new_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=2) + paa_path = str(self.matter_test_config.paa_trust_store_path) + self.TH_server_controller = new_fabric_admin.NewController(nodeId=112233, paaTrustStorePath=paa_path) + self.server_nodeid = 1111 + await self.TH_server_controller.CommissionOnNetwork(nodeId=self.server_nodeid, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator) + logging.info("Commissioning TH_SERVER complete") + + def teardown_class(self): + logging.warning("Stopping app with SIGTERM") + self.app_process.send_signal(signal.SIGTERM.value) + self.app_process.wait() + + os.remove(self.kvs) + super().teardown_class() + + def steps_TC_CCTRL_2_2(self) -> list[TestStep]: + steps = [TestStep(1, "Get number of fabrics from TH_SERVER", is_commissioning=True), + TestStep(2, "Reading Attribute VendorId from TH_SERVER"), + TestStep(3, "Reading Attribute ProductId from TH_SERVER"), + TestStep(4, "Reading Event CommissioningRequestResult from DUT"), + TestStep(5, "Send CommissionNode command to DUT with CASE session"), + TestStep(6, "Send OpenCommissioningWindow command on Administrator Commissioning Cluster to DUT with CASE session"), + TestStep(7, "Send CommissionNode command to DUT with PASE session"), + TestStep(8, "Send RequestCommissioningApproval command to DUT with PASE session"), + TestStep(9, "Send RevokeCommissioning command on Administrator Commissioning Cluster to DUT with CASE session"), + TestStep(10, "Reading Event CommissioningRequestResult from DUT, confirm no new events"), + TestStep(11, "Send RequestCommissioningApproval command to DUT with CASE session with incorrect vendorID"), + TestStep(12, "(Manual Step) Approve Commissioning Approval Request on DUT using method indicated by the manufacturer"), + TestStep(13, "Reading Event CommissioningRequestResult from DUT, confirm one new event"), + TestStep(14, "Send CommissionNode command to DUT with CASE session, with invalid RequestId"), + TestStep(15, "Send CommissionNode command to DUT with CASE session, with invalid ResponseTimeoutSeconds too low"), + TestStep(16, "Send CommissionNode command to DUT with CASE session, with invalid ResponseTimeoutSeconds too high"), + TestStep(17, "Send CommissionNode command to DUT with CASE session, with valid parameters"), + TestStep(18, "Send OpenCommissioningWindow command on Administrator Commissioning Cluster sent to TH_SERVER"), + TestStep(19, "Wait for DUT to fail commissioning TH_SERVER, 30 seconds"), + TestStep(20, "Get number of fabrics from TH_SERVER"), + TestStep(21, "Send RevokeCommissioning command on Administrator Commissioning Cluster sent to TH_SERVER"), + TestStep(22, "Send RequestCommissioningApproval command to DUT with CASE session with correct vendorID"), + TestStep(23, "(Manual Step) Approve Commissioning Approval Request on DUT using method indicated by the manufacturer"), + TestStep(24, "Reading Event CommissioningRequestResult from DUT, confirm one new event"), + TestStep(25, "Send CommissionNode command to DUT with CASE session, with valid parameters"), + TestStep(26, "Send OpenCommissioningWindow command on Administrator Commissioning Cluster sent to TH_SERVER"), + TestStep(27, "Wait for DUT to successfully commission TH_SERVER, 30 seconds"), + TestStep(28, "Get number of fabrics from TH_SERVER, verify DUT successfully commissioned TH_SERVER")] + + return steps + + @per_endpoint_test(has_cluster(Clusters.CommissionerControl)) + async def test_TC_CCTRL_2_2(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + + self.step(1) + th_server_fabrics = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0) + self.step(2) + th_server_vid = await self.read_single_attribute_check_success(cluster=Clusters.BasicInformation, attribute=Clusters.BasicInformation.Attributes.VendorID, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0) + self.step(3) + th_server_pid = await self.read_single_attribute_check_success(cluster=Clusters.BasicInformation, attribute=Clusters.BasicInformation.Attributes.ProductID, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0) + + self.step(4) + event_path = [(self.matter_test_config.endpoint, Clusters.CommissionerControl.Events.CommissioningRequestResult, 1)] + events = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path) + + self.step(5) + ipaddr = ipaddress.IPv6Address('::1') + cmd = Clusters.CommissionerControl.Commands.CommissionNode( + requestId=1, responseTimeoutSeconds=30, ipAddress=ipaddr.packed, port=self.port) + try: + await self.send_single_cmd(cmd) + asserts.fail("Unexpected success on CommissionNode") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Failure, "Incorrect error returned") + + self.step(6) + params = await self.openCommissioningWindow(dev_ctrl=self.default_controller, node_id=self.dut_node_id) + self.step(7) + pase_nodeid = self.dut_node_id + 1 + await self.default_controller.FindOrEstablishPASESession(setupCode=params.commissioningParameters.setupQRCode, nodeid=pase_nodeid) + try: + await self.send_single_cmd(cmd=cmd, node_id=pase_nodeid) + asserts.fail("Unexpected success on CommissionNode") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.UnsupportedAccess, "Incorrect error returned") + + self.step(8) + good_request_id = 0x1234567887654321 + cmd = Clusters.CommissionerControl.Commands.RequestCommissioningApproval( + requestId=good_request_id, vendorId=th_server_vid, productId=th_server_pid) + try: + await self.send_single_cmd(cmd=cmd, node_id=pase_nodeid) + asserts.fail("Unexpected success on RequestCommissioningApproval over PASE") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.UnsupportedAccess, "Incorrect error returned") + + self.step(9) + cmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning() + # If no exception is raised, this is success + await self.send_single_cmd(cmd) + + self.step(10) + if not events: + new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path) + else: + event_nums = [e.Header.EventNumber for e in events] + new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path, eventNumberFilter=max(event_nums)+1) + asserts.assert_equal(new_event, [], "Unexpected event") + + self.step(11) + # There should be nothing on the TH that uses VID 0x6006 as this is a real vendor ID. + not_th_server_vid = 0x6006 + asserts.assert_not_equal(not_th_server_vid, th_server_vid, "Test implementation assumption incorrect") + cmd = Clusters.CommissionerControl.Commands.RequestCommissioningApproval( + requestId=good_request_id, vendorId=not_th_server_vid, productId=th_server_pid) + # If no exception is raised, this is success + await self.send_single_cmd(cmd) + + self.step(12) + if not self.is_ci: + self.wait_for_use_input("Approve Commissioning approval request using manufacturer specified mechanism") + + self.step(13) + if not events: + new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path) + else: + event_nums = [e.Header.EventNumber for e in events] + new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path, eventNumberFilter=max(event_nums)+1) + asserts.assert_equal(len(new_event), 1, "Unexpected event list len") + asserts.assert_equal(new_event[0].Data.statusCode, 0, "Unexpected status code") + asserts.assert_equal(new_event[0].Data.clientNodeId, + self.matter_test_config.controller_node_id, "Unexpected client node id") + asserts.assert_equal(new_event[0].Data.requestId, good_request_id, "Unexpected request ID") + + self.step(14) + bad_request_id = 0x1234567887654322 + cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=bad_request_id, responseTimeoutSeconds=30) + try: + await self.send_single_cmd(cmd=cmd) + asserts.fail("Unexpected success on CommissionNode") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Failure, "Incorrect error returned") + + self.step(15) + cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=good_request_id, responseTimeoutSeconds=29) + try: + await self.send_single_cmd(cmd=cmd) + asserts.fail("Unexpected success on CommissionNode") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Failure, "Incorrect error returned") + + self.step(16) + cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=good_request_id, responseTimeoutSeconds=121) + try: + await self.send_single_cmd(cmd=cmd) + asserts.fail("Unexpected success on CommissionNode") + except InteractionModelError as e: + asserts.assert_equal(e.status, Status.Failure, "Incorrect error returned") + + self.step(17) + cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=good_request_id, responseTimeoutSeconds=30) + resp: Clusters.CommissionerControl.Commands.ReverseOpenCommissioningWindow = await self.send_single_cmd(cmd) + asserts.assert_equal(type(resp), Clusters.CommissionerControl.Commands.ReverseOpenCommissioningWindow, + "Incorrect response type") + + self.step(18) + # min commissioning timeout is 3*60 seconds, so use that even though the command said 30. + cmd = Clusters.AdministratorCommissioning.Commands.OpenCommissioningWindow(commissioningTimeout=3*60, + PAKEPasscodeVerifier=resp.PAKEPasscodeVerifier, + discriminator=resp.discriminator, + iterations=resp.iterations, salt=resp.salt) + await self.send_single_cmd(cmd, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, timedRequestTimeoutMs=5000) + + self.step(19) + logging.info("Test now waits for 30 seconds") + if not self.is_ci: + time.sleep(30) + + self.step(20) + print(f'server node id {self.server_nodeid}') + th_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0) + asserts.assert_equal(len(th_server_fabrics), len(th_server_fabrics_new), "Unexpected number of fabrics on TH_SERVER") + + self.step(21) + cmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning() + await self.send_single_cmd(cmd, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, timedRequestTimeoutMs=5000, endpoint=0) + + self.step(22) + good_request_id = 0x1234567812345678 + cmd = Clusters.CommissionerControl.Commands.RequestCommissioningApproval( + requestId=good_request_id, vendorId=th_server_vid, productId=th_server_pid, label="Test Ecosystem") + await self.send_single_cmd(cmd) + + self.step(23) + if not self.is_ci: + self.wait_for_use_input("Approve Commissioning approval request using manufacturer specified mechanism") + + self.step(24) + events = new_event + event_nums = [e.Header.EventNumber for e in events] + new_event = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path, eventNumberFilter=max(event_nums)+1) + asserts.assert_equal(len(new_event), 1, "Unexpected event list len") + asserts.assert_equal(new_event[0].Data.statusCode, 0, "Unexpected status code") + asserts.assert_equal(new_event[0].Data.clientNodeId, + self.matter_test_config.controller_node_id, "Unexpected client node id") + asserts.assert_equal(new_event[0].Data.requestId, good_request_id, "Unexpected request ID") + + self.step(25) + cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=good_request_id, responseTimeoutSeconds=30) + resp = await self.send_single_cmd(cmd) + asserts.assert_equal(type(resp), Clusters.CommissionerControl.Commands.ReverseOpenCommissioningWindow, + "Incorrect response type") + + self.step(26) + # min commissioning timeout is 3*60 seconds, so use that even though the command said 30. + cmd = Clusters.AdministratorCommissioning.Commands.OpenCommissioningWindow(commissioningTimeout=3*60, + PAKEPasscodeVerifier=resp.PAKEPasscodeVerifier, + discriminator=resp.discriminator, + iterations=resp.iterations, salt=resp.salt) + await self.send_single_cmd(cmd, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, timedRequestTimeoutMs=5000) + + self.step(27) + if not self.is_ci: + time.sleep(30) + + self.step(28) + th_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0) + # TODO: this should be mocked too. + if not self.is_ci: + asserts.assert_equal(len(th_server_fabrics) + 1, len(th_server_fabrics_new), + "Unexpected number of fabrics on TH_SERVER") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_CC_2_2.py b/src/python_testing/TC_CC_2_2.py new file mode 100644 index 00000000000000..66ed2a8f563777 --- /dev/null +++ b/src/python_testing/TC_CC_2_2.py @@ -0,0 +1,290 @@ +# +# 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. +# + +# 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 +import time + +import chip.clusters as Clusters +from chip.clusters import ClusterObjects as ClusterObjects +from matter_testing_support import (ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, default_matter_test_main, + has_cluster, per_endpoint_test) +from mobly import asserts +from test_plan_support import commission_if_required, if_feature_supported, read_attribute, verify_success + + +class TC_CC_2_3(MatterBaseTest): + + # Test includes several long waits, adjust timeout to accommodate. + @property + def default_timeout(self) -> int: + return 180 + + def steps_TC_CC_2_2(self): + THcommand = "Test Harness sends the" + + def store_values(attr: str) -> str: + return f"TH stores the reported values of _{attr}_ in all incoming reports for _{attr}_ attribute, that contains data in _reportedCurrentHueValuesList_, over a period of 20 seconds." + + def verify_entry_count(attr: str) -> str: + return f'TH verifies that _reportedCurrentHueValuesList_ does not contain more than 10 entries for _{attr}_' + + def entry_count_verification() -> str: + return '_reportedCurrentHueValuesList_ has 10 or less entries in the list' + + return [TestStep(1, commission_if_required(), is_commissioning=True), + TestStep(2, read_attribute('FeatureMap')), + TestStep(3, read_attribute('AttributeList')), + TestStep(4, read_attribute('ServerList', 'Descriptor')), + TestStep( + 5, f"If OnOff cluster is present in _ServerList_, {THcommand} On command on OnOff cluster", verify_success()), + TestStep( + 6, f'{if_feature_supported("HS")}, {THcommand} MoveHue with _MoveMode_ field set to Down, _Rate_ field set to 255 and remaining fields set to 0', verify_success()), + TestStep(7, f'{if_feature_supported("HS")}, {THcommand} MoveSaturation with _MoveMode_ field set to Down, _Rate_ field set to 255 and remaining fields set to 0', verify_success()), + TestStep(8, 'Set up a subscription wildcard subscription for the Color Control Cluster, with MinIntervalFloor set to 0, MaxIntervalCeiling set to 30 and KeepSubscriptions set to false', + 'Subscription successfully established'), + TestStep(9, 'If the HS feature is not supported, skip step 10 to 15'), + TestStep(10, f'{THcommand} MoveToHue with _Hue_ field set to 254, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0', verify_success()), + TestStep(11, store_values('CurrentHue')), + TestStep(12, verify_entry_count('CurrentHue'), entry_count_verification()), + TestStep( + 13, f"{THcommand} MoveToSaturation with _Saturation_ field set to 254, _TransitionTime_ field set to 100 and remaining fields set to 0"), + TestStep(14, store_values('CurrentSaturation')), + TestStep(15, verify_entry_count('CurrentSaturation'), entry_count_verification()), + TestStep(16, 'If XY feature is not supported, skip steps 17-21'), + TestStep( + "17a", f"{THcommand} MoveToColor with _ColorX_ field set to 32768, _ColorY_ set to 19660, _TransitionTime_ field set to 0 and remaining fields set to 0"), + TestStep( + "17b", f"{THcommand} MoveToColor with _ColorX_ field set to 13107, _ColorY_ set to 13107, _TransitionTime_ field set to 100 and remaining fields set to 0"), + TestStep(18, store_values('CurrentX')), + TestStep(19, store_values('CurrentY')), + TestStep(20, verify_entry_count('CurrentX'), entry_count_verification()), + TestStep(21, verify_entry_count('CurrentY'), entry_count_verification()), + TestStep(22, "If the EHUE feature is not supported, skip steps 23 to 25"), + TestStep(23, f"{THcommand} EnhancedMoveToHue with _EnhancedHue_ field set to 0, _TransitionTime_ field set to 100, _Direction_ field set to Shortest and remaining fields set to 0", verify_success()), + TestStep(24, store_values('EnhancedCurrentHue')), + TestStep(25, verify_entry_count('EnhancedCurrentHue'), entry_count_verification()), + TestStep(26, "If the RemainingTime attribute is not supported, skip the remaining steps and end test case"), + TestStep(27, store_values('RemainingTime')), + TestStep( + 29, f"If the XY feature is supported and the HS feature is not supported, {THcommand} MoveToColor with _ColorX_ field set to 32768, _ColorY_ set to 19660, _TransitionTime_ field set to 100 and remaining fields set to 0", verify_success()), + TestStep(30, "Wait for 5 seconds"), + TestStep( + 32, f"If the XY feature is supported and the HS feature is not supported, {THcommand} MoveToColor with _ColorX_ field set to 13107, _ColorY_ set to 13107, _TransitionTime_ field set to 150 and remaining fields set to 0", verify_success()), + TestStep(33, "Wait for 20 seconds"), + TestStep(34, "TH verifies _reportedRemainingTimeValuesList_ contains three entries", + "_reportedRemainingTimeValuesList_ has 3 entries in the list"), + TestStep(35, "TH verifies the first entry in _reportedRemainingTimeValuesList_ is 100", + "The first entry in _reportedRemainingTimeValuesList_ is equal to 100"), + TestStep(36, "TH verifies the second entry in _reportedRemainingTimeValuesList_ is approximately 150", + "The second entry in _reportedRemainingTimeValuesList_ is approximately equal to 150"), + TestStep(37, "TH verifies the third entry in _reportedRemainingTimeValuesList_ is 0", + "The third entry in _reportedRemainingTimeValuesList_ is equal to 0") + ] + + @per_endpoint_test(has_cluster(Clusters.ColorControl)) + async def test_TC_CC_2_2(self): + gather_time = 20 + + # commissioning - already done + self.step(1) + + cc = Clusters.ColorControl + + self.step(2) + feature_map = await self.read_single_attribute_check_success(cluster=cc, attribute=cc.Attributes.FeatureMap) + supports_hs = (feature_map & cc.Bitmaps.Feature.kHueAndSaturation) != 0 + supports_xy = (feature_map & cc.Bitmaps.Feature.kXy) != 0 + supports_ehue = (feature_map & cc.Bitmaps.Feature.kEnhancedHue) != 0 + + self.step(3) + attribute_list = await self.read_single_attribute_check_success(cluster=cc, attribute=cc.Attributes.AttributeList) + + self.step(4) + server_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.ServerList) + + self.step(5) + if Clusters.OnOff.id in server_list: + cmd = Clusters.OnOff.Commands.On() + await self.send_single_cmd(cmd) + else: + self.mark_current_step_skipped() + + self.step(6) + if supports_hs: + cmd = cc.Commands.MoveHue(moveMode=cc.Enums.HueMoveMode.kDown, rate=225) + await self.send_single_cmd(cmd) + else: + self.mark_current_step_skipped() + + self.step(7) + if supports_hs: + cmd = cc.Commands.MoveSaturation(moveMode=cc.Enums.SaturationMoveMode.kDown, rate=225) + await self.send_single_cmd(cmd) + else: + self.mark_current_step_skipped() + + self.step(8) + sub_handler = ClusterAttributeChangeAccumulator(cc) + await sub_handler.start(self.default_controller, self.dut_node_id, self.matter_test_config.endpoint) + + def accumulate_reports(): + sub_handler.reset() + logging.info(f"Test will now wait {gather_time} seconds to accumulate reports") + time.sleep(gather_time) + + def check_report_counts(attr: ClusterObjects.ClusterAttributeDescriptor): + count = sub_handler.attribute_report_counts[attr] + # TODO: should be 12 - see issue #34646 + # asserts.assert_less_equal(count, 12, "More than 12 reports received") + asserts.assert_less_equal(count, gather_time, f"More than {gather_time} reports received") + + self.step(9) + if not supports_hs: + self.skip_step(10) + self.skip_step(11) + self.skip_step(12) + self.skip_step(13) + self.skip_step(14) + self.skip_step(15) + else: + self.step(10) + cmd = cc.Commands.MoveToHue(hue=254, transitionTime=100, direction=cc.Enums.HueDirection.kShortestDistance) + await self.send_single_cmd(cmd) + + self.step(11) + accumulate_reports() + + self.step(12) + check_report_counts(cc.Attributes.CurrentHue) + + self.step(13) + cmd = cc.Commands.MoveToSaturation(saturation=254, transitionTime=100) + await self.send_single_cmd(cmd) + + self.step(14) + accumulate_reports() + + self.step(15) + check_report_counts(cc.Attributes.CurrentSaturation) + + self.step(16) + if not supports_xy: + self.skip_step(17) + self.skip_step(18) + self.skip_step(19) + self.skip_step(20) + self.skip_step(21) + else: + self.step("17a") + cmd = cc.Commands.MoveToColor(colorX=32768, colorY=19660, transitionTime=0) + await self.send_single_cmd(cmd) + + self.step("17b") + cmd = cc.Commands.MoveToColor(colorX=13107, colorY=13107, transitionTime=0) + await self.send_single_cmd(cmd) + + self.step(18) + accumulate_reports() + + self.step(19) + # reports for x and y are both accumulated in a dict - done above + + self.step(20) + check_report_counts(cc.Attributes.CurrentX) + + self.step(21) + check_report_counts(cc.Attributes.CurrentY) + + self.step(22) + if not supports_ehue: + self.skip_step(23) + self.skip_step(24) + self.skip_step(25) + else: + self.step(23) + cmd = cc.Commands.EnhancedMoveToHue(enhancedHue=0, transitionTime=100, + direction=cc.Enums.HueDirection.kShortestDistance) + await self.send_single_cmd(cmd) + + self.step(24) + accumulate_reports() + + self.step(25) + check_report_counts(cc.Attributes.EnhancedCurrentHue) + + self.step(26) + if cc.Attributes.RemainingTime.attribute_id not in attribute_list: + self.skip_all_remaining_steps(27) + return + + self.step(27) + accumulate_reports() + + self.step(29) + # TODO: If this is mandatory, we should just omit this + if supports_xy: + cmd = cc.Commands.MoveToColor(colorX=32768, colorY=19660, transitionTime=100) + await self.send_single_cmd(cmd) + else: + self.mark_current_step_skipped() + + self.step(30) + logging.info("Test will now wait for 5 seconds") + time.sleep(5) + + self.step(32) + if supports_xy: + cmd = cc.Commands.MoveToColor(colorX=13107, colorY=13107, transitionTime=150) + await self.send_single_cmd(cmd) + else: + self.mark_current_step_skipped() + + self.step(33) + logging.info("Test will now wait for 20 seconds") + time.sleep(20) + + self.step(34) + # TODO: Re-enable checks 34, 36 when #34643 is addressed + logging.info(f'received reports: {sub_handler.attribute_reports[cc.Attributes.RemainingTime]}') + # count = sub_handler.attribute_report_counts[cc.Attributes.RemainingTime] + # asserts.assert_equal(count, 3, "Unexpected number of reports received") + + self.step(35) + asserts.assert_equal(sub_handler.attribute_reports[cc.Attributes.RemainingTime][0].value, 100, "Unexpected first report") + + self.step(36) + # asserts.assert_almost_equal( + # sub_handler.attribute_reports[cc.Attributes.RemainingTime][1].value, 0, delta=10, msg="Unexpected second report") + + self.step(37) + asserts.assert_equal(sub_handler.attribute_reports[cc.Attributes.RemainingTime][-1].value, 0, "Unexpected last report") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index c64a3470d19ed1..2a0fe309f20a4c 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -76,8 +76,7 @@ def record_warning(location, problem): ignore_attributes: dict[int, list[int]] = {} if ignore_in_progress: # This is a manually curated list of attributes that are in-progress in the SDK, but have landed in the spec - in_progress_attributes = {Clusters.BasicInformation.id: [0x15, 0x016], - Clusters.PowerSource.id: [0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A]} + in_progress_attributes = {Clusters.ThreadNetworkDiagnostics.id: [0x3F, 0x40]} ignore_attributes.update(in_progress_attributes) if is_ci: @@ -337,7 +336,9 @@ async def setup_class(self): await self.setup_class_helper() def test_TC_IDM_10_2(self): - ignore_in_progress = self.user_params.get("ignore_in_progress", False) + # TODO: Turn this off after TE2 + # https://github.com/project-chip/connectedhomeip/issues/34615 + ignore_in_progress = self.user_params.get("ignore_in_progress", True) is_ci = self.check_pics('PICS_SDK_CI_ONLY') success, problems = self.check_conformance(ignore_in_progress, is_ci) self.problems.extend(problems) diff --git a/src/python_testing/TC_ECOINFO_2_1.py b/src/python_testing/TC_ECOINFO_2_1.py new file mode 100644 index 00000000000000..ea9ee43b7f0569 --- /dev/null +++ b/src/python_testing/TC_ECOINFO_2_1.py @@ -0,0 +1,190 @@ +# +# 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 chip.clusters as Clusters +from chip.clusters.Types import NullValue +from chip.interaction_model import Status +from chip.tlv import uint +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + + +class TC_ECOINFO_2_1(MatterBaseTest): + + def _validate_device_directory(self, is_removed_on_null, device_directory): + num_of_devices = len(device_directory) + if is_removed_on_null: + asserts.assert_less_equal(num_of_devices, 256, "Too many device entries") + for device in device_directory: + # TODO do fabric index check first + if device.deviceName is not None: + asserts.assert_true(type_matches(device.deviceName, str), "DeviceName should be a string") + asserts.assert_less_equal(len(device.deviceName), 64, "DeviceName should be <= 64") + asserts.assert_true(type_matches(device.deviceNameLastEdit, uint), "DeviceNameLastEdit should be a uint") + asserts.assert_greater(device.deviceNameLastEdit, 0, "DeviceNameLastEdit must be greater than 0") + else: + asserts.assert_true(device.deviceNameLastEdit is None, + "DeviceNameLastEdit should not be provided when there is no DeviceName") + + asserts.assert_true(type_matches(device.bridgedEndpoint, uint), "BridgedEndpoint should be a uint") + asserts.assert_greater_equal(device.bridgedEndpoint, 0, "BridgedEndpoint >= 0") + asserts.assert_less_equal(device.bridgedEndpoint, 0xffff_ffff, + "BridgedEndpoint less than or equal to Invalid Endpoint value") + + asserts.assert_true(type_matches(device.originalEndpoint, uint), "OriginalEndpoint should be a uint") + asserts.assert_greater_equal(device.originalEndpoint, 0, "OriginalEndpoint >= 0") + asserts.assert_less(device.originalEndpoint, 0xffff_ffff, + "OriginalEndpoint less than or equal to Invalid Endpoint value") + + asserts.assert_true(type_matches(device.deviceTypes, list), "DeviceTypes should be a list") + asserts.assert_greater_equal(len(device.deviceTypes), 1, "DeviceTypes list must contains at least one entry") + for device_type in device.deviceTypes: + asserts.assert_true(type_matches(device_type.deviceType, uint), "DeviceType should be a uint") + # TODO what other validation can we do here to device_type.deviceType + asserts.assert_true(type_matches(device_type.revision, uint), "device type's revision should be a uint") + asserts.assert_greater_equal(device_type.revision, 1, "device type's revision must >= 1") + + asserts.assert_true(type_matches(device.uniqueLocationIDs, list), "UniqueLocationIds should be a list") + num_of_unique_location_ids = len(device.uniqueLocationIDs) + asserts.assert_less_equal(num_of_unique_location_ids, 64, "UniqueLocationIds list should be <= 64") + for location_id in device.uniqueLocationIDs: + asserts.assert_true(type_matches(location_id, str), "UniqueLocationId should be a string") + location_id_string_length = len(location_id) + asserts.assert_greater_equal(location_id_string_length, 1, + "UniqueLocationId must contain at least one character") + asserts.assert_less_equal(location_id_string_length, 64, "UniqueLocationId should be <= 64") + + asserts.assert_true(type_matches(device.uniqueLocationIDsLastEdit, uint), + "UniqueLocationIdsLastEdit should be a uint") + if num_of_unique_location_ids: + asserts.assert_greater(device.uniqueLocationIDsLastEdit, 0, "UniqueLocationIdsLastEdit must be non-zero") + else: + asserts.assert_equal(num_of_devices, 0, "Device was removed, there should be no devices in DeviceDirectory") + + def _validate_location_directory(self, is_removed_on_null, location_directory): + num_of_locations = len(location_directory) + if is_removed_on_null: + asserts.assert_less_equal(num_of_locations, 64, "Too many location entries") + for location in location_directory: + asserts.assert_true(type_matches(location.uniqueLocationID, str), "UniqueLocationId should be a string") + location_id_string_length = len(location.uniqueLocationID) + asserts.assert_greater_equal(location_id_string_length, 1, + "UniqueLocationId must contain at least one character") + asserts.assert_less_equal(location_id_string_length, 64, "UniqueLocationId should be <= 64") + + asserts.assert_true(type_matches(location.locationDescriptor.locationName, str), + "LocationName should be a string") + asserts.assert_less_equal(len(location.locationDescriptor.locationName), 64, "LocationName should be <= 64") + + if location.locationDescriptor.floorNumber is not NullValue: + asserts.assert_true(type_matches(location.locationDescriptor.floorNumber, int), + "FloorNumber should be an int") + # TODO check in range of int16. + + if location.locationDescriptor.areaType is not NullValue: + # TODO check areaType is valid. + pass + + asserts.assert_true(type_matches(location.locationDescriptorLastEdit, uint), + "UniqueLocationIdsLastEdit should be a uint") + asserts.assert_greater(location.locationDescriptorLastEdit, 0, "LocationDescriptorLastEdit must be non-zero") + + else: + asserts.assert_equal(num_of_locations, 0, "Device was removed, there should be no location in LocationDirectory") + + def steps_TC_ECOINFO_2_1(self) -> list[TestStep]: + steps = [TestStep(1, "Identify endpoints with Ecosystem Information Cluster", is_commissioning=True), + TestStep(2, "Reading RemovedOn Attribute"), + TestStep(3, "Reading DeviceDirectory Attribute"), + TestStep(4, "Reading LocationDirectory Attribute"), + TestStep(5, "Try Writing to RemovedOn Attribute"), + TestStep(6, "Try Writing to DeviceDirectory Attribute"), + TestStep(7, "Try Writing to LocationDirectory Attribute"), + TestStep(8, "Repeating steps 2 to 7 for each endpoint identified in step 1")] + return steps + + @async_test_body + async def test_TC_ECOINFO_2_1(self): + dev_ctrl = self.default_controller + dut_node_id = self.dut_node_id + + self.print_step(0, "Commissioning, already done") + + self.step(1) + endpoint_wild_card_read = await dev_ctrl.ReadAttribute(dut_node_id, [(Clusters.EcosystemInformation.Attributes.ClusterRevision)]) + list_of_endpoints = list(endpoint_wild_card_read.keys()) + + for idx, cluster_endpoint in enumerate(list_of_endpoints): + if idx == 0: + self.step(2) + removed_on = await self.read_single_attribute( + dev_ctrl, + dut_node_id, + endpoint=cluster_endpoint, + attribute=Clusters.EcosystemInformation.Attributes.RemovedOn) + + is_removed_on_null = removed_on is NullValue + if not is_removed_on_null: + asserts.assert_true(type_matches(removed_on, uint)) + asserts.assert_greater(removed_on, 0, "RemovedOn must be greater than 0", "RemovedOn should be a uint") + + if idx == 0: + self.step(3) + device_directory = await self.read_single_attribute( + dev_ctrl, + dut_node_id, + endpoint=cluster_endpoint, + attribute=Clusters.EcosystemInformation.Attributes.DeviceDirectory, + fabricFiltered=False) + + self._validate_device_directory(is_removed_on_null, device_directory) + + if idx == 0: + self.step(4) + location_directory = await self.read_single_attribute( + dev_ctrl, + dut_node_id, + endpoint=cluster_endpoint, + attribute=Clusters.EcosystemInformation.Attributes.LocationDirectory, + fabricFiltered=False) + + self._validate_location_directory(is_removed_on_null, location_directory) + + if idx == 0: + self.step(5) + result = await dev_ctrl.WriteAttribute(dut_node_id, [(cluster_endpoint, Clusters.EcosystemInformation.Attributes.RemovedOn(2))]) + asserts.assert_equal(len(result), 1, "Expecting only one result from trying to write to RemovedOn Attribute") + asserts.assert_equal(result[0].Status, Status.UnsupportedWrite, "Expecting Status of UnsupportedWrite") + + if idx == 0: + self.step(6) + result = await dev_ctrl.WriteAttribute(dut_node_id, [(cluster_endpoint, Clusters.EcosystemInformation.Attributes.DeviceDirectory([]))]) + asserts.assert_equal(len(result), 1, "Expecting only one result from trying to write to DeviceDirectory Attribute") + asserts.assert_equal(result[0].Status, Status.UnsupportedWrite, "Expecting Status of UnsupportedWrite") + + if idx == 0: + self.step(7) + result = await dev_ctrl.WriteAttribute(dut_node_id, [(cluster_endpoint, Clusters.EcosystemInformation.Attributes.DeviceDirectory([]))]) + asserts.assert_equal(len(result), 1, "Expecting only one result from trying to write to LocationDirectory Attribute") + asserts.assert_equal(result[0].Status, Status.UnsupportedWrite, "Expecting Status of UnsupportedWrite") + + if idx == 0: + self.step(8) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_ECOINFO_2_2.py b/src/python_testing/TC_ECOINFO_2_2.py new file mode 100644 index 00000000000000..c8bb7de4004d56 --- /dev/null +++ b/src/python_testing/TC_ECOINFO_2_2.py @@ -0,0 +1,123 @@ +# +# 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 chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +_DEVICE_TYPE_AGGREGGATOR = 0x000E + + +class TC_ECOINFO_2_2(MatterBaseTest): + + def steps_TC_ECOINFO_2_2(self) -> list[TestStep]: + steps = [TestStep(1, "Prepare", is_commissioning=True), + TestStep("1a", "Read root endpoint's PartsList"), + TestStep("1b", "For each endpoint in 1a read DeviceType list confirming aggregator endpoint exists"), + TestStep(2, "Add a bridged device"), + TestStep("2a", "(Manual Step) Add a bridged device using method indicated by the manufacturer"), + TestStep("2b", "Read root endpoint's PartsList, validate exactly one endpoint added"), + TestStep("2c", "On newly added endpoint detected in 2b read RemovedOn Ecosystem Information Attribute and validate"), + TestStep(3, "Remove bridged device"), + TestStep("3a", "(Manual Step) Removed bridged device added in step 2a using method indicated by the manufacturer"), + TestStep("3b", "On newly added endpoint detected in 2b read RemovedOn Ecosystem Information Attribute and validate"), + TestStep("3c", "On newly added endpoint detected in 2b read DeviceDirectory Ecosystem Information Attribute and validate"), + TestStep("3d", "On newly added endpoint detected in 2b read LocationDirectory Ecosystem Information Attribute and validate")] + + return steps + + @async_test_body + async def test_TC_ECOINFO_2_2(self): + dev_ctrl = self.default_controller + dut_node_id = self.dut_node_id + + self.print_step(0, "Commissioning, already done") + self.step(1) + self.step("1a") + root_node_endpoint = 0 + root_part_list = await dev_ctrl.ReadAttribute(dut_node_id, [(root_node_endpoint, Clusters.Descriptor.Attributes.PartsList)]) + + self.step("1b") + set_of_endpoints_step_1 = set(root_part_list[root_node_endpoint] + [Clusters.Descriptor][Clusters.Descriptor.Attributes.PartsList]) + list_of_aggregator_endpoints = [] + for endpoint in set_of_endpoints_step_1: + device_type_list_read = await dev_ctrl.ReadAttribute(dut_node_id, [(endpoint, Clusters.Descriptor.Attributes.DeviceTypeList)]) + device_type_list = device_type_list_read[endpoint][Clusters.Descriptor][Clusters.Descriptor.Attributes.DeviceTypeList] + for device_type in device_type_list: + if device_type.deviceType == _DEVICE_TYPE_AGGREGGATOR: + list_of_aggregator_endpoints.append(endpoint) + + asserts.assert_greater_equal(len(list_of_aggregator_endpoints), 1, "Did not find any Aggregator device types") + + self.step(2) + self.step("2a") + self.wait_for_user_input(prompt_msg="Add a bridged device using method indicated by the manufacturer") + + self.step("2b") + root_part_list_step_2 = await dev_ctrl.ReadAttribute(dut_node_id, [(root_node_endpoint, Clusters.Descriptor.Attributes.PartsList)]) + set_of_endpoints_step_2 = set( + root_part_list_step_2[root_node_endpoint][Clusters.Descriptor][Clusters.Descriptor.Attributes.PartsList]) + + asserts.assert_true(set_of_endpoints_step_2.issuperset(set_of_endpoints_step_1), "Expected only new endpoints to be added") + unique_endpoints_set = set_of_endpoints_step_2 - set_of_endpoints_step_1 + asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint") + + self.step("2c") + newly_added_endpoint = list(unique_endpoints_set)[0] + removed_on = await self.read_single_attribute( + dev_ctrl, + dut_node_id, + endpoint=newly_added_endpoint, + attribute=Clusters.EcosystemInformation.Attributes.RemovedOn) + + asserts.assert_true(removed_on is NullValue, "RemovedOn is expected to be null for a newly added device") + + self.step(3) + self.step("3a") + self.wait_for_user_input(prompt_msg="Removed bridged device added in step 2a using method indicated by the manufacturer") + + self.step("3b") + removed_on = await self.read_single_attribute( + dev_ctrl, + dut_node_id, + endpoint=newly_added_endpoint, + attribute=Clusters.EcosystemInformation.Attributes.RemovedOn) + asserts.assert_true(removed_on is not NullValue, "RemovedOn is expected to have a value") + + self.step("3c") + device_directory = await self.read_single_attribute( + dev_ctrl, + dut_node_id, + endpoint=newly_added_endpoint, + attribute=Clusters.EcosystemInformation.Attributes.DeviceDirectory, + fabricFiltered=False) + asserts.assert_equal(len(device_directory), 0, "Expected device directory to be empty") + + self.step("3d") + location_directory = await self.read_single_attribute( + dev_ctrl, + dut_node_id, + endpoint=newly_added_endpoint, + attribute=Clusters.EcosystemInformation.Attributes.LocationDirectory, + fabricFiltered=False) + asserts.assert_equal(len(location_directory), 0, "Expected location directory to be empty") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_EWATERHTRBase.py b/src/python_testing/TC_EWATERHTRBase.py new file mode 100644 index 00000000000000..0bf42a7eb4d0a0 --- /dev/null +++ b/src/python_testing/TC_EWATERHTRBase.py @@ -0,0 +1,94 @@ +# +# 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 logging +import typing + +import chip.clusters as Clusters +from chip.interaction_model import InteractionModelError, Status +from mobly import asserts + +logger = logging.getLogger(__name__) + + +class EWATERHTRBase: + + async def read_whm_attribute_expect_success(self, endpoint: int = None, attribute: str = ""): + cluster = Clusters.Objects.WaterHeaterManagement + full_attr = getattr(cluster.Attributes, attribute) + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=full_attr) + + async def check_whm_attribute(self, attribute, expected_value, endpoint: int = None): + value = await self.read_whm_attribute_expect_success(endpoint=endpoint, attribute=attribute) + asserts.assert_equal(value, expected_value, + f"Unexpected '{attribute}' value - expected {expected_value}, was {value}") + + async def send_boost_command(self, duration: int, one_shot: typing.Optional[bool] = None, emergency_boost: typing.Optional[bool] = None, + temporary_setpoint: typing.Optional[int] = None, target_percentage: typing.Optional[int] = None, target_reheat: typing.Optional[int] = None, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.WaterHeaterManagement.Commands.Boost( + duration=duration, + oneShot=one_shot, + emergencyBoost=emergency_boost, + temporarySetpoint=temporary_setpoint, + targetPercentage=target_percentage, + targetReheat=target_reheat), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_cancel_boost_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.WaterHeaterManagement.Commands.CancelBoost(), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_test_event_trigger_basic_installation_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000000) + + async def send_test_event_trigger_basic_installation_test_event_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000001) + + async def send_test_event_trigger_water_temperature20C_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000002) + + async def send_test_event_trigger_water_temperature61C_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000003) + + async def send_test_event_trigger_water_temperature66C_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000004) + + async def send_test_event_trigger_manual_mode_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000005) + + async def send_test_event_trigger_off_mode_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000006) + + async def send_test_event_trigger_draw_off_hot_water_test_event(self): + await self.send_test_event_triggers(eventTrigger=0x0094000000000007) diff --git a/src/python_testing/TC_EWATERHTR_2_1.py b/src/python_testing/TC_EWATERHTR_2_1.py new file mode 100644 index 00000000000000..c278da6c094010 --- /dev/null +++ b/src/python_testing/TC_EWATERHTR_2_1.py @@ -0,0 +1,121 @@ +# +# 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. + + +# 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 --featureSet 0x03 +# 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 --int-arg PIXIT.EWATERHTR.EM:1 PIXIT.EWATERHTR.TP:2 +# === END CI TEST ARGUMENTS === + +import logging + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_EWATERHTRBase import EWATERHTRBase + +logger = logging.getLogger(__name__) + + +class TC_EWATERHTR_2_1(MatterBaseTest, EWATERHTRBase): + + def desc_TC_EWATERHTR_2_1(self) -> str: + """Returns a description of this test""" + return "[TC-EWATERHTR-2.1] Attributes with attributes with DUT as Server\n" \ + "This test case verifies the non-global attributes of the Water Heater Management cluster server." + + def pics_TC_EWATERHTR_2_1(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["EWATERHTR.S"] + + def steps_TC_EWATERHTR_2_1(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads HeaterTypes attribute.", + "DUT as Server replies with a WaterHeaterTypeBitmap (enum8) greater than 0x00 (at least one type supported), and less than 0x20 (no undefined types supported)."), + TestStep("3", "TH reads HeatDemand attribute.", + "DUT as Server replies with a WaterHeaterDemandBitmap (enum8)."), + TestStep("4", "TH reads TankVolume attribute.", + "DUT as Server replies with a uint16 value."), + TestStep("5", "TH reads EstimatedHeatRequired attribute.", + "DUT as Server replies with an energy-mWh value."), + TestStep("6", "TH reads TankPercentage attribute.", + "DUT as Server replies with a percent value."), + TestStep("7", "TH reads BoostState attribute.", + "DUT as Server replies with a BoostStateEnum (enum8) value."), + ] + + return steps + + @async_test_body + async def test_TC_EWATERHTR_2_1(self): + + em_supported = self.matter_test_config.global_test_params['PIXIT.EWATERHTR.EM'] + tp_supported = self.matter_test_config.global_test_params['PIXIT.EWATERHTR.TP'] + + self.step("1") + # Commission DUT - already done + + self.step("2") + heaterTypes = await self.read_whm_attribute_expect_success(attribute="HeaterTypes") + asserts.assert_greater(heaterTypes, 0, + f"Unexpected HeaterTypes value - expected {heaterTypes} > 0") + asserts.assert_less_equal(heaterTypes, Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterTypeBitmap.kOther, + f"Unexpected HeaterTypes value - expected {heaterTypes} <= WaterHeaterTypeBitmap.kOther") + + self.step("3") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0, + f"Unexpected HeatDemand value - expected {heatDemand} > 0") + asserts.assert_less_equal(heatDemand, Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterDemandBitmap.kOther, + f"Unexpected HeatDemand value - expected {heatDemand} <= WaterHeaterDemandBitmap.kOther") + + self.step("4") + if em_supported: + value = await self.read_whm_attribute_expect_success(attribute="TankVolume") + else: + logging.info("Skipping step 4 as PIXIT.EWATERHTR.EM not supported") + + self.step("5") + if em_supported: + value = await self.read_whm_attribute_expect_success(attribute="EstimatedHeatRequired") + asserts.assert_greater_equal(value, 0, f"Unexpected EstimatedHeatRequired value - expected {value} >= 0") + else: + logging.info("Skipping step 5 as PIXIT.EWATERHTR.EM not supported") + + self.step("6") + if tp_supported: + value = await self.read_whm_attribute_expect_success(attribute="TankPercentage") + asserts.assert_greater_equal(value, 0, f"Unexpected TankPercentage value - expected {value} >= 0") + asserts.assert_less_equal(value, 100, f"Unexpected TankPercentage value - expected {value} <= 100") + else: + logging.info("Skipping step 6 as PIXIT.EWATERHTR.TP not supported") + + self.step("7") + boost_state = await self.read_whm_attribute_expect_success(attribute="BoostState") + asserts.assert_less_equal(boost_state, Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive, + f"Unexpected BoostState value - expected {boost_state} should be BoostStateEnum (enum8) value in range 0x00 to 0x01") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_EWATERHTR_2_2.py b/src/python_testing/TC_EWATERHTR_2_2.py new file mode 100644 index 00000000000000..0d20e1d4af97f4 --- /dev/null +++ b/src/python_testing/TC_EWATERHTR_2_2.py @@ -0,0 +1,378 @@ +# +# 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. + + +# 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 --featureSet 0x00 +# 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 + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_EWATERHTRBase import EWATERHTRBase + +logger = logging.getLogger(__name__) + + +class TC_EWATERHTR_2_2(MatterBaseTest, EWATERHTRBase): + + def desc_TC_EWATERHTR_2_2(self) -> str: + """Returns a description of this test""" + return "[TC-EWATERHTR-2.2] Basic functionality with attributes with DUT as Server." \ + "This test case verifies the primary functionality of the Water Heater Management cluster server." + + def pics_TC_EWATERHTR_2_2(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["EWATERHTR.S"] + + def steps_TC_EWATERHTR_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 value is 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Basic installation Test Event.", + "Verify Command response is Success"), + TestStep("3a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("3b", "TH reads BoostState attribute.", + "Verify value is 0 (Inactive)"), + TestStep("3c", "TH reads HeaterTypes attribute.", + "Verify value is greater than 0x00 (at least one type supported) and store the value as HeaterTypes"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Manual mode Test Event.", + "Verify Command response is Success"), + TestStep("4a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("5", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event.", + "Verify Command response is Success"), + TestStep("5a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 20C Test Event.", + "Verify Command response is Success"), + TestStep("6a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source)"), + TestStep("7", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Off mode Test Event.", + "Verify Command response is Success"), + TestStep("7a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("8", "TH sends Boost with Duration=5s,OneShot=True.", + "Verify Command response is Success"), + TestStep("8a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("8b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("9", "Wait 6 seconds"), + TestStep("9a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("9b", "TH reads BoostState attribute.", + "Verify value is 0 (Inactive)"), + TestStep("10", "TH sends Boost with Duration=600s,OneShot=True.", + "Verify Command response is Success"), + TestStep("10a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("10b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event.", + "Verify Command response is Success"), + TestStep("11a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("11b", "TH reads BoostState attribute.", + "Verify value is 0 (Inactive)"), + TestStep("12", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 20C Test Event.", + "Verify Command response is Success"), + TestStep("12a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("13", "TH sends Boost with Duration=600s.", + "Verify Command response is Success"), + TestStep("13a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("13b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event.", + "Verify Command response is Success"), + TestStep("14a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("14b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("15", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 20C Test Event.", + "Verify Command response is Success"), + TestStep("15a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("15b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("16", "TH sends CancelBoost.", + "Verify Command response is Success"), + TestStep("16a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("16b", "TH reads BoostState attribute.", + "Verify value is 0 (Inactive)"), + TestStep("17", "TH sends Boost with Duration=600s,TemporarySetpoint=65C.", + "Verify Command response is Success"), + TestStep("17a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("17b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event.", + "Verify Command response is Success"), + TestStep("18a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("18b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 66C Test Event.", + "Verify Command response is Success"), + TestStep("19a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("19b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("20", "TH sends Boost with Duration=600s,TemporarySetpoint=70C.", + "Verify Command response is Success"), + TestStep("20a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("20b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("21", "TH sends CancelBoost.", + "Verify Command response is Success"), + TestStep("21a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("21b", "TH reads BoostState attribute.", + "Verify value is 0 (Inactive)"), + TestStep("22", "TH sends CancelBoost.", + "Verify Command response is Success"), + TestStep("23", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Basic installation Test Event Clear.", + "Verify Command response is Success"), + ] + + return steps + + @async_test_body + async def test_TC_EWATERHTR_2_2(self): + + self.step("1") + # Commission DUT - already done + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_basic_installation_test_event() + + self.step("3a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("3b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("3c") + heaterTypes = await self.read_whm_attribute_expect_success(attribute="HeaterTypes") + asserts.assert_greater(heaterTypes, 0, + f"Unexpected HeaterTypes value - expected {heaterTypes} > 0") + asserts.assert_less_equal(heaterTypes, Clusters.WaterHeaterManagement.Bitmaps.WaterHeaterTypeBitmap.kOther, + f"Unexpected HeaterTypes value - expected {heaterTypes} <= WaterHeaterTypeBitmap.kOther") + + self.step("4") + await self.send_test_event_trigger_manual_mode_test_event() + + self.step("4a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("5") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("5a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("6") + await self.send_test_event_trigger_water_temperature20C_test_event() + + self.step("6a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("7") + await self.send_test_event_trigger_off_mode_test_event() + + self.step("7a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("8") + await self.send_boost_command(duration=5, one_shot=True) + + self.step("8a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("8b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("9") + time.sleep(6) + + self.step("9a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("9b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("10") + await self.send_boost_command(duration=600, one_shot=True) + + self.step("10a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("10b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("11") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("11a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("11b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("12") + await self.send_test_event_trigger_water_temperature20C_test_event() + + self.step("12a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("13") + await self.send_boost_command(duration=600) + + self.step("13a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("13b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("14") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("14a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("14b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("15") + await self.send_test_event_trigger_water_temperature20C_test_event() + + self.step("15a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("15b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("16") + await self.send_cancel_boost_command() + + self.step("16a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("16b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("17") + await self.send_boost_command(duration=600, temporary_setpoint=6500) + + self.step("17a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("17b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("18") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("18a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("18b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("19") + await self.send_test_event_trigger_water_temperature66C_test_event() + + self.step("19a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("19b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("20") + await self.send_boost_command(duration=600, temporary_setpoint=7000) + + self.step("20a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("20b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("21") + await self.send_cancel_boost_command() + + self.step("21a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("21b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("22") + await self.send_cancel_boost_command() + + self.step("23") + await self.send_test_event_trigger_basic_installation_test_event_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_EWATERHTR_2_3.py b/src/python_testing/TC_EWATERHTR_2_3.py new file mode 100644 index 00000000000000..b9572c9520d843 --- /dev/null +++ b/src/python_testing/TC_EWATERHTR_2_3.py @@ -0,0 +1,285 @@ +# +# 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. + +# 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 --featureSet 0x03 +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_EWATERHTRBase import EWATERHTRBase + +logger = logging.getLogger(__name__) + + +class TC_EWATERHTR_2_3(MatterBaseTest, EWATERHTRBase): + + def desc_TC_EWATERHTR_2_3(self) -> str: + """Returns a description of this test""" + return "[TC-EWATERHTR-2.3] This test case verifies the functionality of the Water Heater Management cluster server with the TankPercentage feature." + + def pics_TC_EWATERHTR_2_3(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["EWATERHTR.S", "EWATERHTR.S.F01"] + + def steps_TC_EWATERHTR_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 value is 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Basic installation Test Event.", + "Verify Command response is Success"), + TestStep("3a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("3b", "TH reads BoostState attribute.", + "Verify value is 0 (Inactive)"), + TestStep("3c", "TH reads TankPercentage attribute.", + "Verify value is 0%"), + TestStep("3d", "TH reads HeaterTypes attribute.", + "Verify value is greater than 0x00 (at least one type supported) and store the value as HeaterTypes"), + TestStep("4", "TH sends Boost with Duration=600s,TargetPercentage=100%.", + "Verify Command response is Success"), + TestStep("4a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("4b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("5", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event.", + "Verify Command response is Success"), + TestStep("5a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("5b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("5c", "TH reads TankPercentage attribute.", + "Verify value is 100%"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Draw off hot water Test Event.", + "Verify Command response is Success"), + TestStep("6a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("6b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("6c", "TH reads TankPercentage attribute.", + "Verify value is 75%"), + TestStep("7", "TH sends CancelBoost.", + "Verify Command response is Success"), + TestStep("7a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("7b", "TH reads BoostState attribute.", + "Verify value is 0 (Inactive)"), + TestStep("7c", "TH reads TankPercentage attribute.", + "Verify value is 75%"), + TestStep("8", "TH sends Boost with Duration=600s,TargetPercentage=100%,TargetReheat=65%.", + "Verify Command response is Success"), + TestStep("8a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("8b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("8c", "TH reads TankPercentage attribute.", + "Verify value is 75%"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Water Temperature 61C Test Event.", + "Verify Command response is Success"), + TestStep("9a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("9b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("9c", "TH reads TankPercentage attribute.", + "Verify value is 100%"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Draw off hot water Test Event.", + "Verify Command response is Success"), + TestStep("10a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("10b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("10c", "TH reads TankPercentage attribute.", + "Verify value is 75%"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Draw off hot water Test Event.", + "Verify Command response is Success"), + TestStep("11a", "TH reads HeatDemand attribute.", + "Verify value is greater than 0x00 (demand on at least one source) and (HeaterDemand & (!HeaterTypes)) is zero (demand is only from declared supported types)"), + TestStep("11b", "TH reads BoostState attribute.", + "Verify value is 1 (Active)"), + TestStep("11c", "TH reads TankPercentage attribute.", + "Verify value is 50%"), + TestStep("12", "TH sends CancelBoost.", + "Verify Command response is Success"), + TestStep("12a", "TH reads HeatDemand attribute.", + "Verify value is 0x00 (no demand on any source)"), + TestStep("12b", "TH reads BoostState attribute.", + "Verify value is 0 (Inactive)"), + TestStep("12c", "TH reads TankPercentage attribute.", + "Verify value is 50%"), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EWATERHTR.TEST_EVENT_TRIGGER for Basic installation Test Event Clear.", + "Verify Command response is Success"), + ] + + return steps + + @async_test_body + async def test_TC_EWATERHTR_2_3(self): + + self.step("1") + # Commission DUT - already done + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_basic_installation_test_event() + + self.step("3a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("3b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("3c") + await self.check_whm_attribute("TankPercentage", 0) + + self.step("3d") + heaterTypes = await self.read_whm_attribute_expect_success(attribute="HeaterTypes") + asserts.assert_greater(heaterTypes, 0) + + self.step("4") + await self.send_boost_command(duration=600, target_percentage=100) + + self.step("4a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("4b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("5") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("5a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_equal(heatDemand, 0) + + self.step("5b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("5c") + await self.check_whm_attribute("TankPercentage", 100) + + self.step("6") + await self.send_test_event_trigger_draw_off_hot_water_test_event() + + self.step("6a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("6b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("6c") + await self.check_whm_attribute("TankPercentage", 75) + + self.step("7") + await self.send_cancel_boost_command() + + self.step("7a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("7b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("7c") + await self.check_whm_attribute("TankPercentage", 75) + + self.step("8") + await self.send_boost_command(duration=600, target_percentage=100, target_reheat=65) + + self.step("8a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("8b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("8c") + await self.check_whm_attribute("TankPercentage", 75) + + self.step("9") + await self.send_test_event_trigger_water_temperature61C_test_event() + + self.step("9a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("9b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("9c") + await self.check_whm_attribute("TankPercentage", 100) + + self.step("10") + await self.send_test_event_trigger_draw_off_hot_water_test_event() + + self.step("10a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("10b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("10c") + await self.check_whm_attribute("TankPercentage", 75) + + self.step("11") + await self.send_test_event_trigger_draw_off_hot_water_test_event() + + self.step("11a") + heatDemand = await self.read_whm_attribute_expect_success(attribute="HeatDemand") + asserts.assert_greater(heatDemand, 0) + asserts.assert_equal(heatDemand & (~heaterTypes), 0, "heatDemand should only be from declared supported types"), + + self.step("11b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kActive) + + self.step("11c") + await self.check_whm_attribute("TankPercentage", 50) + + self.step("12") + await self.send_cancel_boost_command() + + self.step("12a") + await self.check_whm_attribute("HeatDemand", 0) + + self.step("12b") + await self.check_whm_attribute("BoostState", Clusters.WaterHeaterManagement.Enums.BoostStateEnum.kInactive) + + self.step("12c") + await self.check_whm_attribute("TankPercentage", 50) + + self.step("13") + await self.send_test_event_trigger_basic_installation_test_event_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_LVL_2_3.py b/src/python_testing/TC_LVL_2_3.py new file mode 100644 index 00000000000000..57fbe2b7edc367 --- /dev/null +++ b/src/python_testing/TC_LVL_2_3.py @@ -0,0 +1,186 @@ +# +# 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. +# + +# 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 +import time + +import chip.clusters as Clusters +import test_plan_support +from matter_testing_support import (ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, default_matter_test_main, + has_cluster, per_endpoint_test) +from mobly import asserts + + +class TC_LVL_2_3(MatterBaseTest): + + def steps_TC_LVL_2_3(self) -> list[TestStep]: + THRead = "TH reads" + THcommand = "TH sends the command" + return [TestStep(1, test_plan_support.commission_if_required(), is_commissioning=True), + TestStep(2, f"{THRead} FeatureMap attribute."), + TestStep(3, f"{THRead} MaxLevel attribute and store value as maxLevel", test_plan_support.verify_success()), + TestStep(4, f"{THcommand} MoveWithOnOff with MoveMode field set to Down and remaining fields set to 0", + test_plan_support.verify_success()), + TestStep(5, f"{THRead} CurrentLevel attribute and store value as startCurrentLevel", + test_plan_support.verify_success()), + TestStep(6, "Set up a subscription wildcard subscription for the Level Control Cluster, with MinIntervalFloor set to 0, MaxIntervalCeiling set to 30 and KeepSubscriptions set to false", + "Subscription successfully established"), + TestStep(7, f"{THcommand} MoveToLevel with Level field set to maxLevel, TransitionTime field set to 10 and remaining fields set to 0", + test_plan_support.verify_success()), + TestStep(8, "TH stores the reported values of CurrentLevel in all incoming reports for CurrentLevel attribute, that contains data in reportedCurrentLevelValuesList, over a period of 30 seconds."), + TestStep(9, "TH verifies that reportedCurrentLevelValuesList does not contain more than 10 entries for CurrentLevel", + "reportedCurrentLevelValuesList has 10 or less entries in the list"), + TestStep(10, "If reportedCurrentLevelValuesList only contain a single entry, TH verifies the value of the entry is equal to maxLevel", + "The entry in reportedCurrentLevelValuesList is equal to maxLevel"), + TestStep(11, "If reportedCurrentLevelValuesList contains two or more entries, TH verifies the value of the first entry is larger than startCurrentLevel", + "The first entry in reportedCurrentLevelValuesList is equal to or larger than to startCurrentLevel"), + TestStep(12, "If reportedCurrentLevelValuesList contains two or more entries, TH verifies the value of the last entry is equal to maxLevel", + "The last entry in reportedCurrentLevelValuesList is equal to maxLevel"), + TestStep(13, "If the LT feature is not supported, skip remaining steps and end test case"), + # 14 is missing in the test plan + TestStep(15, "TH stores the reported values of RemainingTime in all incoming reports for RemainingTime attribute, that contains data in reportedRemainingTimeValuesList."), + TestStep(16, f" {THcommand} MoveToLevel with Level field set to startCurrentLevel, TransitionTime field set to 10 and remaining fields set to 0", + test_plan_support.verify_success()), + TestStep(17, "Wait for 5 seconds"), + TestStep(18, f"{THcommand} MoveToLevel with Level field set to startCurrentLevel, TransitionTime field set to 15 and remaining fields set to 0", + test_plan_support.verify_success()), + TestStep(19, "Wait for 20 seconds"), + TestStep(20, "TH verifies reportedRemainingTimeValuesList contains three entries", + "reportedRemainingTimeValuesList has 3 entries in the list"), + TestStep(21, "TH verifies the first entry in reportedRemainingTimeValuesList is 10", + "The first entry in reportedRemainingTimeValuesList is equal to 10"), + TestStep(22, "TH verifies the second entry in reportedRemainingTimeValuesList is 15", + "The second entry in reportedRemainingTimeValuesList is equal to 15"), + TestStep(23, "TH verifies the third entry in reportedRemainingTimeValuesList is 0", + "The third entry in reportedRemainingTimeValuesList is equal to 0") + ] + + @per_endpoint_test(has_cluster(Clusters.LevelControl)) + async def test_TC_LVL_2_3(self): + # Commissioning - already done + self.step(1) + + lvl = Clusters.LevelControl + + self.step(2) + feature_map = await self.read_single_attribute_check_success(cluster=lvl, attribute=lvl.Attributes.FeatureMap) + + self.step(3) + max_level = await self.read_single_attribute_check_success(cluster=lvl, attribute=lvl.Attributes.MaxLevel) + + self.step(4) + cmd = Clusters.LevelControl.Commands.MoveWithOnOff(moveMode=lvl.Enums.MoveModeEnum.kDown) + await self.send_single_cmd(cmd) + # NOTE: added this sleep to let the DUT have some time to move + logging.info("Test waits for 5 seconds") + time.sleep(5) + + self.step(5) + start_current_level = await self.read_single_attribute_check_success(cluster=lvl, attribute=lvl.Attributes.CurrentLevel) + + self.step(6) + sub_handler = ClusterAttributeChangeAccumulator(lvl) + await sub_handler.start(self.default_controller, self.dut_node_id, self.matter_test_config.endpoint) + + self.step(7) + # NOTE: had to use the WithOnOff version of this command because the dut is off at this point thanks to the above command + # TODO: Need to check above and here that the on/off cluster is actually implemented. + cmd = lvl.Commands.MoveToLevelWithOnOff(level=max_level, transitionTime=100, optionsMask=0, optionsOverride=0) + await self.send_single_cmd(cmd) + + self.step(8) + logging.info('Test will now collect data for 30 seconds') + time.sleep(30) + + self.step(9) + count = sub_handler.attribute_report_counts[lvl.Attributes.CurrentLevel] + asserts.assert_less_equal(count, 10, "Received more than 10 reports for CurrentLevel") + asserts.assert_greater(count, 0, "Did not receive any reports for CurrentLevel") + + self.step(10) + if count == 1: + entry = sub_handler.attribute_reports[lvl.Attributes.CurrentLevel][-1] + asserts.assert_equal(entry.value, max_level, "Entry is not equal to max level") + + if count > 1: + self.step(11) + last_value = start_current_level + for e in sub_handler.attribute_reports[lvl.Attributes.CurrentLevel]: + asserts.assert_greater_equal(e.value, last_value, "Values are not increasing") + + self.step(12) + asserts.assert_equal(e.value, max_level, "Last entry is not max value") + else: + self.skip_step(11) + self.skip_step(12) + + self.step(13) + if (lvl.Bitmaps.Feature.kLighting & feature_map) == 0: + self.skip_all_remaining_steps(15) + + self.step(15) + # reports are stored by the handler, so just reset so we get a clean look + sub_handler.reset() + + self.step(16) + cmd = Clusters.LevelControl.Commands.MoveToLevel( + level=start_current_level, transitionTime=100, optionsMask=0, optionsOverride=0) + await self.send_single_cmd(cmd) + + self.step(17) + logging.info("Test waits for 5 seconds") + time.sleep(5) + + self.step(18) + cmd = Clusters.LevelControl.Commands.MoveToLevel( + level=start_current_level, transitionTime=150, optionsMask=0, optionsOverride=0) + await self.send_single_cmd(cmd) + + self.step(19) + logging.info("Test waits for 20 seconds") + time.sleep(20) + + self.step(20) + count = sub_handler.attribute_report_counts[lvl.Attributes.RemainingTime] + asserts.assert_equal(count, 3, "Unexpected number of remaining time reports") + + self.step(21) + remaining_time = sub_handler.attribute_reports[lvl.Attributes.RemainingTime] + logging.info(f'Reamining time reports: {remaining_time}') + asserts.assert_equal(remaining_time[0].value, 100, "Unexpected first RemainingTime report") + + self.step(22) + asserts.assert_almost_equal(remaining_time[1].value, 150, delta=10, msg="Unexpected second RemainingTime report") + + self.step(23) + asserts.assert_equal(remaining_time[2].value, 0, "Unexpected last RemainingTime report") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OpstateCommon.py b/src/python_testing/TC_OpstateCommon.py index 648eea59f2bb3c..09dc73e3344c1f 100644 --- a/src/python_testing/TC_OpstateCommon.py +++ b/src/python_testing/TC_OpstateCommon.py @@ -354,7 +354,7 @@ async def TEST_TC_OPSTATE_BASE_2_1(self, endpoint=1): if phase_list is not NullValue: phase_list_len = len(phase_list) asserts.assert_less_equal(phase_list_len, 32, - f"PhaseList length({phase_list_len}) must be less than 32!") + f"PhaseList length({phase_list_len}) must be at most 32 entries!") # STEP 3: TH reads from the DUT the CurrentPhase attribute self.step(3) @@ -364,8 +364,9 @@ async def TEST_TC_OPSTATE_BASE_2_1(self, endpoint=1): if (phase_list == NullValue) or (not phase_list): asserts.assert_true(current_phase == NullValue, f"CurrentPhase({current_phase}) should be null") else: - asserts.assert_true(0 <= current_phase and current_phase < phase_list_len, - f"CurrentPhase({current_phase}) must be between 0 and {(phase_list_len - 1)}") + asserts.assert_greater_equal(current_phase, 0, f"CurrentPhase({current_phase}) must be >= 0") + asserts.assert_less(current_phase, phase_list_len, + f"CurrentPhase({current_phase}) must be less than {phase_list_len}") # STEP 4: TH reads from the DUT the CountdownTime attribute self.step(4) @@ -652,7 +653,7 @@ async def TEST_TC_OPSTATE_BASE_2_2(self, endpoint=1): if phase_list is not NullValue: phase_list_len = len(phase_list) asserts.assert_less_equal(phase_list_len, 32, - f"PhaseList length({phase_list_len}) must be less than 32!") + f"PhaseList length({phase_list_len}) must be at most 32 entries!") # STEP 9: TH reads from the DUT the CurrentPhase attribute self.step(9) @@ -662,10 +663,10 @@ async def TEST_TC_OPSTATE_BASE_2_2(self, endpoint=1): if (phase_list == NullValue) or (not phase_list): asserts.assert_equal(current_phase, NullValue, f"CurrentPhase({current_phase}) should be null") else: - asserts.assert_less_equal(0, current_phase, - f"CurrentPhase({current_phase}) must be greater or equal than 0") - asserts.assert_less(current_phase < phase_list_len, - f"CurrentPhase({current_phase}) must be less then {(phase_list_len - 1)}") + asserts.assert_greater_equal(current_phase, 0, + f"CurrentPhase({current_phase}) must be greater or equal to 0") + asserts.assert_less(current_phase, phase_list_len, + f"CurrentPhase({current_phase}) must be less than {(phase_list_len)}") # STEP 10: TH waits for {PIXIT.WAITTIME.COUNTDOWN} self.step(10) @@ -679,6 +680,8 @@ async def TEST_TC_OPSTATE_BASE_2_2(self, endpoint=1): attribute=attributes.CountdownTime) if (countdown_time is not NullValue) and (initial_countdown_time is not NullValue): + logging.info(f" -> Initial countdown time: {initial_countdown_time}") + logging.info(f" -> New countdown time: {countdown_time}") asserts.assert_less_equal(countdown_time, (initial_countdown_time - wait_time), f"The countdown time shall have decreased at least {wait_time:.1f} since start command") @@ -821,6 +824,7 @@ async def TEST_TC_OPSTATE_BASE_2_3(self, endpoint=1): initial_countdown_time = await self.read_expect_success(endpoint=endpoint, attribute=attributes.CountdownTime) if initial_countdown_time is not NullValue: + logging.info(f" -> Initial ountdown time: {initial_countdown_time}") asserts.assert_true(0 <= initial_countdown_time <= 259200, f"CountdownTime({initial_countdown_time}) must be between 0 and 259200") @@ -835,6 +839,8 @@ async def TEST_TC_OPSTATE_BASE_2_3(self, endpoint=1): attribute=attributes.CountdownTime) if (countdown_time is not NullValue) and (initial_countdown_time is not NullValue): + logging.info(f" -> Initial countdown time: {initial_countdown_time}") + logging.info(f" -> New countdown time: {countdown_time}") asserts.assert_equal(countdown_time, initial_countdown_time, "The countdown time shall be equal since pause command") diff --git a/src/python_testing/TC_SWTCH.py b/src/python_testing/TC_SWTCH.py index 5fb968b724e098..6da5c7a229e0b7 100644 --- a/src/python_testing/TC_SWTCH.py +++ b/src/python_testing/TC_SWTCH.py @@ -23,7 +23,7 @@ # 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 --endpoint 3 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --PICS src/app/tests/suites/certification/ci-pics-values +# 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 --PICS src/app/tests/suites/certification/ci-pics-values # === END CI TEST ARGUMENTS === import json @@ -37,8 +37,9 @@ import test_plan_support from chip.clusters import ClusterObjects as ClusterObjects from chip.clusters.Attribute import EventReadResult, TypedAttributePath +from chip.tlv import uint from matter_testing_support import (AttributeValue, ClusterAttributeChangeAccumulator, EventChangeCallback, MatterBaseTest, - TestStep, async_test_body, default_matter_test_main) + TestStep, default_matter_test_main, has_feature, per_endpoint_test) from mobly import asserts logger = logging.getLogger(__name__) @@ -52,10 +53,7 @@ def desc_TC_SWTCH_2_4(self) -> str: """Returns a description of this test""" return "[TC-SWTCH-2.4] Momentary Switch Long Press Verification" - def pics_TC_SWTCH_2_4(self): - """ This function returns a list of PICS for this test case that must be True for the test to be run""" - return ["SWTCH.S", "SWTCH.S.F01"] - + # TODO(#34656): Fill test steps # def steps_TC_SWTCH_2_4(self) -> list[TestStep]: # steps = [ # TestStep("0", "Commissioning, already done", is_commissioning=True), @@ -82,28 +80,80 @@ def _send_named_pipe_command(self, command_dict: dict[str, Any]): def _use_button_simulator(self) -> bool: return self.check_pics("PICS_SDK_CI_ONLY") or self.user_params.get("use_button_simulator", False) + def _send_multi_press_named_pipe_command(self, endpoint_id: int, number_of_presses: int, pressed_position: int, feature_map: uint, multi_press_max: uint): + command_dict = {"Name": 'SimulateMultiPress', "EndpointId": endpoint_id, + "ButtonId": pressed_position, "MultiPressPressedTimeMillis": 500, "MultiPressReleasedTimeMillis": 500, + "MultiPressNumPresses": number_of_presses, "FeatureMap": feature_map, "MultiPressMax": multi_press_max} + self._send_named_pipe_command(command_dict) + + def _send_long_press_named_pipe_command(self, endpoint_id: int, pressed_position: int, feature_map: int): + command_dict = {"Name": "SimulateLongPress", "EndpointId": endpoint_id, + "ButtonId": pressed_position, "LongPressDelayMillis": 5000, "LongPressDurationMillis": 5500, "FeatureMap": feature_map} + self._send_named_pipe_command(command_dict) + + def _send_latching_switch_named_pipe_command(self, endpoint_id: int, new_position: int): + command_dict = {"Name": "SimulateLatchPosition", "EndpointId": endpoint_id, "PositionId": new_position} + self._send_named_pipe_command(command_dict) + def _ask_for_switch_idle(self): if not self._use_button_simulator(): self.wait_for_user_input(prompt_msg="Ensure switch is idle") - def _ask_for_long_press(self, endpoint_id: int, pressed_position: int): + def _ask_for_switch_position(self, endpoint_id: int, new_position: int): + if not self._use_button_simulator(): + self.wait_for_user_input(prompt_msg=f"Move latched switch to position {new_position}, if it is not already there.") + else: + self._send_latching_switch_named_pipe_command(endpoint_id, new_position) + + def _ask_for_multi_press_short_long(self, endpoint_id: int, pressed_position: int, feature_map: uint, multi_press_max: uint): + if not self._use_button_simulator(): + msg = f""" + Actuate the switch in the following sequence: + 1. Operate switch (press briefly) associated with position {pressed_position} on the DUT then release switch from DUT + 2. Operate switch (keep pressed for long time, e.g. 5 seconds) on the DUT immediately after the previous step + 3. Release switch from the DUT + """ + self.wait_for_user_input(msg) + else: + # This is just a simulator, ignore the long press instruction for now, it doesn't matter for the CI. It does for cert. + self._send_multi_press_named_pipe_command( + endpoint_id, number_of_presses=2, pressed_position=pressed_position, feature_map=feature_map, multi_press_max=multi_press_max) + + def _ask_for_multi_press_long_short(self, endpoint_id, pressed_position, feature_map: int): + if not self._use_button_simulator(): + msg = f""" + Actuate the switch in the following sequence: + 1. Operate switch (keep pressed for long time, e.g. 5 seconds) on the DUT + 2. Releases switch from the DUT + 3. Immediately after the previous step completes, operate switch (press briefly) associated with position {pressed_position} on the DUT then release switch from DUT + """ + self.wait_for_user_input(msg) + else: + # This is just the start of the sequence + # we'll need to send the short press after getting the LongRelease event because the simulator doesn't queue requests. + self._send_long_press_named_pipe_command(endpoint_id, pressed_position, feature_map) + + def _ask_for_multi_press(self, endpoint_id: int, number_of_presses: int, pressed_position: int, feature_map: uint, multi_press_max: uint): + if not self._use_button_simulator(): + self.wait_for_user_input( + f'Operate the switch (press briefly) associated with position {pressed_position} then release {number_of_presses} times') + else: + self._send_multi_press_named_pipe_command(endpoint_id, number_of_presses, + pressed_position, feature_map, multi_press_max) + + def _ask_for_long_press(self, endpoint_id: int, pressed_position: int, feature_map): if not self._use_button_simulator(): self.wait_for_user_input( prompt_msg=f"Press switch position {pressed_position} for a long time (around 5 seconds) on the DUT, then release it.") else: - command_dict = {"Name": "SimulateActionSwitchLongPress", "EndpointId": endpoint_id, - "ButtonId": pressed_position, "LongPressDelayMillis": 5000, "LongPressDurationMillis": 5500} - self._send_named_pipe_command(command_dict) + self._send_long_press_named_pipe_command(endpoint_id, pressed_position, feature_map) - def _ask_for_keep_pressed(self, endpoint_id: int, pressed_position: int): + def _ask_for_keep_pressed(self, endpoint_id: int, pressed_position: int, feature_map: int): if not self._use_button_simulator(): self.wait_for_user_input( prompt_msg=f"Press switch position {pressed_position} for a long time (around 5 seconds) on the DUT, then release it.") else: - # Using the long press here with a long duration so we can check the intermediate value. - command_dict = {"Name": "SimulateActionSwitchLongPress", "EndpointId": endpoint_id, - "ButtonId": pressed_position, "LongPressDelayMillis": 0, "LongPressDurationMillis": self.keep_pressed_delay} - self._send_named_pipe_command(command_dict) + self._send_long_press_named_pipe_command(endpoint_id, pressed_position, feature_map) def _ask_for_release(self): # Since we used a long press for this, "ask for release" on the button simulator just means waiting out the delay @@ -115,7 +165,7 @@ def _ask_for_release(self): time.sleep(self.keep_pressed_delay/1000) def _placeholder_for_step(self, step_id: str): - # TODO: Global search an replace of `self._placeholder_for_step` with `self.step` when done. + # TODO(#34656): Global search an replace of `self._placeholder_for_step` with `self.step` when done. logging.info(f"Step {step_id}") pass @@ -219,9 +269,9 @@ def _expect_no_events_for_cluster(self, event_queue: queue.Queue, endpoint_id: i logging.info(f"Successfully waited for no further events on {expected_cluster} for {elapsed:.1f} seconds") - @async_test_body + @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) async def test_TC_SWTCH_2_4(self): - # TODO: Make this come from PIXIT + # TODO(#34656): Make this come from PIXIT switch_pressed_position = 1 post_prompt_settle_delay_seconds = 10.0 @@ -263,7 +313,7 @@ async def test_TC_SWTCH_2_4(self): # Step 4a: Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, the release it self._placeholder_for_step("4a") - self._ask_for_long_press(endpoint_id, switch_pressed_position) + self._ask_for_long_press(endpoint_id, switch_pressed_position, feature_map) # Step 4b: TH expects report of CurrentPosition 1, followed by a report of Current Position 0. self._placeholder_for_step("4b") @@ -323,8 +373,89 @@ def _received_event(self, event_listener: EventChangeCallback, target_event: Clu remaining = end_time - datetime.now() return False - def pics_TC_SWTCH_2_3(self): - return ['SWTCH.S.F01'] + def steps_TC_SWTCH_2_2(self): + return [TestStep(1, test_plan_support.commission_if_required(), "", is_commissioning=True), + TestStep(2, "Set up subscription to all events of Switch cluster on the endpoint"), + TestStep(3, "Operator sets switch to first position on the DUT"), + TestStep(4, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), + TestStep(5, "Operator sets switch to second position (one) on the DUT", + "Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT"), + TestStep(6, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1"), + TestStep(7, "If there are more than 2 positions, test subsequent positions of the DUT"), + TestStep(8, "Operator sets switch to first position on the DUT."), + TestStep(9, "Wait 10 seconds for event reports stable." "Verify that last SwitchLatched event received is for NewPosition 0."), + TestStep(10, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), + ] + + @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kLatchingSwitch)) + async def test_TC_SWTCH_2_2(self): + post_prompt_settle_delay_seconds = 10.0 + + # Step 1: Commissioning - already done + self.step(1) + + cluster = Clusters.Switch + endpoint_id = self.matter_test_config.endpoint + + # Step 2: Set up subscription to all events of Switch cluster on the endpoint. + self.step(2) + event_listener = EventChangeCallback(cluster) + await event_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + + # Step 3: Operator sets switch to first position on the DUT. + self.step(3) + self._ask_for_switch_position(endpoint_id, new_position=0) + event_listener.flush_events() + + # Step 4: TH reads the CurrentPosition attribute from the DUT. + # Verify that the value is 0. + self.step(4) + button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) + asserts.assert_equal(button_val, 0, "Switch position value is not 0") + + # Step 5: Operator sets switch to second position (one) on the DUT", + # Verify that the TH receives SwitchLatched event with NewPosition set to 1 from the DUT + self.step(5) + expected_switch_position = 1 + self._ask_for_switch_position(endpoint_id, expected_switch_position) + + data = event_listener.wait_for_event_report(cluster.Events.SwitchLatched, timeout_sec=post_prompt_settle_delay_seconds) + logging.info(f"-> SwitchLatched event last received: {data}") + asserts.assert_equal(data, cluster.Events.SwitchLatched( + newPosition=expected_switch_position), "Did not get expected switch position") + + # Step 6: TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1 + self.step(6) + button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) + asserts.assert_equal(button_val, expected_switch_position, f"Switch position is not {expected_switch_position}") + + # Step 7: If there are more than 2 positions, test subsequent positions of the DUT + # # TODO(#34656): Implement loop for > 2 total positions + self.skip_step(7) + + # Step 8: Operator sets switch to first position on the DUT. + self.step(8) + event_listener.flush_events() + self._ask_for_switch_position(endpoint_id, new_position=0) + + # Step 9: Wait 10 seconds for event reports stable. + # Verify that last SwitchLatched event received is for NewPosition 0. + self.step(9) + time.sleep(10.0) + + expected_switch_position = 0 + last_event = event_listener.get_last_event() + asserts.assert_is_not_none(last_event, "Did not get SwitchLatched events since last operator action.") + last_event_data = last_event.Data + logging.info(f"-> SwitchLatched event last received: {last_event_data}") + asserts.assert_equal(last_event_data, cluster.Events.SwitchLatched( + newPosition=expected_switch_position), "Did not get expected switch position") + + # Step 10: TH reads the CurrentPosition attribute from the DUT. + # Verify that the value is 0 + self.step(10) + button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) + asserts.assert_equal(button_val, 0, "Button value is not 0") def steps_TC_SWTCH_2_3(self): return [TestStep(1, test_plan_support.commission_if_required(), "", is_commissioning=True), @@ -335,13 +466,14 @@ def steps_TC_SWTCH_2_3(self): "Verify that the TH receives InitialPress event with NewPosition set to 1 on the DUT"), TestStep(6, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 1"), TestStep(7, "Operator releases switch on the DUT"), - TestStep("8a", "If the DUT implements the MSR feature, verify that the TH receives ShortRelease event with NewPosition set to 0 on the DUT", "Event received"), + TestStep("8a", "If the DUT implements the MSR feature and does not implement the MSL feature, verify that the TH receives ShortRelease event with NewPosition set to 0 on the DUT", "Event received"), + TestStep("8b", "If the DUT implements the MSR feature and the MSL feature, verify that the TH receives LongRelease event with NewPosition set to 0 on the DUT", "Event received"), TestStep( - "8b", "If the DUT implements the AS feature, verify that the TH does not receive ShortRelease event on the DUT", "No event received"), + "8c", "If the DUT implements the AS feature, verify that the TH does not receive ShortRelease event on the DUT", "No event received"), TestStep(9, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), ] - @async_test_body + @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) async def test_TC_SWTCH_2_3(self): # Commissioning - already done self.step(1) @@ -349,6 +481,7 @@ async def test_TC_SWTCH_2_3(self): feature_map = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.FeatureMap) has_msr_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchRelease) != 0 + has_msl_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchLongPress) != 0 has_as_feature = (feature_map & cluster.Bitmaps.Feature.kActionSwitch) != 0 endpoint_id = self.matter_test_config.endpoint @@ -369,7 +502,7 @@ async def test_TC_SWTCH_2_3(self): # This is 1s larger than the subscription ceiling self.keep_pressed_delay = 6000 self.pressed_position = 1 - self._ask_for_keep_pressed(endpoint_id, self.pressed_position) + self._ask_for_keep_pressed(endpoint_id, self.pressed_position, feature_map) event_listener.wait_for_event_report(cluster.Events.InitialPress) self.step(6) @@ -380,13 +513,18 @@ async def test_TC_SWTCH_2_3(self): self._ask_for_release() self.step("8a") - if has_msr_feature: + if has_msr_feature and not has_msl_feature: asserts.assert_true(self._received_event(event_listener, cluster.Events.ShortRelease, 10), "Did not receive short release") else: self.mark_current_step_skipped() self.step("8b") + if has_msr_feature and has_msl_feature: + asserts.assert_true(self._received_event(event_listener, cluster.Events.LongRelease, 10), + "Did not receive long release") + + self.step("8c") if has_as_feature: asserts.assert_false(self._received_event(event_listener, cluster.Events.ShortRelease, 10), "Received short release") else: @@ -396,6 +534,355 @@ async def test_TC_SWTCH_2_3(self): button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) asserts.assert_equal(button_val, 0, "Button value is not 0") + def steps_TC_SWTCH_2_5(self): + return [TestStep(1, test_plan_support.commission_if_required(), "", is_commissioning=True), + TestStep(2, "Set up a subscription to all Switch cluster events"), + TestStep(3, "Operate does not operate the switch on the DUT"), + TestStep("4a", "Operator operates switch (press briefly) associated with position 1 on the DUT then release switch from DUT", + """ + + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + """), + TestStep("4b", "Operator does not operate switch on the DUT", + "TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 1 from the DUT"), + TestStep("5a", "Operator repeat step 4a 2 times quickly", + """ + + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives MultiPressOngoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 2 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + + + The events sequence SHALL follow the same sequence as above + """), + TestStep("5b", "Operator does not operate switch on the DUT", + "Verify that the TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 2 from the DUT"), + TestStep("6a", "If MultiPressMax == 2 (see 2c of TC-SWTCH-2.1), skip steps 6b .. 6c"), + TestStep("6b", "Operator repeat step 4a 3 times quickly", + """ + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives MultiPressOngoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 2 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives MultiPressOngoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 3 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + + + The events sequence from the subscription SHALL follow the same sequence as expressed above, in the exact order of events specified. + """), + TestStep("6c", "Operator does not operate switch on the DUT for 5 seconds", + "Verify that the TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 3 from the DUT"), + TestStep(7, "Set up subscription to all Switch cluster events"), + TestStep("8a", + """ + Operator operates switch in below sequence: + 1. Operator operates switch (press briefly) associated with position 1 on the DUT then release switch from DUT + 2. Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT immediately after the previous step + 3. Operator releases switch from the DUT + """, + """ + + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + + * Verify that the TH receives MultiPressOngoing event with NewPosition set to 1 and CurrentNumberOfPressesCounted set to 2 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + * Verify that the TH does not receive LongPress event from the DUT + * Verify that the TH does not receive LongRelease event from the DUT + + The events sequence from the subscription SHALL follow the same sequence as expressed above, in the exact order of events specified. + """), + TestStep("8b", "Operator does not operate switch on the DUT", + "TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 2 from the DUT"), + TestStep("9a", + """ + Operator operates switch in below sequence: + 1. Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT + 2. Operator releases switch from the DUT + 3. Immediately after the previous step completes, Operator operates switch (press briefly) associated with position 1 on the DUT then release switch from DUT + """, + """ + + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives (one, not more than one) LongPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives LongRelease event with PreviousPosition set to 1 from the DUT + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives ShortRelease event with PreviousPosition set to 1 from the DUT + * Verify that the TH does not receive MultiPressOngoing event from the DUT + + The events sequence from the subscription SHALL follow the same sequence as expressed above, in the exact order of events specified. + """), + TestStep("9b", "Operator does not operate switch on the DUT", + "TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 2 from the DUT") + + ] + + @staticmethod + def should_run_SWTCH_2_5(wildcard, endpoint): + msm = has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitchMultiPress) + asf = has_feature(Clusters.Switch, 0x20) + return msm(wildcard, endpoint) and not asf(wildcard, endpoint) + + @per_endpoint_test(should_run_SWTCH_2_5) + async def test_TC_SWTCH_2_5(self): + # Commissioning - already done + self.step(1) + + cluster = Clusters.Switch + feature_map = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.FeatureMap) + has_msl_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchLongPress) + multi_press_max = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.MultiPressMax) + + endpoint_id = self.matter_test_config.endpoint + pressed_position = 1 + + self.step(2) + event_listener = EventChangeCallback(cluster) + await event_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + + self.step(3) + self._ask_for_switch_idle() + + def test_multi_press_sequence(starting_step: str, count: int, short_long: bool = False): + step = starting_step + self.step(step) + + if short_long: + self._ask_for_multi_press_short_long(endpoint_id, pressed_position, + feature_map=feature_map, multi_press_max=multi_press_max) + else: + self._ask_for_multi_press(endpoint_id, number_of_presses=count, pressed_position=pressed_position, + feature_map=feature_map, multi_press_max=multi_press_max) + for i in range(count): + event = event_listener.wait_for_event_report(cluster.Events.InitialPress) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on InitialEvent") + if i > 0: + event = event_listener.wait_for_event_report(cluster.Events.MultiPressOngoing) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on MultiPressOngoing") + asserts.assert_equal(event.currentNumberOfPressesCounted, i+1, + "Unexpected CurrentNumberOfPressesCounted on MultiPressOngoing") + event = event_listener.wait_for_event_report(cluster.Events.ShortRelease) + asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on ShortRelease") + + step = step[:-1] + chr(ord(step[-1])+1) + self.step(step) + self._ask_for_switch_idle() + event = event_listener.wait_for_event_report(cluster.Events.MultiPressComplete) + asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on MultiPressComplete") + asserts.assert_equal(event.totalNumberOfPressesCounted, count, "Unexpected count on MultiPressComplete") + + test_multi_press_sequence("4a", 1) + + test_multi_press_sequence("5a", 2) + + self.step("6a") + multi_press_max = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.MultiPressMax) + if multi_press_max == 2: + self.skip_step("6b") + self.skip_step("6c") + else: + test_multi_press_sequence("6b", 3) + + if not has_msl_feature: + self.skip_all_remaining_steps(7) + return + + self.step(7) + # subscription is already set up + + test_multi_press_sequence("8a", 2, short_long=True) + + self.step("9a") + self._ask_for_multi_press_long_short(endpoint_id, pressed_position, feature_map) + + event = event_listener.wait_for_event_report(cluster.Events.InitialPress) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on InitialEvent") + event = event_listener.wait_for_event_report(cluster.Events.LongPress) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on LongPress") + event = event_listener.wait_for_event_report(cluster.Events.LongRelease) + asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on LongRelease") + if self._use_button_simulator: + # simulator can't sequence so we need to help it along here + self._send_multi_press_named_pipe_command(endpoint_id, number_of_presses=1, + pressed_position=1, feature_map=feature_map, multi_press_max=multi_press_max) + + event = event_listener.wait_for_event_report(cluster.Events.InitialPress) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on InitialEvent") + event = event_listener.wait_for_event_report(cluster.Events.ShortRelease) + asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on ShortRelease") + + # Because this is a queue, we verify that no multipress ongoing is received by verifying that the next event is the multipress complete + + self.step("9b") + self._ask_for_switch_idle() + event = event_listener.wait_for_event_report(cluster.Events.MultiPressComplete) + asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on MultiPressComplete") + asserts.assert_equal(event.totalNumberOfPressesCounted, 1, "Unexpected count on MultiPressComplete") + + def steps_TC_SWTCH_2_6(self): + return [TestStep(1, test_plan_support.commission_if_required(), is_commissioning=True), + TestStep(2, "Set up subscription to all Switch cluster events"), + TestStep(3, "Operator does not operate switch on the DUT"), + TestStep("4a", "Operator operates switch (press briefly) associated with position 1 on the DUT then release switch from DUT", + """ + + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH does not receive ShortRelease event from the DUT + """), + TestStep("4b", "Operator does not operate switch on the DUT", + "TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 1 from the DUT"), + TestStep("5a", "Operator repeat step 4a 2 times quickly", + """ + + * Verify that the TH receives InitialPress(one, not more than one) event with NewPosition set to 1 from the DUT + * Verify that the TH does not receive ShortRelease event from the DUT + * Verify that the TH does not receive MultiPressOngoing event from the DUT + """), + TestStep("5b", "Operator does not operate switch on the DUT", + "Verify that the TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 2 from the DUT"), + TestStep("6a", "Operator repeat step 4a MultiPressMax + 1(see 2c of TC-SWTCH-2.1) times quickly", + """ + + * Verify that the TH receives InitialPress(one, not more than one) event with NewPosition set to 1 from the DUT + * Verify that the TH does not receive ShortRelease event from the DUT + * Verify that the TH does not receive MultiPressOngoing event from the DUT + """ + ), + TestStep("6b", "Operator does not operate switch on the DUT", + "Verify that the TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 0 from the DUT"), + TestStep("7a", "If the switch cluster does not implement the MomentarySwitchLongPress (MSL) feature, skip the remaining steps"), + TestStep("7b", "Set up subscription to all Switch cluster events"), + TestStep("8a", + """ + Operator operates switch in below sequence: + 1. Operator operates switch (press briefly) associated with position 1 on the DUT then release switch from DUT + 2. Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT immediately after the previous step + 3. Operator releases switch from the DUT + """, + """ + + * Verify that the TH receives InitialPress(one, not more than one) event with NewPosition set to 1 from the DUT + * Verify that the TH does not receive ShortRelease event from the DUT + * Verify that the TH does not receive MultiPressOngoing event from the DUT + * Verify that the TH does not receive LongPress event from the DUT + * Verify that the TH does not receive LongRelease event from the DUT + """), + TestStep("8b", "Operator does not operate switch on the DUT", + "TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 2 from the DUT"), + TestStep("9a", + """ + Operator operates switch in below sequence: + + 1. Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT + 2. Operator releases switch from the DUT + 3. Immediately after the previous step complete, Operator operates switch (press briefly) associated with position 1 on the DUT then release switch from DUT + """, + """ + + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives (one, not more than one) LongPress event with NewPosition set to 1 from the DUT + * Verify that the TH receives LongRelease event with PreviousPosition set to 1 from the DUT + * Verify that the TH receives InitialPress event with NewPosition set to 1 from the DUT + * Verify that the TH does not receive MultiPressOngoing event from the DUT + * Verify that the TH does not receive ShortRelease event from the DUT + + The events sequence from the subscription SHALL follow the same sequence as expressed above, in the exact order of events specified. + """), + TestStep("9b", "Operator does not operate switch on the DUT" + "Verify that the TH receives MultiPressComplete event with PreviousPosition set to 1 and TotalNumberOfPressesCounted set to 1 from the DUT"), + ] + + @staticmethod + def should_run_SWTCH_2_6(wildcard, endpoint): + msm = has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitchMultiPress) + asf = has_feature(Clusters.Switch, 0x20) + return msm(wildcard, endpoint) and asf(wildcard, endpoint) + + @per_endpoint_test(should_run_SWTCH_2_6) + async def test_TC_SWTCH_2_6(self): + # Commissioning - already done + self.step(1) + + cluster = Clusters.Switch + feature_map = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.FeatureMap) + has_msl_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitchLongPress) + multi_press_max = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.MultiPressMax) + + endpoint_id = self.matter_test_config.endpoint + pressed_position = 1 + + self.step(2) + event_listener = EventChangeCallback(cluster) + await event_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + + self.step(3) + self._ask_for_switch_idle() + + def test_multi_press_sequence(starting_step: str, count: int, short_long: bool = False): + step = starting_step + self.step(step) + + if short_long: + self._ask_for_multi_press_short_long(endpoint_id, pressed_position, + feature_map=feature_map, multi_press_max=multi_press_max) + else: + self._ask_for_multi_press(endpoint_id, number_of_presses=count, pressed_position=pressed_position, + feature_map=feature_map, multi_press_max=multi_press_max) + + event = event_listener.wait_for_event_report(cluster.Events.InitialPress) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on InitialEvent") + + step = step[:-1] + chr(ord(step[-1])+1) + self.step(step) + self._ask_for_switch_idle() + event = event_listener.wait_for_event_report(cluster.Events.MultiPressComplete) + asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on MultiPressComplete") + expected_count = 0 if count > multi_press_max else count + asserts.assert_equal(event.totalNumberOfPressesCounted, expected_count, "Unexpected count on MultiPressComplete") + + test_multi_press_sequence("4a", 1) + + test_multi_press_sequence("5a", 2) + + test_multi_press_sequence("6a", multi_press_max + 1) + + self.step("7a") + if not has_msl_feature: + self.skip_all_remaining_steps("7b") + + # subscription is already established + self.step("7b") + + test_multi_press_sequence("8a", 2, short_long=True) + + self.step("9a") + self._ask_for_multi_press_long_short(endpoint_id, pressed_position, feature_map) + + event = event_listener.wait_for_event_report(cluster.Events.InitialPress) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on InitialEvent") + event = event_listener.wait_for_event_report(cluster.Events.LongPress) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on LongPress") + event = event_listener.wait_for_event_report(cluster.Events.LongRelease) + asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on LongRelease") + if self._use_button_simulator: + # simulator can't sequence so we need to help it along here + self._send_multi_press_named_pipe_command(endpoint_id, number_of_presses=1, + pressed_position=1, feature_map=feature_map, multi_press_max=multi_press_max) + + event = event_listener.wait_for_event_report(cluster.Events.InitialPress) + asserts.assert_equal(event.newPosition, pressed_position, "Unexpected NewPosition on InitialEvent") + + # Verify that we don't receive the multi-press ongoing or short release by verifying that the next event in the sequence is the multi-press complete + self.step("9b") + self._ask_for_switch_idle() + event = event_listener.wait_for_event_report(cluster.Events.MultiPressComplete) + asserts.assert_equal(event.previousPosition, pressed_position, "Unexpected PreviousPosition on MultiPressComplete") + asserts.assert_equal(event.totalNumberOfPressesCounted, 1, "Unexpected count on MultiPressComplete") + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TC_WHM_1_2.py b/src/python_testing/TC_WHM_1_2.py new file mode 100644 index 00000000000000..aaa8d30002bb71 --- /dev/null +++ b/src/python_testing/TC_WHM_1_2.py @@ -0,0 +1,153 @@ +# +# 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. +# + +# === 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 --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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_WHM_1_2(MatterBaseTest): + + async def read_mode_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.WaterHeaterMode + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + def desc_TC_WHM_1_2(self) -> str: + return "[TC-WHM-1.2] Cluster attributes with DUT as Server" + + def steps_TC_WHM_1_2(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Read the SupportedModes attribute"), + TestStep(3, "Read the CurrentMode attribute"), + ] + return steps + + def pics_TC_WHM_1_2(self) -> list[str]: + pics = [ + "WHM.S", + ] + return pics + + @async_test_body + async def test_TC_WHM_1_2(self): + + endpoint = self.user_params.get("endpoint", 1) + + attributes = Clusters.WaterHeaterMode.Attributes + + self.step(1) + + self.step(2) + supported_modes = await self.read_mode_attribute_expect_success(endpoint=endpoint, attribute=attributes.SupportedModes) + asserts.assert_greater_equal(len(supported_modes), 2, + "SupportedModes must have at least 2 entries!") + asserts.assert_less_equal(len(supported_modes), 255, + "SupportedModes must have at most 255 entries!") + modes = set([m.mode for m in supported_modes]) + asserts.assert_equal(len(modes), len(supported_modes), + "SupportedModes must have unique mode values") + + labels = set([m.label for m in supported_modes]) + asserts.assert_equal(len(labels), len(supported_modes), + "SupportedModes must have unique mode label values") + + # common mode tags + commonTags = {0x0: 'Auto', + 0x1: 'Quick', + 0x2: 'Quiet', + 0x3: 'LowNoise', + 0x4: 'LowEnergy', + 0x5: 'Vacation', + 0x6: 'Min', + 0x7: 'Max', + 0x8: 'Night', + 0x9: 'Day'} + + # derived cluster defined tags + derivedTags = [tag.value for tag in Clusters.WaterHeaterMode.Enums.ModeTag] + + logging.info("Derived tags: %s" % derivedTags) + + # According to the Mode spec: + # At least one entry in the SupportedModes attribute SHALL include the Manual mode tag in the ModeTags field list. + # At least one entry in the SupportedModes attribute SHALL include the Off mode tag in the ModeTags field list. + # An entry in the SupportedModes attribute that includes one of an Off, Manual, or Timed tag + # SHALL NOT also include an additional instance of any one of these tag types. + off_present = 0 + manual_present = 0 + timed_present = 0 + + for m in supported_modes: + off_manual_timed_present_in_this_mode = 0 + for t in m.modeTags: + is_mfg = (0x8000 <= t.value and t.value <= 0xBFFF) + asserts.assert_true(t.value in commonTags.keys() or t.value in derivedTags or is_mfg, + "Found a SupportedModes entry with invalid mode tag value!") + if t.value == Clusters.WaterHeaterMode.Enums.ModeTag.kOff: + off_present += 1 + off_manual_timed_present_in_this_mode += 1 + logging.info( + "Found Off mode tag %s with tag value %s", m.mode, t.value) + + if t.value == Clusters.WaterHeaterMode.Enums.ModeTag.kManual: + manual_present += 1 + off_manual_timed_present_in_this_mode += 1 + logging.info( + "Found Manual mode tag %s with tag value %s", m.mode, t.value) + + if t.value == Clusters.WaterHeaterMode.Enums.ModeTag.kTimed: + timed_present += 1 + off_manual_timed_present_in_this_mode += 1 + logging.info( + "Found Timed mode tag %s with tag value %s", m.mode, t.value) + + asserts.assert_less_equal(off_manual_timed_present_in_this_mode, 1, + f"The supported mode ({m.mode}) should only include one of OFF, MANUAL or TIMED, but includes more than one.") + + asserts.assert_greater(off_present, 0, + "SupportedModes does not have an entry of Off(0x4000)") + asserts.assert_greater(manual_present, 0, + "SupportedModes does not have an entry of Manual(0x4001)") + + asserts.assert_less_equal(off_present, 1, + "SupportedModes cannot have more than one instance of Off(0x4000)") + asserts.assert_less_equal(manual_present, 1, + "SupportedModes cannot have more than one instance of Manual(0x4001)") + asserts.assert_less_equal(timed_present, 1, + "SupportedModes cannot have more than one instance of Timed(0x4002)") + + self.step(3) + current_mode = await self.read_mode_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentMode) + logging.info("CurrentMode: %s" % current_mode) + asserts.assert_true(current_mode in modes, + "CurrentMode is not a supported mode!") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_WHM_2_1.py b/src/python_testing/TC_WHM_2_1.py new file mode 100644 index 00000000000000..0d39d23cc2e1ea --- /dev/null +++ b/src/python_testing/TC_WHM_2_1.py @@ -0,0 +1,164 @@ +# +# 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. +# + +# 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 --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + + +class TC_WHM_2_1(MatterBaseTest): + + def __init__(self, *args): + super().__init__(*args) + self.endpoint = 0 + + def steps_TC_WHM_2_1(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Read the SupportedModes attribute"), + TestStep(3, "Read the CurrentMode attribute"), + TestStep(4, "Send ChangeToMode command with NewMode"), + TestStep(5, "Manually put the device in a state from which it will FAIL to transition"), + TestStep(6, "Read CurrentMode attribute"), + TestStep(7, "Send ChangeToMode command with NewMode"), + TestStep(8, "Read CurrentMode attribute"), + TestStep(9, "Manually put the device in a state from which it will SUCCESSFULLY transition"), + TestStep(10, "Read CurrentMode attribute"), + TestStep(11, "Send ChangeToMode command with NewMode"), + TestStep(12, "Read CurrentMode attribute"), + TestStep(13, "Send ChangeToMode command with NewMode set to an invalid mode"), + TestStep(14, "Read CurrentMode attribute"), + ] + return steps + + async def read_mode_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.WaterHeaterMode + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def send_change_to_mode_cmd(self, newMode) -> Clusters.Objects.WaterHeaterMode.Commands.ChangeToModeResponse: + ret = await self.send_single_cmd(cmd=Clusters.Objects.WaterHeaterMode.Commands.ChangeToMode(newMode=newMode), endpoint=self.endpoint) + asserts.assert_true(type_matches(ret, Clusters.Objects.WaterHeaterMode.Commands.ChangeToModeResponse), + "Unexpected return type for Water Heater Mode ChangeToMode") + return ret + + def pics_TC_WHM_2_1(self) -> list[str]: + return ["WHM.S"] + + @async_test_body + async def test_TC_WHM_2_1(self): + + # Valid modes. Only ModeManual referred to in this test + # ModeOff = 0 + ModeManual = 1 + # ModeTimed = 2 + + self.endpoint = self.matter_test_config.endpoint + + attributes = Clusters.WaterHeaterMode.Attributes + + self.step(1) + # Commission DUT - already done + + self.step(2) + + supported_modes = await self.read_mode_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.SupportedModes) + + logging.info(f"SupportedModes: {supported_modes}") + + asserts.assert_greater_equal(len(supported_modes), 2, + "SupportedModes must have at least two entries!") + + self.step(3) + + old_current_mode = await self.read_mode_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info(f"CurrentMode: {old_current_mode}") + + # pick a value that's not on the list of supported modes + modes = [m.mode for m in supported_modes] + invalid_mode = max(modes) + 1 + + self.step(4) + + ret = await self.send_change_to_mode_cmd(newMode=old_current_mode) + logging.info(f"ret.status {ret.status}") + asserts.assert_equal(ret.status, Status.Success, + "Changing the mode to the current mode should be a no-op") + + # Steps 5-9 are not performed as WHM.S.M.CAN_TEST_MODE_FAILURE is false + # TODO - see issue 34565 + self.step(5) + self.step(6) + self.step(7) + self.step(8) + self.step(9) + + self.step(10) + + old_current_mode = await self.read_mode_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info(f"CurrentMode: {old_current_mode}") + + self.step(11) + + ret = await self.send_change_to_mode_cmd(newMode=ModeManual) + asserts.assert_true(ret.status == Status.Success, + f"Changing to mode {ModeManual}must succeed due to the current state of the device") + + self.step(12) + + current_mode = await self.read_mode_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info(f"CurrentMode: {current_mode}") + + asserts.assert_true(current_mode == ModeManual, + "CurrentMode doesn't match the argument of the successful ChangeToMode command!") + + self.step(13) + + ret = await self.send_change_to_mode_cmd(newMode=invalid_mode) + logging.info(f"ret {ret}") + asserts.assert_true(ret.status == Status.Failure, + f"Attempt to change to invalid mode {invalid_mode} didn't fail as expected") + + self.step(14) + + current_mode = await self.read_mode_attribute_expect_success(endpoint=self.endpoint, attribute=attributes.CurrentMode) + + logging.info(f"CurrentMode: {current_mode}") + + asserts.assert_true(current_mode == ModeManual, + "CurrentMode changed after failed ChangeToMode command!") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TestSpecParsingSupport.py b/src/python_testing/TestSpecParsingSupport.py index fadd6a517a4531..0523ebbcd6a6df 100644 --- a/src/python_testing/TestSpecParsingSupport.py +++ b/src/python_testing/TestSpecParsingSupport.py @@ -235,20 +235,17 @@ def setup_class(self): def test_build_xml_override(self): # checks that the 1.3 spec (default) does not contain in-progress clusters and the TOT does tot_xml_clusters, problems = build_xml_clusters(PrebuiltDataModelDirectory.kMaster) - asserts.assert_greater(len(set(tot_xml_clusters.keys()) - set(self.spec_xml_clusters.keys())), + one_three_clusters, problems = build_xml_clusters(PrebuiltDataModelDirectory.k1_3) + asserts.assert_greater(len(set(tot_xml_clusters.keys()) - set(one_three_clusters.keys())), 0, "In progress dir does not contain any clusters not in 1.3") # only the pulse width modulation cluster was removed post 1.3 - asserts.assert_equal(set(self.spec_xml_clusters.keys()) - set(tot_xml_clusters.keys()), + asserts.assert_equal(set(one_three_clusters.keys()) - set(tot_xml_clusters.keys()), set([Clusters.PulseWidthModulation.id]), "There are some 1.3 clusters that are not included in the TOT spec") - str_path = str(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'data_model', '1.3', 'clusters')) + str_path = str(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'data_model', 'master', 'clusters')) string_override_check, problems = build_xml_clusters(str_path) asserts.assert_equal(string_override_check.keys(), self.spec_xml_clusters.keys(), "Mismatched cluster generation") - path = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'data_model', '1.3', 'clusters') - path_override_check, problems = build_xml_clusters(path) - asserts.assert_equal(path_override_check.keys(), self.spec_xml_clusters.keys(), "Mismatched cluster generation") - with asserts.assert_raises(SpecParsingException): build_xml_clusters("baddir") diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 3d235e49873a8a..273ffe94b5f821 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -33,7 +33,7 @@ from dataclasses import asdict as dataclass_asdict from dataclasses import dataclass, field from datetime import datetime, timedelta, timezone -from enum import Enum +from enum import Enum, IntFlag from functools import partial from typing import Any, List, Optional, Tuple @@ -257,11 +257,11 @@ def __call__(self, res: EventReadResult, transaction: SubscriptionTransaction): f'Got subscription report for event on cluster {self._expected_cluster}: {res.Data}') self._q.put(res) - def wait_for_event_report(self, expected_event: ClusterObjects.ClusterEvent, timeoutS: int = 10): - """This function allows a test script to block waiting for the specific event to arrive with a timeout - (specified in seconds). It returns the event data so that the values can be checked.""" + def wait_for_event_report(self, expected_event: ClusterObjects.ClusterEvent, timeout_sec: float = 10.0) -> Any: + """This function allows a test script to block waiting for the specific event to be the next event + to arrive within a timeout (specified in seconds). It returns the event data so that the values can be checked.""" try: - res = self._q.get(block=True, timeout=timeoutS) + res = self._q.get(block=True, timeout=timeout_sec) except queue.Empty: asserts.fail("Failed to receive a report for the event {}".format(expected_event)) @@ -269,16 +269,30 @@ def wait_for_event_report(self, expected_event: ClusterObjects.ClusterEvent, tim asserts.assert_equal(res.Header.EventId, expected_event.event_id, "Expected event ID not found in event report") return res.Data - def wait_for_event_expect_no_report(self, timeoutS: int = 10): - """This function succceeds/returns if an event does not arrive within the timeout specified in seconds. - If an event does arrive, an assert is called.""" + def wait_for_event_expect_no_report(self, timeout_sec: float = 10.0): + """This function returns if an event does not arrive within the timeout specified in seconds. + If any event does arrive, an assert failure occurs.""" try: - res = self._q.get(block=True, timeout=timeoutS) + res = self._q.get(block=True, timeout=timeout_sec) except queue.Empty: return asserts.fail(f"Event reported when not expected {res}") + def get_last_event(self) -> Optional[Any]: + """Flush entire queue, returning last (newest) event only.""" + last_event: Optional[Any] = None + while True: + try: + last_event = self._q.get(block=False) + except queue.Empty: + return last_event + + def flush_events(self) -> None: + """Flush entire queue, returning nothing.""" + _ = self.get_last_event() + return + @property def event_queue(self) -> queue.Queue: return self._q @@ -327,14 +341,19 @@ class AttributeValue: class ClusterAttributeChangeAccumulator: def __init__(self, expected_cluster: ClusterObjects.Cluster): - self._q = queue.Queue() self._expected_cluster = expected_cluster self._subscription = None + self.reset() + + def reset(self): self._attribute_report_counts = {} - attrs = [cls for name, cls in inspect.getmembers(expected_cluster.Attributes) if inspect.isclass( + attrs = [cls for name, cls in inspect.getmembers(self._expected_cluster.Attributes) if inspect.isclass( cls) and issubclass(cls, ClusterObjects.ClusterAttributeDescriptor)] + self._attribute_reports = {} for a in attrs: self._attribute_report_counts[a] = 0 + self._attribute_reports[a] = [] + self._q = queue.Queue() async def start(self, dev_ctrl, node_id: int, endpoint: int, fabric_filtered: bool = False, min_interval_sec: int = 0, max_interval_sec: int = 5) -> Any: """This starts a subscription for attributes on the specified node_id and endpoint. The cluster is specified when the class instance is created.""" @@ -358,6 +377,7 @@ def __call__(self, path: TypedAttributePath, transaction: SubscriptionTransactio logging.info(f"Got subscription report for {path.AttributeType}: {data}") self._q.put(value) self._attribute_report_counts[path.AttributeType] += 1 + self._attribute_reports[path.AttributeType].append(value) @property def attribute_queue(self) -> queue.Queue: @@ -367,6 +387,10 @@ def attribute_queue(self) -> queue.Queue: def attribute_report_counts(self) -> dict[ClusterObjects.ClusterAttributeDescriptor, int]: return self._attribute_report_counts + @property + def attribute_reports(self) -> dict[ClusterObjects.ClusterAttributeDescriptor, AttributeValue]: + return self._attribute_reports + class InternalTestRunnerHooks(TestRunnerHooks): @@ -1093,7 +1117,7 @@ def mark_current_step_skipped(self): steps = self.get_test_steps(self.current_test_info.name) if self.current_step_index == 0: asserts.fail("Script error: mark_current_step_skipped cannot be called before step()") - num = steps[self.current_step_index-1].test_plan_number + num = steps[self.current_step_index - 1].test_plan_number except KeyError: num = self.current_step_index @@ -1730,6 +1754,38 @@ def has_attribute(attribute: ClusterObjects.ClusterAttributeDescriptor) -> Endpo return partial(_has_attribute, attribute=attribute) +def _has_feature(wildcard, endpoint, cluster: ClusterObjects.ClusterObjectDescriptor, feature: IntFlag) -> bool: + try: + feature_map = wildcard.attributes[endpoint][cluster][cluster.Attributes.FeatureMap] + return (feature & feature_map) != 0 + except KeyError: + return False + + +def has_feature(cluster: ClusterObjects.ClusterObjectDescriptor, feature: IntFlag) -> EndpointCheckFunction: + """ EndpointCheckFunction that can be passed as a parameter to the per_endpoint_test decorator. + + Use this function with the per_endpoint_test decorator to run this test on all endpoints with + the specified feature. For example, given a device with the following conformance + + EP0: cluster A, B, C + EP1: cluster D with feature F0 + EP2, cluster D with feature F0 + EP3, cluster D without feature F0 + + And the following test specification: + @per_endpoint_test(has_feature(Clusters.D.Bitmaps.Feature.F0)) + test_mytest(self): + ... + + The test would be run on endpoint 1 and on endpoint 2. + + If the cluster is not found on any endpoint the decorator will call the on_skip function to + notify the test harness that the test is not applicable to this node and the test will not be run. + """ + return partial(_has_feature, cluster=cluster, feature=feature) + + async def get_accepted_endpoints_for_test(self: MatterBaseTest, accept_function: EndpointCheckFunction) -> list[uint]: """ Helper function for the per_endpoint_test decorator. @@ -1773,7 +1829,7 @@ def per_endpoint_test(accept_function: EndpointCheckFunction): def per_endpoint_test_internal(body): def per_endpoint_runner(self: MatterBaseTest, *args, **kwargs): asserts.assert_false(self.get_test_pics(self.current_test_info.name), "pics_ method supplied for per_endpoint_test.") - runner_with_timeout = asyncio.wait_for(get_accepted_endpoints_for_test(self, accept_function), timeout=5) + runner_with_timeout = asyncio.wait_for(get_accepted_endpoints_for_test(self, accept_function), timeout=30) endpoints = asyncio.run(runner_with_timeout) if not endpoints: logging.info("No matching endpoints found - skipping test") diff --git a/src/python_testing/spec_parsing_support.py b/src/python_testing/spec_parsing_support.py index e106167e7b5487..1b8e29c4cf33cf 100644 --- a/src/python_testing/spec_parsing_support.py +++ b/src/python_testing/spec_parsing_support.py @@ -517,7 +517,7 @@ def _get_data_model_directory(data_model_directory: typing.Union[PrebuiltDataMod return data_model_directory -def build_xml_clusters(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.k1_3) -> tuple[dict[uint, XmlCluster], list[ProblemNotice]]: +def build_xml_clusters(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.kMaster) -> tuple[dict[uint, XmlCluster], list[ProblemNotice]]: dir = _get_data_model_directory(data_model_directory, DataModelLevel.kCluster) clusters: dict[int, XmlCluster] = {} @@ -743,7 +743,7 @@ def parse_single_device_type(root: ElementTree.Element) -> tuple[list[ProblemNot return device_types, problems -def build_xml_device_types(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.k1_3) -> tuple[dict[int, XmlDeviceType], list[ProblemNotice]]: +def build_xml_device_types(data_model_directory: typing.Union[PrebuiltDataModelDirectory, str] = PrebuiltDataModelDirectory.kMaster) -> tuple[dict[int, XmlDeviceType], list[ProblemNotice]]: dir = _get_data_model_directory(data_model_directory, DataModelLevel.kDeviceType) device_types: dict[int, XmlDeviceType] = {} problems = [] diff --git a/src/python_testing/test_plan_support.py b/src/python_testing/test_plan_support.py index 1acb8576bdb15c..3e332e143203b8 100644 --- a/src/python_testing/test_plan_support.py +++ b/src/python_testing/test_plan_support.py @@ -76,3 +76,7 @@ def remove_fabric(index_var: str, controller: str): def verify_commissioning_successful() -> str: return 'Verify the commissioning is successful.' + + +def if_feature_supported(feature: str) -> str: + return f"If the {feature} is supported" diff --git a/src/python_testing/test_testing/MockTestRunner.py b/src/python_testing/test_testing/MockTestRunner.py index c8febc93381fdc..024228db7cd035 100644 --- a/src/python_testing/test_testing/MockTestRunner.py +++ b/src/python_testing/test_testing/MockTestRunner.py @@ -38,10 +38,12 @@ async def __call__(self, *args, **kwargs): class MockTestRunner(): - def __init__(self, filename: str, classname: str, test: str, endpoint: int = 0, pics: dict[str, bool] = None): + def __init__(self, filename: str, classname: str, test: str, endpoint: int = 0, pics: dict[str, bool] = None, paa_trust_store_path=None): self.test = test self.endpoint = endpoint self.pics = pics + self.kvs_storage = 'kvs_admin.json' + self.paa_path = paa_trust_store_path self.set_test(filename, classname, test) self.stack = MatterStackState(self.config) self.default_controller = self.stack.certificate_authorities[0].adminList[0].NewController( @@ -60,6 +62,8 @@ def set_test_config(self, test_config: MatterTestConfig = MatterTestConfig()): self.config = test_config self.config.tests = [self.test] self.config.endpoint = self.endpoint + self.config.storage_path = self.kvs_storage + self.config.paa_trust_store_path = self.paa_path if not self.config.dut_node_ids: self.config.dut_node_ids = [1] if self.pics: diff --git a/src/python_testing/test_testing/TestDecorators.py b/src/python_testing/test_testing/TestDecorators.py index 60a75bfca466ef..2ce418d6c5e43a 100644 --- a/src/python_testing/test_testing/TestDecorators.py +++ b/src/python_testing/test_testing/TestDecorators.py @@ -30,15 +30,14 @@ import chip.clusters as Clusters from chip.clusters import Attribute -from chip.clusters import ClusterObjects as ClusterObjects try: from matter_testing_support import (MatterBaseTest, async_test_body, get_accepted_endpoints_for_test, has_attribute, - has_cluster, per_endpoint_test, per_node_test) + has_cluster, has_feature, per_endpoint_test, per_node_test) except ImportError: sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) from matter_testing_support import (MatterBaseTest, async_test_body, get_accepted_endpoints_for_test, has_attribute, - has_cluster, per_endpoint_test, per_node_test) + has_cluster, has_feature, per_endpoint_test, per_node_test) from typing import Optional @@ -204,6 +203,16 @@ async def test_endpoint_attribute_supported_cluster_no(self): async def test_endpoint_attribute_unsupported_cluster_no(self): pass + # This test should be run once per endpoint + @per_endpoint_test(has_feature(Clusters.OnOff, Clusters.OnOff.Bitmaps.Feature.kLighting)) + async def test_endpoint_feature_yes(self): + pass + + # This test should be skipped since this attribute is part of an unsupported cluster + @per_endpoint_test(has_feature(Clusters.TimeSynchronization, Clusters.TimeSynchronization.Bitmaps.Feature.kNTPClient)) + async def test_endpoint_feature_unsupported_cluster_no(self): + pass + # This test should be run since both are present @per_endpoint_test(has_attribute(Clusters.OnOff.Attributes.OnOff) and has_cluster(Clusters.OnOff)) async def test_endpoint_boolean_yes(self): @@ -292,6 +301,8 @@ def check_skipped(test_name: str): check_once_per_endpoint('test_endpoint_attribute_yes') check_skipped('test_endpoint_attribute_supported_cluster_no') check_skipped('test_endpoint_attribute_unsupported_cluster_no') + check_once_per_endpoint('test_endpoint_feature_yes') + check_skipped('test_endpoint_feature_unsupported_cluster_no') check_once_per_endpoint('test_endpoint_boolean_yes') check_skipped('test_endpoint_boolean_no') diff --git a/src/python_testing/test_testing/test_TC_CCNTL_2_2.py b/src/python_testing/test_testing/test_TC_CCNTL_2_2.py new file mode 100644 index 00000000000000..ba884bc48f9ee4 --- /dev/null +++ b/src/python_testing/test_testing/test_TC_CCNTL_2_2.py @@ -0,0 +1,191 @@ +#!/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 base64 +import click +import os +import pathlib +import sys +import typing + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.clusters import Attribute +from chip.interaction_model import InteractionModelError, Status +from MockTestRunner import AsyncMock, MockTestRunner + +try: + from matter_testing_support import MatterTestConfig, get_default_paa_trust_store, run_tests_no_exit +except ImportError: + sys.path.append(os.path.abspath( + os.path.join(os.path.dirname(__file__), '..'))) + from matter_testing_support import MatterTestConfig, get_default_paa_trust_store, run_tests_no_exit + +invoke_call_count = 0 +event_call_count = 0 + + +def dynamic_invoke_return(*args, **argv): + ''' Returns the response to a mocked SendCommand call. + ''' + global invoke_call_count + invoke_call_count += 1 + + # passcode 20202024 + reverse_open = Clusters.CommissionerControl.Commands.ReverseOpenCommissioningWindow(commissioningTimeout=30, + PAKEPasscodeVerifier=b"+w1qZQR05Zn0bc2LDyNaDAhsrhDS5iRHPTN10+EmNx8E2OpIPC4SjWRDQVOgqcbnXdYMlpiZ168xLBqn1fx9659gGK/7f9Yc6GxpoJH8kwAUYAYyLGsYeEBt1kL6kpXjgA==", + discriminator=2222, iterations=10000, salt=base64.b64encode(bytes('SaltyMcSalterson', 'utf-8'))) + + print(f'invoke call {invoke_call_count}') + if invoke_call_count == 1: # Commission node with no prior request, return failure - step 5 + raise InteractionModelError(status=Status.Failure) + elif invoke_call_count == 2: # Commission node over pase - return unsupported access - step 7 + raise InteractionModelError(status=Status.UnsupportedAccess) + elif invoke_call_count == 3: # request commissioning approval over pase - return unsupported access - step 8 + raise InteractionModelError(status=Status.UnsupportedAccess) + elif invoke_call_count == 4: # good RevokeCommissioning over CASE with bad vid - step 9 + return None + elif invoke_call_count == 5: # good RequestCommissioningApproval over CASE with bad vid - step 10 + return None + elif invoke_call_count == 6: # CommissionNode with bad request id - step 14 + raise InteractionModelError(status=Status.Failure) + elif invoke_call_count == 7: # CommissionNode with bad timeout (low) - step 15 + raise InteractionModelError(status=Status.Failure) + elif invoke_call_count == 8: # CommissionNode with bad timeout (high) - step 16 + raise InteractionModelError(status=Status.Failure) + elif invoke_call_count == 9: # CommissionNode - step 17 + # passcode 20202024 + return reverse_open + elif invoke_call_count == 10: # RequestCommissioningApproval with good vid - step 22 + return None + elif invoke_call_count == 11: # CommissionNode - step 25 + # passcode 20202024 + return reverse_open + else: + raise InteractionModelError(Status.Failure) + + +def dynamic_event_return(*args, **argv): + ''' Returns the response to a mocked ReadEvent call. + ''' + global event_call_count + event_call_count += 1 + + if event_call_count == 1: # reading events, start empty - no events + return [] + elif event_call_count == 2: # read event with filter - expect empty + return [] + elif event_call_count == 3: # returned event + header = Attribute.EventHeader(EndpointId=0, ClusterId=Clusters.CommissionerControl.id, + EventId=Clusters.CommissionerControl.Events.CommissioningRequestResult.event_id, EventNumber=1) + data = Clusters.CommissionerControl.Events.CommissioningRequestResult( + requestId=0x1234567887654321, clientNodeId=112233, statusCode=0) + result = Attribute.EventReadResult(Header=header, Status=Status.Success, Data=data) + return [result] + elif event_call_count == 4: # returned event with new request + header = Attribute.EventHeader(EndpointId=0, ClusterId=Clusters.CommissionerControl.id, + EventId=Clusters.CommissionerControl.Events.CommissioningRequestResult.event_id, EventNumber=1) + data = Clusters.CommissionerControl.Events.CommissioningRequestResult( + requestId=0x1234567812345678, clientNodeId=112233, statusCode=0) + result = Attribute.EventReadResult(Header=header, Status=Status.Success, Data=data) + return [result] + else: + raise InteractionModelError(Status.Failure) + + +def wildcard() -> Attribute.AsyncReadTransaction.ReadResponse: + ''' Returns the response to a wildcard read. + For this test, we just need descriptors and a few attributes + Tree + EP1 (Aggregator): Descriptor + - EP2 (Bridged Node): Descriptor, Bridged Device Basic Information, Ecosystem Information + ''' + cc = Clusters.CommissionerControl + ei = Clusters.EcosystemInformation + desc = Clusters.Descriptor + bdbi = Clusters.BridgedDeviceBasicInformation + + # EP1 is aggregator device type with a commissioner control cluster + # children - EP2 type bridged node endpoint, ecosystem information, bridged device basic information. Should also have and admin commissioning, but I don't need it for this test. + desc_ep1 = {desc.Attributes.PartsList: [2], desc.Attributes.ServerList: [ + cc.id], desc.Attributes.DeviceTypeList: [desc.Structs.DeviceTypeStruct(deviceType=0x000E, revision=2)]} + desc_ep2 = {desc.Attributes.ServerList: [bdbi.id, ei.id], desc.Attributes.DeviceTypeList: [ + desc.Structs.DeviceTypeStruct(deviceType=0x0013, revision=3)]} + + # I'm not filling anything in here, because I don't care. I just care that the cluster exists. + ei_attrs = {ei.Attributes.AttributeList: [ei.Attributes.DeviceDirectory.attribute_id, + ei.Attributes.LocationDirectory.attribute_id], ei.Attributes.DeviceDirectory: [], ei.Attributes.LocationDirectory: []} + + # This cluster just needs to exist, so I'm just going to throw on the mandatory items for now. + bdbi_attrs = {bdbi.Attributes.AttributeList: [bdbi.Attributes.Reachable.attribute_id, + bdbi.Attributes.UniqueID.attribute_id], bdbi.Attributes.Reachable: True, bdbi.Attributes.UniqueID: 'something'} + + cc_attrs = {cc.Attributes.AttributeList: [cc.Attributes.SupportedDeviceCategories], cc.Attributes.AcceptedCommandList: [cc.Commands.RequestCommissioningApproval, cc.Commands.CommissionNode], + cc.Attributes.GeneratedCommandList: [cc.Commands.RequestCommissioningApproval], cc.Attributes.SupportedDeviceCategories: 1} + + resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) + resp.attributes = {1: {desc: desc_ep1, cc: cc_attrs}, 2: {desc: desc_ep2, ei: ei_attrs, bdbi: bdbi_attrs}} + return resp + + +class MyMock(MockTestRunner): + def run_test_with_mock(self, dynamic_invoke_return: typing.Callable, dynamic_event_return: typing.Callable, read_cache: Attribute.AsyncReadTransaction.ReadResponse, hooks=None): + ''' Run the test using the Mocked versions of Read, SendCommand, OpenCommissioningWindow, FindOrEstablishPASESession and ReadEvent + dynamic_invoke_return: Callable function that returns the result of a SendCommand call + Function should return one of + - command response for commands with responses + - None for commands with success results + - raise InteractionModelError for error results + dynamic_event_return: Callable function that returns the result of a ReadEvent call + Function should return one of + - list of EventReadResult for successful reads + - raise InteractionModelError for error results + read_cache : Response to a Read call. For this test, this will be the wildcard read of all teh attributes + hooks : Test harness hook object if desired. + ''' + self.default_controller.Read = AsyncMock(return_value=read_cache) + self.default_controller.SendCommand = AsyncMock(return_value=None, side_effect=dynamic_invoke_return) + # It doesn't actually matter what we return here because I'm going to catch the next pase session connection anyway + params = ChipDeviceCtrl.CommissioningParameters(setupPinCode=0, setupManualCode='', setupQRCode='') + self.default_controller.OpenCommissioningWindow = AsyncMock(return_value=params) + self.default_controller.FindOrEstablishPASESession = AsyncMock(return_value=None) + self.default_controller.ReadEvent = AsyncMock(return_value=[], side_effect=dynamic_event_return) + + return run_tests_no_exit(self.test_class, self.config, hooks, self.default_controller, self.stack) + + +@click.command() +@click.argument('th_server_app', type=click.Path(exists=True)) +def main(th_server_app: str): + root = os.path.abspath(os.path.join(pathlib.Path(__file__).resolve().parent, '..', '..', '..')) + print(f'root = {root}') + paa_path = get_default_paa_trust_store(root) + print(f'paa = {paa_path}') + + pics = {"PICS_SDK_CI_ONLY": True} + test_runner = MyMock('TC_CCTRL_2_2', 'TC_CCTRL_2_2', 'test_TC_CCTRL_2_2', 1, paa_trust_store_path=paa_path, pics=pics) + config = MatterTestConfig() + config.user_params = {'th_server_app_path': th_server_app} + test_runner.set_test_config(config) + + test_runner.run_test_with_mock(dynamic_invoke_return, dynamic_event_return, wildcard()) + test_runner.Shutdown() + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/setup_payload/SetupPayload.cpp b/src/setup_payload/SetupPayload.cpp index 1ef4795d571e4d..9683da21f8a7f9 100644 --- a/src/setup_payload/SetupPayload.cpp +++ b/src/setup_payload/SetupPayload.cpp @@ -62,7 +62,7 @@ bool PayloadContents::isValidQRCodePayload(ValidationMode mode) const if (mode == ValidationMode::kProduce) { chip::RendezvousInformationFlags valid(RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kOnNetwork, - RendezvousInformationFlag::kSoftAP); + RendezvousInformationFlag::kSoftAP, RendezvousInformationFlag::kWiFiPAF); VerifyOrReturnValue(rendezvousInformation.Value().HasOnly(valid), false); } diff --git a/src/setup_payload/SetupPayload.h b/src/setup_payload/SetupPayload.h index dc67206dd51867..3d5d101fbf4c6e 100644 --- a/src/setup_payload/SetupPayload.h +++ b/src/setup_payload/SetupPayload.h @@ -101,6 +101,7 @@ enum class RendezvousInformationFlag : uint8_t kSoftAP = 1 << 0, ///< Device supports Wi-Fi softAP kBLE = 1 << 1, ///< Device supports BLE kOnNetwork = 1 << 2, ///< Device supports Setup on network + kWiFiPAF = 1 << 3, ///< Device supports Wi-Fi Public Action Frame for discovery }; using RendezvousInformationFlags = chip::BitFlags; diff --git a/src/setup_payload/tests/BUILD.gn b/src/setup_payload/tests/BUILD.gn index c3013c94f5acb5..75cdb8a71b0ad3 100644 --- a/src/setup_payload/tests/BUILD.gn +++ b/src/setup_payload/tests/BUILD.gn @@ -17,6 +17,7 @@ import("//build_overrides/chip.gni") import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/chip_test_suite.gni") +import("${chip_root}/build/chip/fuzz_test.gni") chip_test_suite("tests") { output_name = "libSetupPayloadTests" @@ -38,3 +39,20 @@ chip_test_suite("tests") { "${chip_root}/src/setup_payload", ] } + +if (enable_fuzz_test_targets) { + chip_fuzz_target("fuzz-setup-payload-base38") { + sources = [ "FuzzBase38.cpp" ] + public_deps = [ + "${chip_root}/src/platform/logging:stdio", + "${chip_root}/src/setup_payload", + ] + } + chip_fuzz_target("fuzz-setup-payload-base38-decode") { + sources = [ "FuzzBase38Decode.cpp" ] + public_deps = [ + "${chip_root}/src/platform/logging:stdio", + "${chip_root}/src/setup_payload", + ] + } +} diff --git a/src/setup_payload/tests/FuzzBase38.cpp b/src/setup_payload/tests/FuzzBase38.cpp new file mode 100644 index 00000000000000..478b2a0fc1d9dd --- /dev/null +++ b/src/setup_payload/tests/FuzzBase38.cpp @@ -0,0 +1,63 @@ +#include +#include +#include +#include +#include + +#include +#include + +using namespace chip; + +/** + * @file + * This file describes a base38 roundtrip Fuzzer. + * It starts by encoding the fuzzing value passed + * in Base38. The value encoded will then be decoded. + * The fuzzer verify that the decoded value is the same + * as the one in input. + */ + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t * data, size_t len) +{ + size_t outputSizeNeeded = base38EncodedLength(len); + const size_t kMaxOutputSize = 512; + + if (outputSizeNeeded > kMaxOutputSize) + { + return 0; + } + + ByteSpan span(data, len); + char encodedBuf[kMaxOutputSize]; + MutableCharSpan encodedSpan(encodedBuf); + CHIP_ERROR encodingError = base38Encode(span, encodedSpan); + + if (encodingError != CHIP_NO_ERROR) + { + __builtin_trap(); + } + + std::string base38EncodedString(encodedSpan.data(), encodedSpan.size()); + + std::vector decodedData; + CHIP_ERROR decodingError = base38Decode(base38EncodedString, decodedData); + + if (decodingError == CHIP_NO_ERROR) + { + if (decodedData.size() != len) + { + __builtin_trap(); + } + + if (memcmp(data, decodedData.data(), len) != 0) + { + __builtin_trap(); + } + } + else + { + __builtin_trap(); + } + return 0; +} diff --git a/src/setup_payload/tests/FuzzBase38Decode.cpp b/src/setup_payload/tests/FuzzBase38Decode.cpp new file mode 100644 index 00000000000000..317473370230c7 --- /dev/null +++ b/src/setup_payload/tests/FuzzBase38Decode.cpp @@ -0,0 +1,24 @@ +#include +#include +#include + +#include + +using namespace chip; + +/** + * @file + * This file describes a Fuzzer for decoding base38 encoded strings. + */ + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t * data, size_t len) +{ + std::string base38EncodedString(reinterpret_cast(data), len); + std::vector decodedData; + + // Ignoring return value, because in general the data is garbage and won't decode properly. + // We're just testing that the decoder does not crash on the fuzzer-generated inputs. + chip::base38Decode(base38EncodedString, decodedData); + + return 0; +} diff --git a/src/setup_payload/tests/TestQRCode.cpp b/src/setup_payload/tests/TestQRCode.cpp index 44c50d9e1e8f5b..e5d68227c2956e 100644 --- a/src/setup_payload/tests/TestQRCode.cpp +++ b/src/setup_payload/tests/TestQRCode.cpp @@ -53,6 +53,9 @@ TEST(TestQRCode, TestRendezvousFlags) inPayload.rendezvousInformation.SetValue(RendezvousInformationFlag::kOnNetwork); EXPECT_TRUE(CheckWriteRead(inPayload)); + inPayload.rendezvousInformation.SetValue(RendezvousInformationFlag::kWiFiPAF); + EXPECT_TRUE(CheckWriteRead(inPayload)); + inPayload.rendezvousInformation.SetValue( RendezvousInformationFlags(RendezvousInformationFlag::kSoftAP, RendezvousInformationFlag::kOnNetwork)); EXPECT_TRUE(CheckWriteRead(inPayload)); @@ -61,9 +64,26 @@ TEST(TestQRCode, TestRendezvousFlags) RendezvousInformationFlags(RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kOnNetwork)); EXPECT_TRUE(CheckWriteRead(inPayload)); + inPayload.rendezvousInformation.SetValue( + RendezvousInformationFlags(RendezvousInformationFlag::kWiFiPAF, RendezvousInformationFlag::kOnNetwork)); + EXPECT_TRUE(CheckWriteRead(inPayload)); + inPayload.rendezvousInformation.SetValue(RendezvousInformationFlags( RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kSoftAP, RendezvousInformationFlag::kOnNetwork)); EXPECT_TRUE(CheckWriteRead(inPayload)); + + inPayload.rendezvousInformation.SetValue(RendezvousInformationFlags( + RendezvousInformationFlag::kWiFiPAF, RendezvousInformationFlag::kSoftAP, RendezvousInformationFlag::kOnNetwork)); + EXPECT_TRUE(CheckWriteRead(inPayload)); + + inPayload.rendezvousInformation.SetValue(RendezvousInformationFlags( + RendezvousInformationFlag::kWiFiPAF, RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kOnNetwork)); + EXPECT_TRUE(CheckWriteRead(inPayload)); + + inPayload.rendezvousInformation.SetValue( + RendezvousInformationFlags(RendezvousInformationFlag::kWiFiPAF, RendezvousInformationFlag::kBLE, + RendezvousInformationFlag::kSoftAP, RendezvousInformationFlag::kOnNetwork)); + EXPECT_TRUE(CheckWriteRead(inPayload)); } TEST(TestQRCode, TestCommissioningFlow) @@ -88,8 +108,9 @@ TEST(TestQRCode, TestMaximumValues) inPayload.vendorID = 0xFFFF; inPayload.productID = 0xFFFF; inPayload.commissioningFlow = CommissioningFlow::kCustom; - inPayload.rendezvousInformation.SetValue(RendezvousInformationFlags( - RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kSoftAP, RendezvousInformationFlag::kOnNetwork)); + inPayload.rendezvousInformation.SetValue( + RendezvousInformationFlags(RendezvousInformationFlag::kWiFiPAF, RendezvousInformationFlag::kBLE, + RendezvousInformationFlag::kSoftAP, RendezvousInformationFlag::kOnNetwork)); inPayload.discriminator.SetLongValue(static_cast((1 << kPayloadDiscriminatorFieldLengthInBits) - 1)); inPayload.setUpPINCode = static_cast((1 << kSetupPINCodeFieldLengthInBits) - 1); @@ -303,9 +324,10 @@ TEST(TestQRCode, TestSetupPayloadVerify) EXPECT_EQ(test_payload.isValidQRCodePayload(), false); // test invalid rendezvousInformation - test_payload = payload; - RendezvousInformationFlags invalid = RendezvousInformationFlags( - RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kSoftAP, RendezvousInformationFlag::kOnNetwork); + test_payload = payload; + RendezvousInformationFlags invalid = + RendezvousInformationFlags(RendezvousInformationFlag::kBLE, RendezvousInformationFlag::kSoftAP, + RendezvousInformationFlag::kOnNetwork, RendezvousInformationFlag::kWiFiPAF); invalid.SetRaw(static_cast(invalid.Raw() + 1)); test_payload.rendezvousInformation.SetValue(invalid); EXPECT_EQ(test_payload.isValidQRCodePayload(), false); diff --git a/src/transport/raw/BUILD.gn b/src/transport/raw/BUILD.gn index 3e8d3d4761dca3..f5593c012769e7 100644 --- a/src/transport/raw/BUILD.gn +++ b/src/transport/raw/BUILD.gn @@ -15,6 +15,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/ble/ble.gni") import("${chip_root}/src/inet/inet.gni") +import("${chip_root}/src/platform/device.gni") static_library("raw") { output_name = "libRawTransport" @@ -44,6 +45,12 @@ static_library("raw") { "BLE.h", ] } + if (chip_device_config_enable_wifipaf) { + sources += [ + "WiFiPAF.cpp", + "WiFiPAF.h", + ] + } cflags = [ "-Wconversion" ] diff --git a/src/transport/raw/PeerAddress.h b/src/transport/raw/PeerAddress.h index 64588bc64c062f..896648f76f537a 100644 --- a/src/transport/raw/PeerAddress.h +++ b/src/transport/raw/PeerAddress.h @@ -53,6 +53,7 @@ enum class Type : uint8_t kUdp, kBle, kTcp, + kWiFiPAF, }; /** @@ -64,6 +65,7 @@ class PeerAddress PeerAddress() : mIPAddress(Inet::IPAddress::Any), mTransportType(Type::kUndefined) {} PeerAddress(const Inet::IPAddress & addr, Type type) : mIPAddress(addr), mTransportType(type) {} PeerAddress(Type type) : mTransportType(type) {} + PeerAddress(Type type, NodeId remoteId) : mTransportType(type), mRemoteId(remoteId) {} PeerAddress(PeerAddress &&) = default; PeerAddress(const PeerAddress &) = default; @@ -77,6 +79,8 @@ class PeerAddress return *this; } + NodeId GetRemoteId() const { return mRemoteId; } + Type GetTransportType() const { return mTransportType; } PeerAddress & SetTransportType(Type type) { @@ -167,6 +171,9 @@ class PeerAddress #endif snprintf(buf, bufSize, "TCP:[%s%s]:%d", ip_addr, interface, mPort); break; + case Type::kWiFiPAF: + snprintf(buf, bufSize, "Wi-Fi PAF"); + break; case Type::kBle: // Note that BLE does not currently use any specific address. snprintf(buf, bufSize, "BLE"); @@ -209,6 +216,8 @@ class PeerAddress return TCP(addr).SetPort(port).SetInterface(interface); } + static PeerAddress WiFiPAF(NodeId remoteId) { return PeerAddress(Type::kWiFiPAF); } + static PeerAddress Multicast(chip::FabricId fabric, chip::GroupId group) { constexpr uint8_t scope = 0x05; // Site-Local @@ -237,6 +246,7 @@ class PeerAddress Type mTransportType = Type::kUndefined; uint16_t mPort = CHIP_PORT; ///< Relevant for UDP data sending. Inet::InterfaceId mInterface = Inet::InterfaceId::Null(); + NodeId mRemoteId = 0; }; } // namespace Transport diff --git a/src/transport/raw/TCP.cpp b/src/transport/raw/TCP.cpp index 8a15f754d54027..b73540d7956f29 100644 --- a/src/transport/raw/TCP.cpp +++ b/src/transport/raw/TCP.cpp @@ -578,6 +578,9 @@ void TCPBase::HandleIncomingConnection(Inet::TCPEndPoint * listenEndPoint, Inet: tcp->mUsedEndPointCount++; activeConnection->mConnectionState = TCPState::kConnected; + // Set the TCPKeepalive configurations on the received connection + endPoint->EnableKeepAlive(activeConnection->mTCPKeepAliveIntervalSecs, activeConnection->mTCPMaxNumKeepAliveProbes); + char addrStr[Transport::PeerAddress::kMaxToStringSize]; peerAddress.ToString(addrStr); ChipLogProgress(Inet, "Incoming connection established with peer at %s.", addrStr); diff --git a/src/transport/raw/WiFiPAF.cpp b/src/transport/raw/WiFiPAF.cpp new file mode 100644 index 00000000000000..97b465dd261e9b --- /dev/null +++ b/src/transport/raw/WiFiPAF.cpp @@ -0,0 +1,113 @@ +/* + * + * 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. + */ + +/** + * @file + * This file implements the Matter Connection object that maintains a Wi-Fi PAF connection + * + */ + +#include +#include +#include +#include +#include +#include + +using namespace chip::System; + +namespace chip { +namespace Transport { + +WiFiPAFBase::~WiFiPAFBase() +{ + ClearState(); +} + +void WiFiPAFBase::ClearState() +{ + mState = State::kNotReady; +} + +CHIP_ERROR WiFiPAFBase::Init(const WiFiPAFListenParameters & param) +{ + ChipLogDetail(Inet, "WiFiPAFBase::Init - setting/overriding transport"); + VerifyOrReturnError(mState == State::kNotReady, CHIP_ERROR_INCORRECT_STATE); + DeviceLayer::ConnectivityMgr().SetWiFiPAF(this); + mState = State::kInitialized; + + if (!DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted()) + { + ChipLogError(Inet, "Wi-Fi Management has not started, do it now."); + static constexpr useconds_t kWiFiStartCheckTimeUsec = WIFI_START_CHECK_TIME_USEC; + static constexpr uint8_t kWiFiStartCheckAttempts = WIFI_START_CHECK_ATTEMPTS; + DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement(); + { + for (int cnt = 0; cnt < kWiFiStartCheckAttempts; cnt++) + { + if (DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted()) + { + break; + } + usleep(kWiFiStartCheckTimeUsec); + } + } + if (!DeviceLayer::ConnectivityMgrImpl().IsWiFiManagementStarted()) + { + ChipLogError(Inet, "Wi-Fi Management taking too long to start - device configuration will be reset."); + return CHIP_ERROR_INTERNAL; + } + ChipLogProgress(NotSpecified, "Wi-Fi Management is started"); + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR WiFiPAFBase::SendMessage(const Transport::PeerAddress & address, System::PacketBufferHandle && msgBuf) +{ + ReturnErrorCodeIf(address.GetTransportType() != Type::kWiFiPAF, CHIP_ERROR_INVALID_ARGUMENT); + ReturnErrorCodeIf(mState == State::kNotReady, CHIP_ERROR_INCORRECT_STATE); + DeviceLayer::ConnectivityMgr().WiFiPAFSend(std::move(msgBuf)); + + return CHIP_NO_ERROR; +} + +void WiFiPAFBase::OnWiFiPAFMessageReceived(System::PacketBufferHandle && buffer) +{ + HandleMessageReceived(Transport::PeerAddress(Transport::Type::kWiFiPAF), std::move(buffer)); + return; +} + +CHIP_ERROR WiFiPAFBase::SendAfterConnect(System::PacketBufferHandle && msg) +{ + CHIP_ERROR err = CHIP_ERROR_NO_MEMORY; + + for (size_t i = 0; i < mPendingPacketsSize; i++) + { + if (mPendingPackets[i].IsNull()) + { + mPendingPackets[i] = std::move(msg); + err = CHIP_NO_ERROR; + break; + } + } + + return err; +} + +} // namespace Transport +} // namespace chip diff --git a/src/transport/raw/WiFiPAF.h b/src/transport/raw/WiFiPAF.h new file mode 100644 index 00000000000000..bd54d22cc3e26f --- /dev/null +++ b/src/transport/raw/WiFiPAF.h @@ -0,0 +1,115 @@ +/* + * + * 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. + */ + +/** + * @file + * This file defines the Matter Connection object that maintains a Wi-Fi PAF connection. + * + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace chip { +namespace Transport { + +class WiFiPAFLayer +{ +public: + WiFiPAFLayer() = default; +}; +class WiFiPAFListenParameters; + +/** + * Implements a transport using Wi-Fi-PAF + */ +class DLL_EXPORT WiFiPAFBase : public Base +{ +public: + /** + * The State of the Wi-Fi-PAF connection + * + */ + enum class State + { + kNotReady = 0, /**< State before initialization. */ + kInitialized = 1, /**< State after class is connected and ready. */ + kConnected = 2, /**< Endpoint connected. */ + }; + WiFiPAFBase() = default; + WiFiPAFBase(System::PacketBufferHandle * packetBuffers, size_t packetBuffersSize) : + mPendingPackets(packetBuffers), mPendingPacketsSize(packetBuffersSize) + {} + ~WiFiPAFBase() override; + + /** + * Initialize a Wi-Fi-PAF transport + * + * @param param Wi-Fi-PAF configuration parameters for this transport + */ + CHIP_ERROR Init(const WiFiPAFListenParameters & param); + CHIP_ERROR SendMessage(const Transport::PeerAddress & address, System::PacketBufferHandle && msgBuf) override; + bool CanSendToPeer(const Transport::PeerAddress & address) override + { + return (mState != State::kNotReady) && (address.GetTransportType() == Type::kWiFiPAF); + } + void OnWiFiPAFMessageReceived(System::PacketBufferHandle && buffer); + void SetWiFiPAFState(State state) { mState = state; }; + State GetWiFiPAFState() { return mState; }; + +private: + void ClearState(); + /** + * Sends the specified message once a connection has been established. + * @param msg - what buffer to send once a connection has been established. + */ + CHIP_ERROR SendAfterConnect(System::PacketBufferHandle && msg); + State mState = State::kNotReady; + + System::PacketBufferHandle * mPendingPackets; + size_t mPendingPacketsSize; +}; + +template +class WiFiPAF : public WiFiPAFBase +{ +public: + WiFiPAF() : WiFiPAFBase(mPendingPackets, kPendingPacketSize) {} + +private: + System::PacketBufferHandle mPendingPackets[kPendingPacketSize]; +}; + +/** Defines parameters for setting up the Wi-Fi PAF transport */ +class WiFiPAFListenParameters +{ +public: + WiFiPAFListenParameters() = default; + explicit WiFiPAFListenParameters(WiFiPAFBase * layer) : mWiFiPAF(layer) {} + +private: + WiFiPAFBase * mWiFiPAF; +}; + +} // namespace Transport +} // namespace chip 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 0c974b62593860..81744d5c6994ff 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 @@ -5828,6 +5828,191 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t valu } // namespace Breadcrumb +namespace TCAcceptedVersion { + +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::GeneralCommissioning::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::GeneralCommissioning::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::GeneralCommissioning::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace TCAcceptedVersion + +namespace TCMinRequiredVersion { + +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::GeneralCommissioning::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::GeneralCommissioning::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::GeneralCommissioning::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace TCMinRequiredVersion + +namespace TCAcknowledgements { + +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::GeneralCommissioning::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::GeneralCommissioning::Id, Id, writable, ZCL_BITMAP16_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::GeneralCommissioning::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE); +} + +} // namespace TCAcknowledgements + +namespace TCAcknowledgementsRequired { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::GeneralCommissioning::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, bool 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::GeneralCommissioning::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool 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::GeneralCommissioning::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE); +} + +} // namespace TCAcknowledgementsRequired + namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) @@ -20765,16 +20950,68 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu namespace ServiceArea { namespace Attributes { -namespace CurrentLocation { +namespace ClusterRevision { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = emberAfReadAttribute(endpoint, Clusters::ServiceArea::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::ServiceArea::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::ServiceArea::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ServiceArea + +namespace PumpConfigurationAndControl { +namespace Attributes { + +namespace MaxPressure { + +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::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (Traits::IsNullValue(temp)) { value.SetNull(); @@ -20786,9 +21023,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20796,12 +21033,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20809,28 +21047,29 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -20841,7 +21080,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -20851,17 +21090,17 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace CurrentLocation +} // namespace MaxPressure -namespace EstimatedEndTime { +namespace MaxSpeed { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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::ServiceArea::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (Traits::IsNullValue(temp)) { @@ -20874,9 +21113,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20884,12 +21123,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20897,28 +21137,29 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -20929,7 +21170,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -20939,107 +21180,99 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace EstimatedEndTime +} // namespace MaxSpeed -namespace FeatureMap { +namespace MaxFlow { -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::ServiceArea::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::PumpConfigurationAndControl::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, uint16_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::ServiceArea::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_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::ServiceArea::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap - -namespace ClusterRevision { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ServiceArea::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; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { 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::ServiceArea::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +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::ServiceArea::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + + return Set(endpoint, value.Value(), markDirty); } -} // namespace ClusterRevision +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } -} // namespace Attributes -} // namespace ServiceArea + return Set(endpoint, value.Value()); +} -namespace PumpConfigurationAndControl { -namespace Attributes { +} // namespace MaxFlow -namespace MaxPressure { +namespace MinConstPressure { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) { @@ -21127,13 +21360,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MaxPressure +} // namespace MinConstPressure -namespace MaxSpeed { +namespace MaxConstPressure { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -21150,9 +21383,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21160,13 +21393,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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21174,29 +21407,29 @@ 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -21207,7 +21440,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -21217,13 +21450,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MaxSpeed +} // namespace MaxConstPressure -namespace MaxFlow { +namespace MinCompPressure { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -21240,9 +21473,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21250,13 +21483,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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21264,29 +21497,29 @@ 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -21297,7 +21530,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -21307,9 +21540,9 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MaxFlow +} // namespace MinCompPressure -namespace MinConstPressure { +namespace MaxCompPressure { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) { @@ -21397,13 +21630,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MinConstPressure +} // namespace MaxCompPressure -namespace MaxConstPressure { +namespace MinConstSpeed { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -21420,9 +21653,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21430,13 +21663,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21444,29 +21677,29 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -21477,7 +21710,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -21487,13 +21720,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MaxConstPressure +} // namespace MinConstSpeed -namespace MinCompPressure { +namespace MaxConstSpeed { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -21510,9 +21743,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21520,13 +21753,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21534,29 +21767,29 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -21567,7 +21800,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -21577,13 +21810,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MinCompPressure +} // namespace MaxConstSpeed -namespace MaxCompPressure { +namespace MinConstFlow { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -21600,9 +21833,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21610,13 +21843,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21624,29 +21857,29 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -21657,7 +21890,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -21667,9 +21900,9 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MaxCompPressure +} // namespace MinConstFlow -namespace MinConstSpeed { +namespace MaxConstFlow { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) { @@ -21757,13 +21990,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MinConstSpeed +} // namespace MaxConstFlow -namespace MaxConstSpeed { +namespace MinConstTemp { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -21780,9 +22013,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21790,13 +22023,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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21804,29 +22037,29 @@ 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -21837,7 +22070,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -21847,13 +22080,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MaxConstSpeed +} // namespace MinConstTemp -namespace MinConstFlow { +namespace MaxConstTemp { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -21870,9 +22103,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21880,13 +22113,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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -21894,29 +22127,29 @@ 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -21927,7 +22160,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -21937,99 +22170,162 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MinConstFlow +} // namespace MaxConstTemp -namespace MaxConstFlow { +namespace PumpStatus { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::BitMask * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits>; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = emberAfReadAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { - value.SetNonNull() = Traits::StorageToWorking(temp); + return Protocols::InteractionModel::Status::ConstraintError; } + *value = Traits::StorageToWorking(temp); return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value, + MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::BitMask value) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE); } -Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) +} // namespace PumpStatus + +namespace EffectiveOperationMode { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum * value) { - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, - markDirty); + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::PumpConfigurationAndControl::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 SetNull(chip::EndpointId endpoint) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum value, + MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, + markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum value) { - if (value.IsNull()) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { - return SetNull(endpoint, markDirty); + return Protocols::InteractionModel::Status::ConstraintError; } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); +} - return Set(endpoint, value.Value(), markDirty); +} // namespace EffectiveOperationMode + +namespace EffectiveControlMode { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::PumpConfigurationAndControl::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, const chip::app::DataModel::Nullable & value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum value, + MarkAttributeDirty markDirty) { - if (value.IsNull()) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { - return SetNull(endpoint); + return Protocols::InteractionModel::Status::ConstraintError; } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, + markDirty); +} - return Set(endpoint, value.Value()); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); } -} // namespace MaxConstFlow +} // namespace EffectiveControlMode -namespace MinConstTemp { +namespace Capacity { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) { @@ -22117,13 +22413,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MinConstTemp +} // namespace Capacity -namespace MaxConstTemp { +namespace Speed { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -22140,9 +22436,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -22150,13 +22446,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -22164,29 +22460,29 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -22197,7 +22493,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -22207,166 +22503,103 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace MaxConstTemp +} // namespace Speed -namespace PumpStatus { +namespace LifetimeRunningHours { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * 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::PumpConfigurationAndControl::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, - chip::BitMask value, - MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE); -} - -} // namespace PumpStatus - -namespace EffectiveOperationMode { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::PumpConfigurationAndControl::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; + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum value, - MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, + using Traits = NumericAttributeTraits>; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); -} - -} // namespace EffectiveOperationMode - -namespace EffectiveControlMode { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum * 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::PumpConfigurationAndControl::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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum value, +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::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, - markDirty); + + return Set(endpoint, value.Value(), markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::app::Clusters::PumpConfigurationAndControl::ControlModeEnum 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); + + return Set(endpoint, value.Value()); } -} // namespace EffectiveControlMode +} // namespace LifetimeRunningHours -namespace Capacity { +namespace Power { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -22383,9 +22616,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits>; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -22393,13 +22626,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits>; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -22407,29 +22640,29 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int16_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits>; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits>; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -22440,7 +22673,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -22450,13 +22683,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace Capacity +} // namespace Power -namespace Speed { +namespace LifetimeEnergyConsumed { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & 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 = @@ -22473,9 +22706,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nu return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -22483,13 +22716,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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -22497,29 +22730,29 @@ 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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType value; Traits::SetNull(value); uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); } -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) { if (value.IsNull()) @@ -22530,7 +22763,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value(), 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) { if (value.IsNull()) { @@ -22540,300 +22773,30 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a return Set(endpoint, value.Value()); } -} // namespace Speed +} // namespace LifetimeEnergyConsumed -namespace LifetimeRunningHours { +namespace OperationMode { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum * value) { - using Traits = NumericAttributeTraits>; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = emberAfReadAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { - value.SetNonNull() = Traits::StorageToWorking(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 = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_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 LifetimeRunningHours - -namespace Power { - -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::PumpConfigurationAndControl::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, uint32_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT24U_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 Power - -namespace LifetimeEnergyConsumed { - -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::PumpConfigurationAndControl::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, uint32_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT32U_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT32U_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::PumpConfigurationAndControl::Id, Id, writable, ZCL_INT32U_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 LifetimeEnergyConsumed - -namespace OperationMode { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::PumpConfigurationAndControl::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::PumpConfigurationAndControl::OperationModeEnum value, - MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, + chip::app::Clusters::PumpConfigurationAndControl::OperationModeEnum value, + MarkAttributeDirty markDirty) { using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) @@ -26154,66 +26117,19 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::a { if (value.IsNull()) { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace ActiveScheduleHandle - -namespace PresetsSchedulesEditable { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::Thermostat::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, bool 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::Thermostat::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - 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::Thermostat::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE); + + return Set(endpoint, value.Value()); } -} // namespace PresetsSchedulesEditable +} // namespace ActiveScheduleHandle -namespace TemperatureSetpointHoldPolicy { +namespace PresetsSchedulesEditable { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value) { - using Traits = NumericAttributeTraits>; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = @@ -26227,11 +26143,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits>; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -26239,13 +26153,12 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) { - using Traits = NumericAttributeTraits>; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -26253,10 +26166,10 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE); } -} // namespace TemperatureSetpointHoldPolicy +} // namespace PresetsSchedulesEditable namespace SetpointHoldExpiryTimestamp { @@ -34203,237 +34116,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_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::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace PIRUnoccupiedToOccupiedThreshold - -namespace UltrasonicOccupiedToUnoccupiedDelay { - -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::OccupancySensing::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::OccupancySensing::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::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace UltrasonicOccupiedToUnoccupiedDelay - -namespace UltrasonicUnoccupiedToOccupiedDelay { - -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::OccupancySensing::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::OccupancySensing::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::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace UltrasonicUnoccupiedToOccupiedDelay - -namespace UltrasonicUnoccupiedToOccupiedThreshold { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::OccupancySensing::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, uint8_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::OccupancySensing::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 = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace UltrasonicUnoccupiedToOccupiedThreshold - -namespace PhysicalContactOccupiedToUnoccupiedDelay { - -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::OccupancySensing::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::OccupancySensing::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::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace PhysicalContactOccupiedToUnoccupiedDelay - -namespace PhysicalContactUnoccupiedToOccupiedDelay { - -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::OccupancySensing::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::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) -{ - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34441,16 +34124,16 @@ 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::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace PhysicalContactUnoccupiedToOccupiedDelay +} // namespace PIRUnoccupiedToOccupiedThreshold -namespace PhysicalContactUnoccupiedToOccupiedThreshold { +namespace UltrasonicOccupiedToUnoccupiedDelay { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = @@ -34464,9 +34147,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * val return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34474,12 +34157,12 @@ 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::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34487,16 +34170,16 @@ 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::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace PhysicalContactUnoccupiedToOccupiedThreshold +} // namespace UltrasonicOccupiedToUnoccupiedDelay -namespace FeatureMap { +namespace UltrasonicUnoccupiedToOccupiedDelay { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = @@ -34510,9 +34193,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * va return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34520,12 +34203,12 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34533,16 +34216,16 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap +} // namespace UltrasonicUnoccupiedToOccupiedDelay -namespace ClusterRevision { +namespace UltrasonicUnoccupiedToOccupiedThreshold { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = @@ -34556,9 +34239,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * va return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34566,12 +34249,12 @@ 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::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34579,18 +34262,12 @@ 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::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace OccupancySensing - -namespace CarbonMonoxideConcentrationMeasurement { -namespace Attributes { +} // namespace UltrasonicUnoccupiedToOccupiedThreshold -namespace ClusterRevision { +namespace PhysicalContactOccupiedToUnoccupiedDelay { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -34598,7 +34275,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::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -34618,8 +34295,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::CarbonMonoxideConcentrationMeasurement::Id, Id, writable, - ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -34632,19 +34308,12 @@ 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::CarbonMonoxideConcentrationMeasurement::Id, Id, writable, - ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace CarbonMonoxideConcentrationMeasurement - -namespace CarbonDioxideConcentrationMeasurement { -namespace Attributes { +} // namespace PhysicalContactOccupiedToUnoccupiedDelay -namespace ClusterRevision { +namespace PhysicalContactUnoccupiedToOccupiedDelay { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -34652,7 +34321,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::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -34672,8 +34341,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::CarbonDioxideConcentrationMeasurement::Id, Id, writable, - ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -34686,27 +34354,20 @@ 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::CarbonDioxideConcentrationMeasurement::Id, Id, writable, - ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace CarbonDioxideConcentrationMeasurement - -namespace NitrogenDioxideConcentrationMeasurement { -namespace Attributes { +} // namespace PhysicalContactUnoccupiedToOccupiedDelay -namespace ClusterRevision { +namespace PhysicalContactUnoccupiedToOccupiedThreshold { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -34716,9 +34377,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * va return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34726,13 +34387,12 @@ 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::NitrogenDioxideConcentrationMeasurement::Id, Id, writable, - ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34740,27 +34400,20 @@ 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::NitrogenDioxideConcentrationMeasurement::Id, Id, writable, - ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace NitrogenDioxideConcentrationMeasurement - -namespace OzoneConcentrationMeasurement { -namespace Attributes { +} // namespace PhysicalContactUnoccupiedToOccupiedThreshold -namespace ClusterRevision { +namespace FeatureMap { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -34770,9 +34423,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * va return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34780,13 +34433,12 @@ 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::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, - markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -34794,16 +34446,10 @@ 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::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace OzoneConcentrationMeasurement - -namespace Pm25ConcentrationMeasurement { -namespace Attributes { +} // namespace FeatureMap namespace ClusterRevision { @@ -34813,7 +34459,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::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::OccupancySensing::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -34833,8 +34479,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::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, - markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -34847,15 +34492,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::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OccupancySensing::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace Pm25ConcentrationMeasurement +} // namespace OccupancySensing -namespace FormaldehydeConcentrationMeasurement { +namespace CarbonMonoxideConcentrationMeasurement { namespace Attributes { namespace ClusterRevision { @@ -34866,7 +34511,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::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -34886,7 +34531,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::FormaldehydeConcentrationMeasurement::Id, Id, writable, + return emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } @@ -34900,16 +34545,16 @@ 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::FormaldehydeConcentrationMeasurement::Id, Id, writable, + return emberAfWriteAttribute(endpoint, Clusters::CarbonMonoxideConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace FormaldehydeConcentrationMeasurement +} // namespace CarbonMonoxideConcentrationMeasurement -namespace Pm1ConcentrationMeasurement { +namespace CarbonDioxideConcentrationMeasurement { namespace Attributes { namespace ClusterRevision { @@ -34920,7 +34565,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::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -34940,8 +34585,8 @@ 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::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, - markDirty); + return emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable, + ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -34954,15 +34599,16 @@ 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::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::CarbonDioxideConcentrationMeasurement::Id, Id, writable, + ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace Pm1ConcentrationMeasurement +} // namespace CarbonDioxideConcentrationMeasurement -namespace Pm10ConcentrationMeasurement { +namespace NitrogenDioxideConcentrationMeasurement { namespace Attributes { namespace ClusterRevision { @@ -34973,7 +34619,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::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -34993,8 +34639,8 @@ 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::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, - markDirty); + return emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable, + ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -35007,15 +34653,16 @@ 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::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::NitrogenDioxideConcentrationMeasurement::Id, Id, writable, + ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace Pm10ConcentrationMeasurement +} // namespace NitrogenDioxideConcentrationMeasurement -namespace TotalVolatileOrganicCompoundsConcentrationMeasurement { +namespace OzoneConcentrationMeasurement { namespace Attributes { namespace ClusterRevision { @@ -35024,9 +34671,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * va { using Traits = NumericAttributeTraits; Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = emberAfReadAttribute( - endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -35046,8 +34693,8 @@ 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::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable, - ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -35060,16 +34707,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::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable, - ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::OzoneConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace TotalVolatileOrganicCompoundsConcentrationMeasurement +} // namespace OzoneConcentrationMeasurement -namespace RadonConcentrationMeasurement { +namespace Pm25ConcentrationMeasurement { namespace Attributes { namespace ClusterRevision { @@ -35080,7 +34726,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::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -35100,7 +34746,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::RadonConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } @@ -35114,26 +34760,26 @@ 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::RadonConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::Pm25ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace RadonConcentrationMeasurement +} // namespace Pm25ConcentrationMeasurement -namespace WiFiNetworkManagement { +namespace FormaldehydeConcentrationMeasurement { namespace Attributes { -namespace FeatureMap { +namespace ClusterRevision { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -35143,9 +34789,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * va return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -35153,13 +34799,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, - markDirty); + return emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable, + ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -35167,10 +34813,17 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::FormaldehydeConcentrationMeasurement::Id, Id, writable, + ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace FormaldehydeConcentrationMeasurement + +namespace Pm1ConcentrationMeasurement { +namespace Attributes { namespace ClusterRevision { @@ -35180,7 +34833,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::WiFiNetworkManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -35200,7 +34853,8 @@ 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::WiFiNetworkManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -35213,122 +34867,79 @@ 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::WiFiNetworkManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::Pm1ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace WiFiNetworkManagement +} // namespace Pm1ConcentrationMeasurement -namespace ThreadBorderRouterManagement { +namespace Pm10ConcentrationMeasurement { namespace Attributes { -namespace BorderRouterName { +namespace ClusterRevision { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { - uint8_t zclString[63 + 1]; + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, zclString, sizeof(zclString)); + emberAfReadAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - size_t length = emberAfStringLength(zclString); - if (length == NumericAttributeTraits::kNullValue) + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { return Protocols::InteractionModel::Status::ConstraintError; } - - VerifyOrReturnError(value.size() == 63, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(value.data(), &zclString[1], 63); - value.reduce_size(length); + *value = Traits::StorageToWorking(temp); return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value, MarkAttributeDirty markDirty) -{ - - static_assert(63 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 63, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[63 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, zclString, - ZCL_CHAR_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value) -{ - - static_assert(63 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 63, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[63 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, zclString, - ZCL_CHAR_STRING_ATTRIBUTE_TYPE); -} - -} // namespace BorderRouterName - -namespace BorderAgentID { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableByteSpan & value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - uint8_t zclString[254 + 1]; - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, zclString, sizeof(zclString)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - size_t length = emberAfStringLength(zclString); - if (length == NumericAttributeTraits::kNullValue) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; } - - VerifyOrReturnError(value.size() == 254, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(value.data(), &zclString[1], 254); - value.reduce_size(length); - return status; + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, + markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - - static_assert(254 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 254, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[254 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, zclString, - ZCL_OCTET_STRING_ATTRIBUTE_TYPE, 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::Pm10ConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value) -{ +} // namespace ClusterRevision - static_assert(254 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 254, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[254 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, zclString, - ZCL_OCTET_STRING_ATTRIBUTE_TYPE); -} +} // namespace Attributes +} // namespace Pm10ConcentrationMeasurement -} // namespace BorderAgentID +namespace TotalVolatileOrganicCompoundsConcentrationMeasurement { +namespace Attributes { -namespace ThreadVersion { +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::ThreadBorderRouterManagement::Id, Id, readable, sizeof(temp)); + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = emberAfReadAttribute( + endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -35348,8 +34959,8 @@ 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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, - markDirty); + return emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable, + ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -35362,20 +34973,27 @@ 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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id, Id, writable, + ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace ThreadVersion +} // namespace ClusterRevision -namespace InterfaceEnabled { +} // namespace Attributes +} // namespace TotalVolatileOrganicCompoundsConcentrationMeasurement -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value) +namespace RadonConcentrationMeasurement { +namespace Attributes { + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -35385,9 +35003,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value) return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -35395,13 +35013,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, M Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -35409,110 +35027,73 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::RadonConcentrationMeasurement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace InterfaceEnabled +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace RadonConcentrationMeasurement -namespace ActiveDatasetTimestamp { +namespace WiFiNetworkManagement { +namespace Attributes { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { - value.SetNonNull() = Traits::StorageToWorking(temp); + return Protocols::InteractionModel::Status::ConstraintError; } + *value = Traits::StorageToWorking(temp); return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, 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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, 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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT64U_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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT64U_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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT64U_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()); + return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } -} // namespace ActiveDatasetTimestamp +} // namespace FeatureMap -namespace FeatureMap { +namespace ClusterRevision { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -35522,9 +35103,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * va return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -35532,13 +35113,12 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, - markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -35546,10 +35126,16 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t valu Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WiFiNetworkManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WiFiNetworkManagement + +namespace ThreadBorderRouterManagement { +namespace Attributes { namespace ClusterRevision { 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 45b29d719e47eb..cd73287e99b4ca 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 @@ -919,6 +919,30 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t valu Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value, MarkAttributeDirty markDirty); } // namespace Breadcrumb +namespace TCAcceptedVersion { +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 TCAcceptedVersion + +namespace TCMinRequiredVersion { +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 TCMinRequiredVersion + +namespace TCAcknowledgements { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // bitmap16 +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace TCAcknowledgements + +namespace TCAcknowledgementsRequired { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value); // boolean +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty); +} // namespace TCAcknowledgementsRequired + namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); @@ -3335,34 +3359,6 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu namespace ServiceArea { namespace Attributes { -namespace CurrentLocation { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int32u -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_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 CurrentLocation - -namespace EstimatedEndTime { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // epoch_s -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_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 EstimatedEndTime - -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); @@ -4093,17 +4089,6 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty); } // namespace PresetsSchedulesEditable -namespace TemperatureSetpointHoldPolicy { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * - value); // TemperatureSetpointHoldPolicyBitmap -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty); -} // namespace TemperatureSetpointHoldPolicy - namespace SetpointHoldExpiryTimestamp { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // epoch_s Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); @@ -5421,47 +5406,6 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu namespace ThreadBorderRouterManagement { namespace Attributes { -namespace BorderRouterName { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value); // char_string -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value, MarkAttributeDirty markDirty); -} // namespace BorderRouterName - -namespace BorderAgentID { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableByteSpan & value); // octet_string -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty); -} // namespace BorderAgentID - -namespace ThreadVersion { -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 ThreadVersion - -namespace InterfaceEnabled { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value); // boolean -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty); -} // namespace InterfaceEnabled - -namespace ActiveDatasetTimestamp { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // int64u -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_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 ActiveDatasetTimestamp - -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); 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 f1aa9705d7c8c3..60cdf13689cf10 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -5671,6 +5671,12 @@ bool emberAfLevelControlClusterStopWithOnOffCallback( bool emberAfLevelControlClusterMoveToClosestFrequencyCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::LevelControl::Commands::MoveToClosestFrequency::DecodableType & commandData); +/** + * @brief Access Control Cluster ReviewFabricRestrictions Command callback (from client) + */ +bool emberAfAccessControlClusterReviewFabricRestrictionsCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictions::DecodableType & commandData); /** * @brief Actions Cluster InstantAction Command callback (from client) */ @@ -5791,6 +5797,12 @@ bool emberAfGeneralCommissioningClusterSetRegulatoryConfigCallback( bool emberAfGeneralCommissioningClusterCommissioningCompleteCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningComplete::DecodableType & commandData); +/** + * @brief General Commissioning Cluster SetTCAcknowledgements Command callback (from client) + */ +bool emberAfGeneralCommissioningClusterSetTCAcknowledgementsCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgements::DecodableType & commandData); /** * @brief Diagnostic Logs Cluster RetrieveLogsRequest Command callback (from client) */ @@ -6059,18 +6071,6 @@ 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) */ @@ -6294,18 +6294,6 @@ bool emberAfBarrierControlClusterBarrierControlGoToPercentCallback( bool emberAfBarrierControlClusterBarrierControlStopCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::BarrierControl::Commands::BarrierControlStop::DecodableType & commandData); -/** - * @brief Service Area Cluster SelectLocations Command callback (from client) - */ -bool emberAfServiceAreaClusterSelectLocationsCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ServiceArea::Commands::SelectLocations::DecodableType & commandData); -/** - * @brief Service Area Cluster SkipCurrentLocation Command callback (from client) - */ -bool emberAfServiceAreaClusterSkipCurrentLocationCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::DecodableType & commandData); /** * @brief Thermostat Cluster SetpointRaiseLower Command callback (from client) */ @@ -6360,12 +6348,6 @@ bool emberAfThermostatClusterCancelPresetsSchedulesEditRequestCallback( bool emberAfThermostatClusterCommitPresetsSchedulesRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Thermostat::Commands::CommitPresetsSchedulesRequest::DecodableType & commandData); -/** - * @brief Thermostat Cluster SetTemperatureSetpointHoldPolicy Command callback (from client) - */ -bool emberAfThermostatClusterSetTemperatureSetpointHoldPolicyCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::DecodableType & commandData); /** * @brief Fan Control Cluster Step Command callback (from client) */ @@ -6486,30 +6468,6 @@ bool emberAfColorControlClusterMoveColorTemperatureCallback( bool emberAfColorControlClusterStepColorTemperatureCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ColorControl::Commands::StepColorTemperature::DecodableType & commandData); -/** - * @brief Thread Border Router Management Cluster GetActiveDatasetRequest Command callback (from client) - */ -bool emberAfThreadBorderRouterManagementClusterGetActiveDatasetRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetActiveDatasetRequest::DecodableType & commandData); -/** - * @brief Thread Border Router Management Cluster GetPendingDatasetRequest Command callback (from client) - */ -bool emberAfThreadBorderRouterManagementClusterGetPendingDatasetRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ThreadBorderRouterManagement::Commands::GetPendingDatasetRequest::DecodableType & commandData); -/** - * @brief Thread Border Router Management Cluster SetActiveDatasetRequest Command callback (from client) - */ -bool emberAfThreadBorderRouterManagementClusterSetActiveDatasetRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetActiveDatasetRequest::DecodableType & commandData); -/** - * @brief Thread Border Router Management Cluster SetPendingDatasetRequest Command callback (from client) - */ -bool emberAfThreadBorderRouterManagementClusterSetPendingDatasetRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::ThreadBorderRouterManagement::Commands::SetPendingDatasetRequest::DecodableType & commandData); /** * @brief Channel Cluster ChangeChannel 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 af96e92e1dc3a7..40ca9c4ab84f60 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 @@ -429,6 +429,20 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(AccessControl::AccessCo return EnumType::kUnknownEnumValue; } } +static auto __attribute__((unused)) EnsureKnownEnumValue(AccessControl::AccessRestrictionTypeEnum val) +{ + using EnumType = AccessControl::AccessRestrictionTypeEnum; + switch (val) + { + case EnumType::kAttributeAccessForbidden: + case EnumType::kAttributeWriteForbidden: + case EnumType::kCommandForbidden: + case EnumType::kEventForbidden: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} static auto __attribute__((unused)) EnsureKnownEnumValue(AccessControl::ChangeTypeEnum val) { using EnumType = AccessControl::ChangeTypeEnum; @@ -948,6 +962,9 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(GeneralCommissioning::C case EnumType::kInvalidAuthentication: case EnumType::kNoFailSafe: case EnumType::kBusyWithOtherAdmin: + case EnumType::kRequiredTCNotAccepted: + case EnumType::kTCAcknowledgementsNotReceived: + case EnumType::kTCMinVersionNotMet: return val; default: return EnumType::kUnknownEnumValue; @@ -2701,6 +2718,7 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(Thermostat::PresetScena case EnumType::kSleep: case EnumType::kWake: case EnumType::kVacation: + case EnumType::kGoingToSleep: case EnumType::kUserDefined: return val; default: 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 8a15f1f0b1bac1..78d0a0085a9079 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 @@ -519,6 +519,20 @@ enum class AccessControlEntryPrivilegeEnum : uint8_t kUnknownEnumValue = 0, }; +// Enum for AccessRestrictionTypeEnum +enum class AccessRestrictionTypeEnum : uint8_t +{ + kAttributeAccessForbidden = 0x00, + kAttributeWriteForbidden = 0x01, + kCommandForbidden = 0x02, + kEventForbidden = 0x03, + // 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 = 4, +}; + // Enum for ChangeTypeEnum enum class ChangeTypeEnum : uint8_t { @@ -531,6 +545,13 @@ enum class ChangeTypeEnum : uint8_t // enum value. This specific should never be transmitted. kUnknownEnumValue = 3, }; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kExtension = 0x1, + kManagedDevice = 0x2, +}; } // namespace AccessControl namespace Actions { @@ -1089,16 +1110,19 @@ namespace GeneralCommissioning { // Enum for CommissioningErrorEnum enum class CommissioningErrorEnum : uint8_t { - kOk = 0x00, - kValueOutsideRange = 0x01, - kInvalidAuthentication = 0x02, - kNoFailSafe = 0x03, - kBusyWithOtherAdmin = 0x04, + kOk = 0x00, + kValueOutsideRange = 0x01, + kInvalidAuthentication = 0x02, + kNoFailSafe = 0x03, + kBusyWithOtherAdmin = 0x04, + kRequiredTCNotAccepted = 0x05, + kTCAcknowledgementsNotReceived = 0x06, + kTCMinVersionNotMet = 0x07, // 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 = 8, }; // Enum for RegulatoryLocationTypeEnum @@ -1113,6 +1137,12 @@ enum class RegulatoryLocationTypeEnum : uint8_t // enum value. This specific should never be transmitted. kUnknownEnumValue = 3, }; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kTermsAndConditions = 0x1, +}; } // namespace GeneralCommissioning namespace NetworkCommissioning { @@ -3964,13 +3994,14 @@ enum class ControlSequenceOfOperationEnum : uint8_t // Enum for PresetScenarioEnum enum class PresetScenarioEnum : uint8_t { - kUnspecified = 0x00, - kOccupied = 0x01, - kUnoccupied = 0x02, - kSleep = 0x03, - kWake = 0x04, - kVacation = 0x05, - kUserDefined = 0x06, + kUnspecified = 0x00, + kOccupied = 0x01, + kUnoccupied = 0x02, + kSleep = 0x03, + kWake = 0x04, + kVacation = 0x05, + kGoingToSleep = 0x06, + kUserDefined = 0xFE, // 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 @@ -4162,13 +4193,6 @@ enum class ScheduleTypeFeaturesBitmap : uint16_t kSupportsNames = 0x4, kSupportsOff = 0x8, }; - -// Bitmap for TemperatureSetpointHoldPolicyBitmap -enum class TemperatureSetpointHoldPolicyBitmap : uint8_t -{ - kHoldDurationElapsed = 0x1, - kHoldDurationElapsedOrPresetChanged = 0x2, -}; } // namespace Thermostat namespace FanControl { 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 2a3e9856803f68..881ec25faa191d 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 @@ -2100,6 +2100,170 @@ namespace Events {} // namespace Events namespace AccessControl { namespace Structs { +namespace AccessRestrictionStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kType), type); + encoder.Encode(to_underlying(Fields::kId), id); + 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::kType)) + { + err = DataModel::Decode(reader, type); + } + else if (__context_tag == to_underlying(Fields::kId)) + { + err = DataModel::Decode(reader, id); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace AccessRestrictionStruct + +namespace CommissioningAccessRestrictionEntryStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kEndpoint), endpoint); + encoder.Encode(to_underlying(Fields::kCluster), cluster); + encoder.Encode(to_underlying(Fields::kRestrictions), restrictions); + 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::kEndpoint)) + { + err = DataModel::Decode(reader, endpoint); + } + else if (__context_tag == to_underlying(Fields::kCluster)) + { + err = DataModel::Decode(reader, cluster); + } + else if (__context_tag == to_underlying(Fields::kRestrictions)) + { + err = DataModel::Decode(reader, restrictions); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace CommissioningAccessRestrictionEntryStruct + +namespace AccessRestrictionEntryStruct { +CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + return DoEncode(aWriter, aTag, NullOptional); +} + +CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & aWriter, TLV::Tag aTag, FabricIndex aAccessingFabricIndex) const +{ + return DoEncode(aWriter, aTag, MakeOptional(aAccessingFabricIndex)); +} + +CHIP_ERROR Type::DoEncode(TLV::TLVWriter & aWriter, TLV::Tag aTag, const Optional & aAccessingFabricIndex) const +{ + bool includeSensitive = !aAccessingFabricIndex.HasValue() || (aAccessingFabricIndex.Value() == fabricIndex); + + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kEndpoint), endpoint); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kCluster), cluster); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kRestrictions), restrictions); + } + if (aAccessingFabricIndex.HasValue()) + { + encoder.Encode(to_underlying(Fields::kFabricIndex), fabricIndex); + } + + 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::kEndpoint)) + { + err = DataModel::Decode(reader, endpoint); + } + else if (__context_tag == to_underlying(Fields::kCluster)) + { + err = DataModel::Decode(reader, cluster); + } + else if (__context_tag == to_underlying(Fields::kRestrictions)) + { + err = DataModel::Decode(reader, restrictions); + } + else if (__context_tag == to_underlying(Fields::kFabricIndex)) + { + err = DataModel::Decode(reader, fabricIndex); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace AccessRestrictionEntryStruct + namespace AccessControlTargetStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -2293,7 +2457,76 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace AccessControlExtensionStruct } // namespace Structs -namespace Commands {} // namespace Commands +namespace Commands { +namespace ReviewFabricRestrictions { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kArl), arl); + 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::kArl)) + { + err = DataModel::Decode(reader, arl); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ReviewFabricRestrictions. +namespace ReviewFabricRestrictionsResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kToken), token); + 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::kToken)) + { + err = DataModel::Decode(reader, token); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ReviewFabricRestrictionsResponse. +} // namespace Commands namespace Attributes { CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) @@ -2310,6 +2543,10 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, targetsPerAccessControlEntry); case Attributes::AccessControlEntriesPerFabric::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, accessControlEntriesPerFabric); + case Attributes::CommissioningARL::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, commissioningARL); + case Attributes::Arl::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, arl); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -2439,6 +2676,91 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace AccessControlExtensionChanged. +namespace AccessRestrictionEntryChanged { +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::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::kFabricIndex)) + { + err = DataModel::Decode(reader, fabricIndex); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace AccessRestrictionEntryChanged. +namespace FabricRestrictionReviewUpdate { +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::kToken), token)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kInstruction), instruction)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kRedirectURL), redirectURL)); + 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::kToken)) + { + err = DataModel::Decode(reader, token); + } + else if (__context_tag == to_underlying(Fields::kInstruction)) + { + err = DataModel::Decode(reader, instruction); + } + else if (__context_tag == to_underlying(Fields::kRedirectURL)) + { + err = DataModel::Decode(reader, redirectURL); + } + else if (__context_tag == to_underlying(Fields::kFabricIndex)) + { + err = DataModel::Decode(reader, fabricIndex); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace FabricRestrictionReviewUpdate. } // namespace Events } // namespace AccessControl @@ -4814,6 +5136,79 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace CommissioningCompleteResponse. +namespace SetTCAcknowledgements { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kTCVersion), TCVersion); + encoder.Encode(to_underlying(Fields::kTCUserResponse), TCUserResponse); + 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::kTCVersion)) + { + err = DataModel::Decode(reader, TCVersion); + } + else if (__context_tag == to_underlying(Fields::kTCUserResponse)) + { + err = DataModel::Decode(reader, TCUserResponse); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SetTCAcknowledgements. +namespace SetTCAcknowledgementsResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kErrorCode), errorCode); + 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::kErrorCode)) + { + err = DataModel::Decode(reader, errorCode); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SetTCAcknowledgementsResponse. } // namespace Commands namespace Attributes { @@ -4831,6 +5226,14 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, locationCapability); case Attributes::SupportsConcurrentConnection::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, supportsConcurrentConnection); + case Attributes::TCAcceptedVersion::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, TCAcceptedVersion); + case Attributes::TCMinRequiredVersion::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, TCMinRequiredVersion); + case Attributes::TCAcknowledgements::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, TCAcknowledgements); + case Attributes::TCAcknowledgementsRequired::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, TCAcknowledgementsRequired); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -7782,6 +8185,7 @@ namespace KeepActive { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kStayActiveDuration), stayActiveDuration); return encoder.Finalize(); } @@ -7795,6 +8199,19 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { return std::get(__element); } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kStayActiveDuration)) + { + err = DataModel::Decode(reader, stayActiveDuration); + } + else + { + } + + ReturnErrorOnFailure(err); } } } // namespace KeepActive. @@ -21358,40 +21775,6 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace CommitPresetsSchedulesRequest. -namespace SetTemperatureSetpointHoldPolicy { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const -{ - DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kTemperatureSetpointHoldPolicy), temperatureSetpointHoldPolicy); - 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::kTemperatureSetpointHoldPolicy)) - { - err = DataModel::Decode(reader, temperatureSetpointHoldPolicy); - } - else - { - } - - ReturnErrorOnFailure(err); - } -} -} // namespace SetTemperatureSetpointHoldPolicy. } // namespace Commands namespace Attributes { @@ -21519,8 +21902,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, schedules); case Attributes::PresetsSchedulesEditable::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, presetsSchedulesEditable); - case Attributes::TemperatureSetpointHoldPolicy::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, temperatureSetpointHoldPolicy); case Attributes::SetpointHoldExpiryTimestamp::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, setpointHoldExpiryTimestamp); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): @@ -23772,6 +24153,8 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre { case Attributes::Ssid::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, ssid); + case Attributes::PassphraseSurrogate::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, passphraseSurrogate); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -31764,7 +32147,6 @@ bool CommandNeedsTimedInvoke(ClusterId aCluster, CommandId aCommand) { case Clusters::ThreadNetworkDirectory::Commands::AddNetwork::Id: case Clusters::ThreadNetworkDirectory::Commands::RemoveNetwork::Id: - case Clusters::ThreadNetworkDirectory::Commands::GetOperationalDataset::Id: return true; default: return false; @@ -31843,6 +32225,15 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::AccessControl::Id: { + switch (aCommand) + { + case Clusters::AccessControl::Commands::ReviewFabricRestrictions::Id: + return true; + default: + return false; + } + } case Clusters::Actions::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 81be5e1224e81d..c52692f1ad4591 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 @@ -2657,6 +2657,110 @@ struct TypeInfo } // namespace Binding namespace AccessControl { namespace Structs { +namespace AccessRestrictionStruct { +enum class Fields : uint8_t +{ + kType = 0, + kId = 1, +}; + +struct Type +{ +public: + AccessRestrictionTypeEnum type = static_cast(0); + DataModel::Nullable id; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace AccessRestrictionStruct +namespace CommissioningAccessRestrictionEntryStruct { +enum class Fields : uint8_t +{ + kEndpoint = 0, + kCluster = 1, + kRestrictions = 2, +}; + +struct Type +{ +public: + chip::EndpointId endpoint = static_cast(0); + chip::ClusterId cluster = static_cast(0); + DataModel::List restrictions; + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +struct DecodableType +{ +public: + chip::EndpointId endpoint = static_cast(0); + chip::ClusterId cluster = static_cast(0); + DataModel::DecodableList restrictions; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; +}; + +} // namespace CommissioningAccessRestrictionEntryStruct +namespace AccessRestrictionEntryStruct { +enum class Fields : uint8_t +{ + kEndpoint = 0, + kCluster = 1, + kRestrictions = 2, + kFabricIndex = 254, +}; + +struct Type +{ +public: + chip::EndpointId endpoint = static_cast(0); + chip::ClusterId cluster = static_cast(0); + DataModel::List restrictions; + chip::FabricIndex fabricIndex = static_cast(0); + + static constexpr bool kIsFabricScoped = true; + + auto GetFabricIndex() const { return fabricIndex; } + + void SetFabricIndex(chip::FabricIndex fabricIndex_) { fabricIndex = fabricIndex_; } + + CHIP_ERROR EncodeForWrite(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + CHIP_ERROR EncodeForRead(TLV::TLVWriter & aWriter, TLV::Tag aTag, FabricIndex aAccessingFabricIndex) const; + +private: + CHIP_ERROR DoEncode(TLV::TLVWriter & aWriter, TLV::Tag aTag, const Optional & aAccessingFabricIndex) const; +}; + +struct DecodableType +{ +public: + chip::EndpointId endpoint = static_cast(0); + chip::ClusterId cluster = static_cast(0); + DataModel::DecodableList restrictions; + chip::FabricIndex fabricIndex = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = true; + + auto GetFabricIndex() const { return fabricIndex; } + + void SetFabricIndex(chip::FabricIndex fabricIndex_) { fabricIndex = fabricIndex_; } +}; + +} // namespace AccessRestrictionEntryStruct namespace AccessControlTargetStruct { enum class Fields : uint8_t { @@ -2766,6 +2870,88 @@ using DecodableType = Type; } // namespace AccessControlExtensionStruct } // namespace Structs +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace ReviewFabricRestrictions { +struct Type; +struct DecodableType; +} // namespace ReviewFabricRestrictions + +namespace ReviewFabricRestrictionsResponse { +struct Type; +struct DecodableType; +} // namespace ReviewFabricRestrictionsResponse + +} // namespace Commands + +namespace Commands { +namespace ReviewFabricRestrictions { +enum class Fields : uint8_t +{ + kArl = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ReviewFabricRestrictions::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + + DataModel::List arl; + + 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::ReviewFabricRestrictions::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + + DataModel::DecodableList arl; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ReviewFabricRestrictions +namespace ReviewFabricRestrictionsResponse { +enum class Fields : uint8_t +{ + kToken = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ReviewFabricRestrictionsResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + + uint64_t token = static_cast(0); + + 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::ReviewFabricRestrictionsResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + + uint64_t token = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ReviewFabricRestrictionsResponse +} // namespace Commands + namespace Attributes { namespace Acl { @@ -2832,6 +3018,35 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace AccessControlEntriesPerFabric +namespace CommissioningARL { +struct TypeInfo +{ + using Type = chip::app::DataModel::List< + const chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::Type>; + using DecodableType = chip::app::DataModel::DecodableList< + chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::DecodableType>; + using DecodableArgType = const chip::app::DataModel::DecodableList< + chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::DecodableType> &; + + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::CommissioningARL::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace CommissioningARL +namespace Arl { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList< + chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::DecodableType>; + using DecodableArgType = const chip::app::DataModel::DecodableList< + chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::DecodableType> &; + + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::Arl::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace Arl namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -2882,6 +3097,8 @@ struct TypeInfo Attributes::SubjectsPerAccessControlEntry::TypeInfo::DecodableType subjectsPerAccessControlEntry = static_cast(0); Attributes::TargetsPerAccessControlEntry::TypeInfo::DecodableType targetsPerAccessControlEntry = static_cast(0); Attributes::AccessControlEntriesPerFabric::TypeInfo::DecodableType accessControlEntriesPerFabric = static_cast(0); + Attributes::CommissioningARL::TypeInfo::DecodableType commissioningARL; + Attributes::Arl::TypeInfo::DecodableType arl; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; @@ -2986,6 +3203,85 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; } // namespace AccessControlExtensionChanged +namespace AccessRestrictionEntryChanged { +static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; + +enum class Fields : uint8_t +{ + kFabricIndex = 254, +}; + +struct Type +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::AccessRestrictionEntryChanged::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + static constexpr bool kIsFabricScoped = true; + + 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::AccessRestrictionEntryChanged::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + + chip::FabricIndex fabricIndex = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +} // namespace AccessRestrictionEntryChanged +namespace FabricRestrictionReviewUpdate { +static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; + +enum class Fields : uint8_t +{ + kToken = 0, + kInstruction = 1, + kRedirectURL = 2, + kFabricIndex = 254, +}; + +struct Type +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::FabricRestrictionReviewUpdate::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + static constexpr bool kIsFabricScoped = true; + + uint64_t token = static_cast(0); + DataModel::Nullable instruction; + DataModel::Nullable redirectURL; + 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::FabricRestrictionReviewUpdate::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } + + uint64_t token = static_cast(0); + DataModel::Nullable instruction; + DataModel::Nullable redirectURL; + chip::FabricIndex fabricIndex = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +} // namespace FabricRestrictionReviewUpdate } // namespace Events } // namespace AccessControl namespace Actions { @@ -6044,6 +6340,16 @@ struct Type; struct DecodableType; } // namespace CommissioningCompleteResponse +namespace SetTCAcknowledgements { +struct Type; +struct DecodableType; +} // namespace SetTCAcknowledgements + +namespace SetTCAcknowledgementsResponse { +struct Type; +struct DecodableType; +} // namespace SetTCAcknowledgementsResponse + } // namespace Commands namespace Commands { @@ -6253,6 +6559,73 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace CommissioningCompleteResponse +namespace SetTCAcknowledgements { +enum class Fields : uint8_t +{ + kTCVersion = 0, + kTCUserResponse = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SetTCAcknowledgements::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } + + uint16_t TCVersion = static_cast(0); + uint16_t TCUserResponse = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SetTCAcknowledgements::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } + + uint16_t TCVersion = static_cast(0); + uint16_t TCUserResponse = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SetTCAcknowledgements +namespace SetTCAcknowledgementsResponse { +enum class Fields : uint8_t +{ + kErrorCode = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SetTCAcknowledgementsResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } + + CommissioningErrorEnum errorCode = static_cast(0); + + 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::SetTCAcknowledgementsResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } + + CommissioningErrorEnum errorCode = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SetTCAcknowledgementsResponse } // namespace Commands namespace Attributes { @@ -6317,6 +6690,54 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace SupportsConcurrentConnection +namespace TCAcceptedVersion { +struct TypeInfo +{ + using Type = uint16_t; + using DecodableType = uint16_t; + using DecodableArgType = uint16_t; + + static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::TCAcceptedVersion::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace TCAcceptedVersion +namespace TCMinRequiredVersion { +struct TypeInfo +{ + using Type = uint16_t; + using DecodableType = uint16_t; + using DecodableArgType = uint16_t; + + static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::TCMinRequiredVersion::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace TCMinRequiredVersion +namespace TCAcknowledgements { +struct TypeInfo +{ + using Type = uint16_t; + using DecodableType = uint16_t; + using DecodableArgType = uint16_t; + + static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::TCAcknowledgements::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace TCAcknowledgements +namespace TCAcknowledgementsRequired { +struct TypeInfo +{ + using Type = bool; + using DecodableType = bool; + using DecodableArgType = bool; + + static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::TCAcknowledgementsRequired::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace TCAcknowledgementsRequired namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -6369,6 +6790,10 @@ struct TypeInfo Attributes::LocationCapability::TypeInfo::DecodableType locationCapability = static_cast(0); Attributes::SupportsConcurrentConnection::TypeInfo::DecodableType supportsConcurrentConnection = static_cast(0); + Attributes::TCAcceptedVersion::TypeInfo::DecodableType TCAcceptedVersion = static_cast(0); + Attributes::TCMinRequiredVersion::TypeInfo::DecodableType TCMinRequiredVersion = static_cast(0); + Attributes::TCAcknowledgements::TypeInfo::DecodableType TCAcknowledgements = static_cast(0); + Attributes::TCAcknowledgementsRequired::TypeInfo::DecodableType TCAcknowledgementsRequired = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; @@ -10638,6 +11063,7 @@ namespace Commands { namespace KeepActive { enum class Fields : uint8_t { + kStayActiveDuration = 0, }; struct Type @@ -10647,6 +11073,8 @@ struct Type static constexpr CommandId GetCommandId() { return Commands::KeepActive::Id; } static constexpr ClusterId GetClusterId() { return Clusters::BridgedDeviceBasicInformation::Id; } + uint32_t stayActiveDuration = static_cast(0); + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; using ResponseType = DataModel::NullObjectType; @@ -10660,6 +11088,7 @@ struct DecodableType static constexpr CommandId GetCommandId() { return Commands::KeepActive::Id; } static constexpr ClusterId GetClusterId() { return Clusters::BridgedDeviceBasicInformation::Id; } + uint32_t stayActiveDuration = static_cast(0); CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace KeepActive @@ -29360,11 +29789,6 @@ struct Type; struct DecodableType; } // namespace CommitPresetsSchedulesRequest -namespace SetTemperatureSetpointHoldPolicy { -struct Type; -struct DecodableType; -} // namespace SetTemperatureSetpointHoldPolicy - } // namespace Commands namespace Commands { @@ -29700,40 +30124,6 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace CommitPresetsSchedulesRequest -namespace SetTemperatureSetpointHoldPolicy { -enum class Fields : uint8_t -{ - kTemperatureSetpointHoldPolicy = 0, -}; - -struct Type -{ -public: - // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand - static constexpr CommandId GetCommandId() { return Commands::SetTemperatureSetpointHoldPolicy::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } - - chip::BitMask temperatureSetpointHoldPolicy = - static_cast>(0); - - 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::SetTemperatureSetpointHoldPolicy::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } - - chip::BitMask temperatureSetpointHoldPolicy = - static_cast>(0); - CHIP_ERROR Decode(TLV::TLVReader & reader); -}; -}; // namespace SetTemperatureSetpointHoldPolicy } // namespace Commands namespace Attributes { @@ -30468,18 +30858,6 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace PresetsSchedulesEditable -namespace TemperatureSetpointHoldPolicy { -struct TypeInfo -{ - using Type = chip::BitMask; - using DecodableType = chip::BitMask; - using DecodableArgType = chip::BitMask; - - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::TemperatureSetpointHoldPolicy::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace TemperatureSetpointHoldPolicy namespace SetpointHoldExpiryTimestamp { struct TypeInfo { @@ -30611,8 +30989,6 @@ struct TypeInfo Attributes::Presets::TypeInfo::DecodableType presets; Attributes::Schedules::TypeInfo::DecodableType schedules; Attributes::PresetsSchedulesEditable::TypeInfo::DecodableType presetsSchedulesEditable = static_cast(0); - Attributes::TemperatureSetpointHoldPolicy::TypeInfo::DecodableType temperatureSetpointHoldPolicy = - static_cast>(0); Attributes::SetpointHoldExpiryTimestamp::TypeInfo::DecodableType setpointHoldExpiryTimestamp; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; @@ -35963,6 +36339,18 @@ struct TypeInfo static constexpr size_t MaxLength() { return 32; } }; } // namespace Ssid +namespace PassphraseSurrogate { +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::WiFiNetworkManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::PassphraseSurrogate::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace PassphraseSurrogate namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -36009,6 +36397,7 @@ struct TypeInfo CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); Attributes::Ssid::TypeInfo::DecodableType ssid; + Attributes::PassphraseSurrogate::TypeInfo::DecodableType passphraseSurrogate; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; @@ -36473,7 +36862,7 @@ struct Type using ResponseType = Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType; - static constexpr bool MustUseTimedInvoke() { return true; } + static constexpr bool MustUseTimedInvoke() { return false; } }; struct DecodableType 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 c1d26d64c5d27b..b6e3a64e1bcfc7 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 @@ -504,6 +504,14 @@ namespace AccessControlEntriesPerFabric { static constexpr AttributeId Id = 0x00000004; } // namespace AccessControlEntriesPerFabric +namespace CommissioningARL { +static constexpr AttributeId Id = 0x00000005; +} // namespace CommissioningARL + +namespace Arl { +static constexpr AttributeId Id = 0x00000006; +} // namespace Arl + namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList @@ -1100,6 +1108,22 @@ namespace SupportsConcurrentConnection { static constexpr AttributeId Id = 0x00000004; } // namespace SupportsConcurrentConnection +namespace TCAcceptedVersion { +static constexpr AttributeId Id = 0x00000005; +} // namespace TCAcceptedVersion + +namespace TCMinRequiredVersion { +static constexpr AttributeId Id = 0x00000006; +} // namespace TCMinRequiredVersion + +namespace TCAcknowledgements { +static constexpr AttributeId Id = 0x00000007; +} // namespace TCAcknowledgements + +namespace TCAcknowledgementsRequired { +static constexpr AttributeId Id = 0x00000008; +} // namespace TCAcknowledgementsRequired + namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList @@ -5186,12 +5210,8 @@ namespace PresetsSchedulesEditable { static constexpr AttributeId Id = 0x00000052; } // namespace PresetsSchedulesEditable -namespace TemperatureSetpointHoldPolicy { -static constexpr AttributeId Id = 0x00000053; -} // namespace TemperatureSetpointHoldPolicy - namespace SetpointHoldExpiryTimestamp { -static constexpr AttributeId Id = 0x00000054; +static constexpr AttributeId Id = 0x00000053; } // namespace SetpointHoldExpiryTimestamp namespace GeneratedCommandList { @@ -6749,9 +6769,13 @@ namespace WiFiNetworkManagement { namespace Attributes { namespace Ssid { -static constexpr AttributeId Id = 0x00000001; +static constexpr AttributeId Id = 0x00000000; } // namespace Ssid +namespace PassphraseSurrogate { +static constexpr AttributeId Id = 0x00000001; +} // namespace PassphraseSurrogate + namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList 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 926df4190a620e..68b11f130dcb4c 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 @@ -159,6 +159,20 @@ static constexpr CommandId Id = 0x00000008; } // namespace Commands } // namespace LevelControl +namespace AccessControl { +namespace Commands { + +namespace ReviewFabricRestrictions { +static constexpr CommandId Id = 0x00000000; +} // namespace ReviewFabricRestrictions + +namespace ReviewFabricRestrictionsResponse { +static constexpr CommandId Id = 0x00000001; +} // namespace ReviewFabricRestrictionsResponse + +} // namespace Commands +} // namespace AccessControl + namespace Actions { namespace Commands { @@ -286,6 +300,14 @@ namespace CommissioningCompleteResponse { static constexpr CommandId Id = 0x00000005; } // namespace CommissioningCompleteResponse +namespace SetTCAcknowledgements { +static constexpr CommandId Id = 0x00000006; +} // namespace SetTCAcknowledgements + +namespace SetTCAcknowledgementsResponse { +static constexpr CommandId Id = 0x00000007; +} // namespace SetTCAcknowledgementsResponse + } // namespace Commands } // namespace GeneralCommissioning @@ -1338,10 +1360,6 @@ namespace CommitPresetsSchedulesRequest { static constexpr CommandId Id = 0x00000009; } // namespace CommitPresetsSchedulesRequest -namespace SetTemperatureSetpointHoldPolicy { -static constexpr CommandId Id = 0x0000000B; -} // namespace SetTemperatureSetpointHoldPolicy - } // namespace Commands } // namespace Thermostat 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 3a997b42d51bb5..f8243c506f906d 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 @@ -36,6 +36,14 @@ namespace AccessControlExtensionChanged { static constexpr EventId Id = 0x00000001; } // namespace AccessControlExtensionChanged +namespace AccessRestrictionEntryChanged { +static constexpr EventId Id = 0x00000002; +} // namespace AccessRestrictionEntryChanged + +namespace FabricRestrictionReviewUpdate { +static constexpr EventId Id = 0x00000003; +} // namespace FabricRestrictionReviewUpdate + } // namespace Events } // namespace AccessControl diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 273f743a19cf00..01d9f7edc46758 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -1253,6 +1253,7 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | Cluster AccessControl | 0x001F | |------------------------------------------------------------------------------| | Commands: | | +| * ReviewFabricRestrictions | 0x00 | |------------------------------------------------------------------------------| | Attributes: | | | * Acl | 0x0000 | @@ -1260,6 +1261,8 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | * SubjectsPerAccessControlEntry | 0x0002 | | * TargetsPerAccessControlEntry | 0x0003 | | * AccessControlEntriesPerFabric | 0x0004 | +| * CommissioningARL | 0x0005 | +| * Arl | 0x0006 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -1270,8 +1273,51 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | Events: | | | * AccessControlEntryChanged | 0x0000 | | * AccessControlExtensionChanged | 0x0001 | +| * AccessRestrictionEntryChanged | 0x0002 | +| * FabricRestrictionReviewUpdate | 0x0003 | \*----------------------------------------------------------------------------*/ +/* + * Command ReviewFabricRestrictions + */ +class AccessControlReviewFabricRestrictions : public ClusterCommand +{ +public: + AccessControlReviewFabricRestrictions(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("review-fabric-restrictions", credsIssuerConfig), mComplex_Arl(&mRequest.arl) + { + AddArgument("Arl", &mComplex_Arl); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::AccessControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictions::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::AccessControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictions::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::AccessControl::Commands::ReviewFabricRestrictions::Type mRequest; + TypedComplexArgument> + mComplex_Arl; +}; + /*----------------------------------------------------------------------------*\ | Cluster Actions | 0x0025 | |------------------------------------------------------------------------------| @@ -2191,6 +2237,7 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * ArmFailSafe | 0x00 | | * SetRegulatoryConfig | 0x02 | | * CommissioningComplete | 0x04 | +| * SetTCAcknowledgements | 0x06 | |------------------------------------------------------------------------------| | Attributes: | | | * Breadcrumb | 0x0000 | @@ -2198,6 +2245,10 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * RegulatoryConfig | 0x0002 | | * LocationCapability | 0x0003 | | * SupportsConcurrentConnection | 0x0004 | +| * TCAcceptedVersion | 0x0005 | +| * TCMinRequiredVersion | 0x0006 | +| * TCAcknowledgements | 0x0007 | +| * TCAcknowledgementsRequired | 0x0008 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -2324,6 +2375,45 @@ class GeneralCommissioningCommissioningComplete : public ClusterCommand chip::app::Clusters::GeneralCommissioning::Commands::CommissioningComplete::Type mRequest; }; +/* + * Command SetTCAcknowledgements + */ +class GeneralCommissioningSetTCAcknowledgements : public ClusterCommand +{ +public: + GeneralCommissioningSetTCAcknowledgements(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("set-tcacknowledgements", credsIssuerConfig) + { + AddArgument("TCVersion", 0, UINT16_MAX, &mRequest.TCVersion); + AddArgument("TCUserResponse", 0, UINT16_MAX, &mRequest.TCUserResponse); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgements::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::GeneralCommissioning::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgements::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::GeneralCommissioning::Commands::SetTCAcknowledgements::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster NetworkCommissioning | 0x0031 | |------------------------------------------------------------------------------| @@ -3436,6 +3526,7 @@ class BridgedDeviceBasicInformationKeepActive : public ClusterCommand BridgedDeviceBasicInformationKeepActive(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("keep-active", credsIssuerConfig) { + AddArgument("StayActiveDuration", 0, UINT32_MAX, &mRequest.stayActiveDuration); ClusterCommand::AddArguments(); } @@ -9435,7 +9526,6 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand | * StartPresetsSchedulesEditRequest | 0x07 | | * CancelPresetsSchedulesEditRequest | 0x08 | | * CommitPresetsSchedulesRequest | 0x09 | -| * SetTemperatureSetpointHoldPolicy | 0x0B | |------------------------------------------------------------------------------| | Attributes: | | | * LocalTemperature | 0x0000 | @@ -9498,8 +9588,7 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand | * Presets | 0x0050 | | * Schedules | 0x0051 | | * PresetsSchedulesEditable | 0x0052 | -| * TemperatureSetpointHoldPolicy | 0x0053 | -| * SetpointHoldExpiryTimestamp | 0x0054 | +| * SetpointHoldExpiryTimestamp | 0x0053 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -9857,44 +9946,6 @@ class ThermostatCommitPresetsSchedulesRequest : public ClusterCommand chip::app::Clusters::Thermostat::Commands::CommitPresetsSchedulesRequest::Type mRequest; }; -/* - * Command SetTemperatureSetpointHoldPolicy - */ -class ThermostatSetTemperatureSetpointHoldPolicy : public ClusterCommand -{ -public: - ThermostatSetTemperatureSetpointHoldPolicy(CredentialIssuerCommands * credsIssuerConfig) : - ClusterCommand("set-temperature-setpoint-hold-policy", credsIssuerConfig) - { - AddArgument("TemperatureSetpointHoldPolicy", 0, UINT8_MAX, &mRequest.temperatureSetpointHoldPolicy); - ClusterCommand::AddArguments(); - } - - CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::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::Thermostat::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::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::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Type mRequest; -}; - /*----------------------------------------------------------------------------*\ | Cluster FanControl | 0x0202 | |------------------------------------------------------------------------------| @@ -11296,7 +11347,8 @@ class ColorControlStepColorTemperature : public ClusterCommand | * NetworkPassphraseRequest | 0x00 | |------------------------------------------------------------------------------| | Attributes: | | -| * Ssid | 0x0001 | +| * Ssid | 0x0000 | +| * PassphraseSurrogate | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -16179,7 +16231,8 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands // // Commands // - make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // // // Attributes // @@ -16192,6 +16245,8 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique(Id, "access-control-entries-per-fabric", Attributes::AccessControlEntriesPerFabric::Id, credsIssuerConfig), // + make_unique(Id, "commissioning-arl", Attributes::CommissioningARL::Id, credsIssuerConfig), // + make_unique(Id, "arl", Attributes::Arl::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), // @@ -16214,6 +16269,12 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands make_unique>(Id, "access-control-entries-per-fabric", 0, UINT16_MAX, Attributes::AccessControlEntriesPerFabric::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "commissioning-arl", Attributes::CommissioningARL::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "arl", Attributes::Arl::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -16236,6 +16297,8 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique(Id, "access-control-entries-per-fabric", Attributes::AccessControlEntriesPerFabric::Id, credsIssuerConfig), // + make_unique(Id, "commissioning-arl", Attributes::CommissioningARL::Id, credsIssuerConfig), // + make_unique(Id, "arl", Attributes::Arl::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), // @@ -16248,12 +16311,20 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "access-control-entry-changed", Events::AccessControlEntryChanged::Id, credsIssuerConfig), // make_unique(Id, "access-control-extension-changed", Events::AccessControlExtensionChanged::Id, + credsIssuerConfig), // + make_unique(Id, "access-restriction-entry-changed", Events::AccessRestrictionEntryChanged::Id, + credsIssuerConfig), // + make_unique(Id, "fabric-restriction-review-update", Events::FabricRestrictionReviewUpdate::Id, credsIssuerConfig), // make_unique(Id, credsIssuerConfig), // make_unique(Id, "access-control-entry-changed", Events::AccessControlEntryChanged::Id, credsIssuerConfig), // make_unique(Id, "access-control-extension-changed", Events::AccessControlExtensionChanged::Id, credsIssuerConfig), // + make_unique(Id, "access-restriction-entry-changed", Events::AccessRestrictionEntryChanged::Id, + credsIssuerConfig), // + make_unique(Id, "fabric-restriction-review-update", Events::FabricRestrictionReviewUpdate::Id, + credsIssuerConfig), // }; commands.RegisterCluster(clusterName, clusterCommands); @@ -17080,6 +17151,7 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // // // Attributes // @@ -17090,6 +17162,11 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo make_unique(Id, "location-capability", Attributes::LocationCapability::Id, credsIssuerConfig), // make_unique(Id, "supports-concurrent-connection", Attributes::SupportsConcurrentConnection::Id, credsIssuerConfig), // + make_unique(Id, "tcaccepted-version", Attributes::TCAcceptedVersion::Id, credsIssuerConfig), // + make_unique(Id, "tcmin-required-version", Attributes::TCMinRequiredVersion::Id, credsIssuerConfig), // + make_unique(Id, "tcacknowledgements", Attributes::TCAcknowledgements::Id, credsIssuerConfig), // + make_unique(Id, "tcacknowledgements-required", Attributes::TCAcknowledgementsRequired::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), // @@ -17110,6 +17187,14 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>(Id, "supports-concurrent-connection", 0, 1, Attributes::SupportsConcurrentConnection::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "tcaccepted-version", 0, UINT16_MAX, Attributes::TCAcceptedVersion::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "tcmin-required-version", 0, UINT16_MAX, Attributes::TCMinRequiredVersion::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "tcacknowledgements", 0, UINT16_MAX, Attributes::TCAcknowledgements::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "tcacknowledgements-required", 0, 1, Attributes::TCAcknowledgementsRequired::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -17131,6 +17216,11 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo make_unique(Id, "location-capability", Attributes::LocationCapability::Id, credsIssuerConfig), // make_unique(Id, "supports-concurrent-connection", Attributes::SupportsConcurrentConnection::Id, credsIssuerConfig), // + make_unique(Id, "tcaccepted-version", Attributes::TCAcceptedVersion::Id, credsIssuerConfig), // + make_unique(Id, "tcmin-required-version", Attributes::TCMinRequiredVersion::Id, credsIssuerConfig), // + make_unique(Id, "tcacknowledgements", Attributes::TCAcknowledgements::Id, credsIssuerConfig), // + make_unique(Id, "tcacknowledgements-required", Attributes::TCAcknowledgementsRequired::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), // @@ -22991,7 +23081,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // - make_unique(credsIssuerConfig), // // // Attributes // @@ -23073,8 +23162,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "schedules", Attributes::Schedules::Id, credsIssuerConfig), // make_unique(Id, "presets-schedules-editable", Attributes::PresetsSchedulesEditable::Id, credsIssuerConfig), // - make_unique(Id, "temperature-setpoint-hold-policy", Attributes::TemperatureSetpointHoldPolicy::Id, - credsIssuerConfig), // make_unique(Id, "setpoint-hold-expiry-timestamp", Attributes::SetpointHoldExpiryTimestamp::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // @@ -23243,9 +23330,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c Id, "schedules", Attributes::Schedules::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "presets-schedules-editable", 0, 1, Attributes::PresetsSchedulesEditable::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "temperature-setpoint-hold-policy", 0, UINT8_MAX, Attributes::TemperatureSetpointHoldPolicy::Id, - WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>(Id, "setpoint-hold-expiry-timestamp", 0, UINT32_MAX, Attributes::SetpointHoldExpiryTimestamp::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -23344,8 +23428,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "schedules", Attributes::Schedules::Id, credsIssuerConfig), // make_unique(Id, "presets-schedules-editable", Attributes::PresetsSchedulesEditable::Id, credsIssuerConfig), // - make_unique(Id, "temperature-setpoint-hold-policy", Attributes::TemperatureSetpointHoldPolicy::Id, - credsIssuerConfig), // make_unique(Id, "setpoint-hold-expiry-timestamp", Attributes::SetpointHoldExpiryTimestamp::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // @@ -25570,6 +25652,7 @@ void registerClusterWiFiNetworkManagement(Commands & commands, CredentialIssuerC // make_unique(Id, credsIssuerConfig), // make_unique(Id, "ssid", Attributes::Ssid::Id, credsIssuerConfig), // + make_unique(Id, "passphrase-surrogate", Attributes::PassphraseSurrogate::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), // @@ -25579,6 +25662,9 @@ void registerClusterWiFiNetworkManagement(Commands & commands, CredentialIssuerC make_unique>(Id, credsIssuerConfig), // make_unique>>( Id, "ssid", Attributes::Ssid::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>(Id, "passphrase-surrogate", 0, UINT64_MAX, + Attributes::PassphraseSurrogate::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -25594,6 +25680,7 @@ void registerClusterWiFiNetworkManagement(Commands & commands, CredentialIssuerC WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique(Id, credsIssuerConfig), // make_unique(Id, "ssid", Attributes::Ssid::Id, credsIssuerConfig), // + make_unique(Id, "passphrase-surrogate", Attributes::PassphraseSurrogate::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), // diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index c93045a49de528..3b958cf45af7ff 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -563,6 +563,124 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::Binding::Structs::Targ ComplexArgumentParser::Finalize(request.fabricIndex); } +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::AccessControl::Structs::AccessRestrictionStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AccessRestrictionStruct.type", "type", value.isMember("type"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AccessRestrictionStruct.id", "id", value.isMember("id"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "type"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.type, value["type"])); + valueCopy.removeMember("type"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "id"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.id, value["id"])); + valueCopy.removeMember("id"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::AccessControl::Structs::AccessRestrictionStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.type); + ComplexArgumentParser::Finalize(request.id); +} + +CHIP_ERROR +ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("CommissioningAccessRestrictionEntryStruct.endpoint", "endpoint", + value.isMember("endpoint"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("CommissioningAccessRestrictionEntryStruct.cluster", "cluster", + value.isMember("cluster"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("CommissioningAccessRestrictionEntryStruct.restrictions", + "restrictions", value.isMember("restrictions"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoint"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoint, value["endpoint"])); + valueCopy.removeMember("endpoint"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "cluster"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.cluster, value["cluster"])); + valueCopy.removeMember("cluster"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "restrictions"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.restrictions, value["restrictions"])); + valueCopy.removeMember("restrictions"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize( + chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.endpoint); + ComplexArgumentParser::Finalize(request.cluster); + ComplexArgumentParser::Finalize(request.restrictions); +} + +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("AccessRestrictionEntryStruct.endpoint", "endpoint", value.isMember("endpoint"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("AccessRestrictionEntryStruct.cluster", "cluster", value.isMember("cluster"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AccessRestrictionEntryStruct.restrictions", "restrictions", + value.isMember("restrictions"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "endpoint"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.endpoint, value["endpoint"])); + valueCopy.removeMember("endpoint"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "cluster"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.cluster, value["cluster"])); + valueCopy.removeMember("cluster"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "restrictions"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.restrictions, value["restrictions"])); + valueCopy.removeMember("restrictions"); + + if (value.isMember("fabricIndex")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "fabricIndex"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.fabricIndex, value["fabricIndex"])); + } + valueCopy.removeMember("fabricIndex"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.endpoint); + ComplexArgumentParser::Finalize(request.cluster); + ComplexArgumentParser::Finalize(request.restrictions); + ComplexArgumentParser::Finalize(request.fabricIndex); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::AccessControl::Structs::AccessControlTargetStruct::Type & request, Json::Value & value) diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h index a72e57e690d024..47683b1ab87888 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h @@ -86,6 +86,23 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Binding::Struct static void Finalize(chip::app::Clusters::Binding::Structs::TargetStruct::Type & request); +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::AccessControl::Structs::AccessRestrictionStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::AccessControl::Structs::AccessRestrictionStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::AccessControl::Structs::AccessControlTargetStruct::Type & request, Json::Value & value); 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 c6c1231bab95d1..d34bbe31914c4a 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -491,6 +491,108 @@ 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 chip::app::Clusters::AccessControl::Structs::AccessRestrictionStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Type", indent + 1, value.type); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Type'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Id", indent + 1, value.id); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Id'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue( + const char * label, size_t indent, + const chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Endpoint", indent + 1, value.endpoint); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Endpoint'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Cluster", indent + 1, value.cluster); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Cluster'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Restrictions", indent + 1, value.restrictions); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Restrictions'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR +DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Endpoint", indent + 1, value.endpoint); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Endpoint'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Cluster", indent + 1, value.cluster); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Cluster'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Restrictions", indent + 1, value.restrictions); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Restrictions'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("FabricIndex", indent + 1, value.fabricIndex); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct 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 chip::app::Clusters::AccessControl::Structs::AccessControlTargetStruct::DecodableType & value) @@ -5402,6 +5504,62 @@ 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 AccessControl::Events::AccessRestrictionEntryChanged::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + 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 AccessControl::Events::FabricRestrictionReviewUpdate::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = DataModelLogger::LogValue("Token", indent + 1, value.token); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'Token'"); + return err; + } + } + { + CHIP_ERROR err = DataModelLogger::LogValue("Instruction", indent + 1, value.instruction); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'Instruction'"); + return err; + } + } + { + CHIP_ERROR err = DataModelLogger::LogValue("RedirectURL", indent + 1, value.redirectURL); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'RedirectURL'"); + 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 Actions::Events::StateChanged::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); @@ -7789,6 +7947,14 @@ 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 AccessControl::Commands::ReviewFabricRestrictionsResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("token", indent + 1, value.token)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const OtaSoftwareUpdateProvider::Commands::QueryImageResponse::DecodableType & value) { @@ -7840,6 +8006,14 @@ 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 GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("errorCode", indent + 1, value.errorCode)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & value) { @@ -9161,6 +9335,20 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("AccessControlEntriesPerFabric", 1, value); } + case AccessControl::Attributes::CommissioningARL::Id: { + chip::app::DataModel::DecodableList< + chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::DecodableType> + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CommissioningARL", 1, value); + } + case AccessControl::Attributes::Arl::Id: { + chip::app::DataModel::DecodableList< + chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::DecodableType> + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ARL", 1, value); + } case AccessControl::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -9893,6 +10081,26 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("SupportsConcurrentConnection", 1, value); } + case GeneralCommissioning::Attributes::TCAcceptedVersion::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("TCAcceptedVersion", 1, value); + } + case GeneralCommissioning::Attributes::TCMinRequiredVersion::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("TCMinRequiredVersion", 1, value); + } + case GeneralCommissioning::Attributes::TCAcknowledgements::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("TCAcknowledgements", 1, value); + } + case GeneralCommissioning::Attributes::TCAcknowledgementsRequired::Id: { + bool value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("TCAcknowledgementsRequired", 1, value); + } case GeneralCommissioning::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14980,11 +15188,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("PresetsSchedulesEditable", 1, value); } - case Thermostat::Attributes::TemperatureSetpointHoldPolicy::Id: { - chip::BitMask value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("TemperatureSetpointHoldPolicy", 1, value); - } case Thermostat::Attributes::SetpointHoldExpiryTimestamp::Id: { chip::app::DataModel::Nullable value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16906,6 +17109,11 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("SSID", 1, value); } + case WiFiNetworkManagement::Attributes::PassphraseSurrogate::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("PassphraseSurrogate", 1, value); + } case WiFiNetworkManagement::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19119,6 +19327,17 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case AccessControl::Id: { + switch (path.mCommandId) + { + case AccessControl::Commands::ReviewFabricRestrictionsResponse::Id: { + AccessControl::Commands::ReviewFabricRestrictionsResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ReviewFabricRestrictionsResponse", 1, value); + } + } + break; + } case OtaSoftwareUpdateProvider::Id: { switch (path.mCommandId) { @@ -19153,6 +19372,11 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("CommissioningCompleteResponse", 1, value); } + case GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::Id: { + GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SetTCAcknowledgementsResponse", 1, value); + } } break; } @@ -19829,6 +20053,16 @@ CHIP_ERROR DataModelLogger::LogEvent(const chip::app::EventHeader & header, chip ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("AccessControlExtensionChanged", 1, value); } + case AccessControl::Events::AccessRestrictionEntryChanged::Id: { + chip::app::Clusters::AccessControl::Events::AccessRestrictionEntryChanged::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AccessRestrictionEntryChanged", 1, value); + } + case AccessControl::Events::FabricRestrictionReviewUpdate::Id: { + chip::app::Clusters::AccessControl::Events::FabricRestrictionReviewUpdate::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FabricRestrictionReviewUpdate", 1, value); + } } break; } 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 4cfb8d31d2098c..165d44db24002f 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -59,6 +59,16 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Binding::Structs::TargetStruct::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::AccessControl::Structs::AccessRestrictionStruct::DecodableType & value); + +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::AccessControl::Structs::CommissioningAccessRestrictionEntryStruct::DecodableType & value); + +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::AccessControl::Structs::AccessRestrictionEntryStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::AccessControl::Structs::AccessControlTargetStruct::DecodableType & value); @@ -416,6 +426,10 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::AccessControl::Events::AccessControlEntryChanged::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::AccessControl::Events::AccessControlExtensionChanged::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::AccessControl::Events::AccessRestrictionEntryChanged::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::AccessControl::Events::FabricRestrictionReviewUpdate::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Actions::Events::StateChanged::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, @@ -665,6 +679,9 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Groups::Commands::RemoveGroupResponse::DecodableType & value); static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictionsResponse::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::OtaSoftwareUpdateProvider::Commands::QueryImageResponse::DecodableType & value); static CHIP_ERROR @@ -678,6 +695,9 @@ LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::NetworkCommissioning::Commands::ScanNetworksResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, 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 8ebe6735d29dd0..59410234dd7589 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -10070,6 +10070,7 @@ class SubscribeAttributeBindingClusterRevision : public SubscribeAttribute { | Cluster AccessControl | 0x001F | |------------------------------------------------------------------------------| | Commands: | | +| * ReviewFabricRestrictions | 0x00 | |------------------------------------------------------------------------------| | Attributes: | | | * Acl | 0x0000 | @@ -10077,6 +10078,8 @@ class SubscribeAttributeBindingClusterRevision : public SubscribeAttribute { | * SubjectsPerAccessControlEntry | 0x0002 | | * TargetsPerAccessControlEntry | 0x0003 | | * AccessControlEntriesPerFabric | 0x0004 | +| * CommissioningARL | 0x0005 | +| * Arl | 0x0006 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -10087,8 +10090,91 @@ class SubscribeAttributeBindingClusterRevision : public SubscribeAttribute { | Events: | | | * AccessControlEntryChanged | 0x0000 | | * AccessControlExtensionChanged | 0x0001 | +| * AccessRestrictionEntryChanged | 0x0002 | +| * FabricRestrictionReviewUpdate | 0x0003 | \*----------------------------------------------------------------------------*/ +#if MTR_ENABLE_PROVISIONAL +/* + * Command ReviewFabricRestrictions + */ +class AccessControlReviewFabricRestrictions : public ClusterCommand { +public: + AccessControlReviewFabricRestrictions() + : ClusterCommand("review-fabric-restrictions") + , mComplex_Arl(&mRequest.arl) + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("Arl", &mComplex_Arl); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::AccessControl::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictions::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 = [[MTRBaseClusterAccessControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRAccessControlClusterReviewFabricRestrictionsParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + for (auto & entry_0 : mRequest.arl) { + MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct * newElement_0; + newElement_0 = [MTRAccessControlClusterCommissioningAccessRestrictionEntryStruct new]; + newElement_0.endpoint = [NSNumber numberWithUnsignedShort:entry_0.endpoint]; + newElement_0.cluster = [NSNumber numberWithUnsignedInt:entry_0.cluster]; + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + for (auto & entry_2 : entry_0.restrictions) { + MTRAccessControlClusterAccessRestrictionStruct * newElement_2; + newElement_2 = [MTRAccessControlClusterAccessRestrictionStruct new]; + newElement_2.type = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.type)]; + if (entry_2.id.IsNull()) { + newElement_2.id = nil; + } else { + newElement_2.id = [NSNumber numberWithUnsignedInt:entry_2.id.Value()]; + } + [array_2 addObject:newElement_2]; + } + newElement_0.restrictions = array_2; + } + [array_0 addObject:newElement_0]; + } + params.arl = array_0; + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster reviewFabricRestrictionsWithParams: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::AccessControl::Commands::ReviewFabricRestrictions::Type mRequest; + TypedComplexArgument> mComplex_Arl; +}; + +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute Acl */ @@ -10657,6 +10743,181 @@ class SubscribeAttributeAccessControlAccessControlEntriesPerFabric : public Subs } }; +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute CommissioningARL + */ +class ReadAccessControlCommissioningARL : public ReadAttribute { +public: + ReadAccessControlCommissioningARL() + : ReadAttribute("commissioning-arl") + { + } + + ~ReadAccessControlCommissioningARL() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::AccessControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::AccessControl::Attributes::CommissioningARL::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 = [[MTRBaseClusterAccessControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeCommissioningARLWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"AccessControl.CommissioningARL response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("AccessControl CommissioningARL read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeAccessControlCommissioningARL : public SubscribeAttribute { +public: + SubscribeAttributeAccessControlCommissioningARL() + : SubscribeAttribute("commissioning-arl") + { + } + + ~SubscribeAttributeAccessControlCommissioningARL() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::AccessControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::AccessControl::Attributes::CommissioningARL::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 = [[MTRBaseClusterAccessControl 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 subscribeAttributeCommissioningARLWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"AccessControl.CommissioningARL 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 Arl + */ +class ReadAccessControlArl : public ReadAttribute { +public: + ReadAccessControlArl() + : ReadAttribute("arl") + { + } + + ~ReadAccessControlArl() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::AccessControl::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::AccessControl::Attributes::Arl::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 = [[MTRBaseClusterAccessControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRReadParams alloc] init]; + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + [cluster readAttributeARLWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"AccessControl.ARL response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("AccessControl ARL read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeAccessControlArl : public SubscribeAttribute { +public: + SubscribeAttributeAccessControlArl() + : SubscribeAttribute("arl") + { + } + + ~SubscribeAttributeAccessControlArl() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::AccessControl::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::AccessControl::Attributes::Arl::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 = [[MTRBaseClusterAccessControl 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 subscribeAttributeARLWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"AccessControl.ARL 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 + /* * Attribute GeneratedCommandList */ @@ -22779,6 +23040,7 @@ class SubscribeAttributePowerSourceClusterRevision : public SubscribeAttribute { | * ArmFailSafe | 0x00 | | * SetRegulatoryConfig | 0x02 | | * CommissioningComplete | 0x04 | +| * SetTCAcknowledgements | 0x06 | |------------------------------------------------------------------------------| | Attributes: | | | * Breadcrumb | 0x0000 | @@ -22786,6 +23048,10 @@ class SubscribeAttributePowerSourceClusterRevision : public SubscribeAttribute { | * RegulatoryConfig | 0x0002 | | * LocationCapability | 0x0003 | | * SupportsConcurrentConnection | 0x0004 | +| * TCAcceptedVersion | 0x0005 | +| * TCMinRequiredVersion | 0x0006 | +| * TCAcknowledgements | 0x0007 | +| * TCAcknowledgementsRequired | 0x0008 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -22958,6 +23224,72 @@ class GeneralCommissioningCommissioningComplete : public ClusterCommand { private: }; +#if MTR_ENABLE_PROVISIONAL +/* + * Command SetTCAcknowledgements + */ +class GeneralCommissioningSetTCAcknowledgements : public ClusterCommand { +public: + GeneralCommissioningSetTCAcknowledgements() + : ClusterCommand("set-tcacknowledgements") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("TCVersion", 0, UINT16_MAX, &mRequest.TCVersion); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("TCUserResponse", 0, UINT16_MAX, &mRequest.TCUserResponse); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgements::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 = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRGeneralCommissioningClusterSetTCAcknowledgementsParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.tcVersion = [NSNumber numberWithUnsignedShort:mRequest.TCVersion]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.tcUserResponse = [NSNumber numberWithUnsignedShort:mRequest.TCUserResponse]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster setTCAcknowledgementsWithParams:params completion: + ^(MTRGeneralCommissioningClusterSetTCAcknowledgementsResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgements::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute Breadcrumb */ @@ -23409,6 +23741,347 @@ class SubscribeAttributeGeneralCommissioningSupportsConcurrentConnection : publi } }; +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute TCAcceptedVersion + */ +class ReadGeneralCommissioningTCAcceptedVersion : public ReadAttribute { +public: + ReadGeneralCommissioningTCAcceptedVersion() + : ReadAttribute("tcaccepted-version") + { + } + + ~ReadGeneralCommissioningTCAcceptedVersion() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::TCAcceptedVersion::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 = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeTCAcceptedVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"GeneralCommissioning.TCAcceptedVersion response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("GeneralCommissioning TCAcceptedVersion read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeGeneralCommissioningTCAcceptedVersion : public SubscribeAttribute { +public: + SubscribeAttributeGeneralCommissioningTCAcceptedVersion() + : SubscribeAttribute("tcaccepted-version") + { + } + + ~SubscribeAttributeGeneralCommissioningTCAcceptedVersion() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::TCAcceptedVersion::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 = [[MTRBaseClusterGeneralCommissioning 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 subscribeAttributeTCAcceptedVersionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"GeneralCommissioning.TCAcceptedVersion 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 TCMinRequiredVersion + */ +class ReadGeneralCommissioningTCMinRequiredVersion : public ReadAttribute { +public: + ReadGeneralCommissioningTCMinRequiredVersion() + : ReadAttribute("tcmin-required-version") + { + } + + ~ReadGeneralCommissioningTCMinRequiredVersion() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::TCMinRequiredVersion::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 = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeTCMinRequiredVersionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"GeneralCommissioning.TCMinRequiredVersion response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("GeneralCommissioning TCMinRequiredVersion read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeGeneralCommissioningTCMinRequiredVersion : public SubscribeAttribute { +public: + SubscribeAttributeGeneralCommissioningTCMinRequiredVersion() + : SubscribeAttribute("tcmin-required-version") + { + } + + ~SubscribeAttributeGeneralCommissioningTCMinRequiredVersion() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::TCMinRequiredVersion::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 = [[MTRBaseClusterGeneralCommissioning 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 subscribeAttributeTCMinRequiredVersionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"GeneralCommissioning.TCMinRequiredVersion 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 TCAcknowledgements + */ +class ReadGeneralCommissioningTCAcknowledgements : public ReadAttribute { +public: + ReadGeneralCommissioningTCAcknowledgements() + : ReadAttribute("tcacknowledgements") + { + } + + ~ReadGeneralCommissioningTCAcknowledgements() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::TCAcknowledgements::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 = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeTCAcknowledgementsWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"GeneralCommissioning.TCAcknowledgements response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("GeneralCommissioning TCAcknowledgements read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeGeneralCommissioningTCAcknowledgements : public SubscribeAttribute { +public: + SubscribeAttributeGeneralCommissioningTCAcknowledgements() + : SubscribeAttribute("tcacknowledgements") + { + } + + ~SubscribeAttributeGeneralCommissioningTCAcknowledgements() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::TCAcknowledgements::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 = [[MTRBaseClusterGeneralCommissioning 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 subscribeAttributeTCAcknowledgementsWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"GeneralCommissioning.TCAcknowledgements 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 TCAcknowledgementsRequired + */ +class ReadGeneralCommissioningTCAcknowledgementsRequired : public ReadAttribute { +public: + ReadGeneralCommissioningTCAcknowledgementsRequired() + : ReadAttribute("tcacknowledgements-required") + { + } + + ~ReadGeneralCommissioningTCAcknowledgementsRequired() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::TCAcknowledgementsRequired::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 = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeTCAcknowledgementsRequiredWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"GeneralCommissioning.TCAcknowledgementsRequired response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("GeneralCommissioning TCAcknowledgementsRequired read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeGeneralCommissioningTCAcknowledgementsRequired : public SubscribeAttribute { +public: + SubscribeAttributeGeneralCommissioningTCAcknowledgementsRequired() + : SubscribeAttribute("tcacknowledgements-required") + { + } + + ~SubscribeAttributeGeneralCommissioningTCAcknowledgementsRequired() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::TCAcknowledgementsRequired::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 = [[MTRBaseClusterGeneralCommissioning 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 subscribeAttributeTCAcknowledgementsRequiredWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"GeneralCommissioning.TCAcknowledgementsRequired 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 + /* * Attribute GeneratedCommandList */ @@ -39513,6 +40186,9 @@ class BridgedDeviceBasicInformationKeepActive : public ClusterCommand { BridgedDeviceBasicInformationKeepActive() : ClusterCommand("keep-active") { +#if MTR_ENABLE_PROVISIONAL + AddArgument("StayActiveDuration", 0, UINT32_MAX, &mRequest.stayActiveDuration); +#endif // MTR_ENABLE_PROVISIONAL ClusterCommand::AddArguments(); } @@ -39527,6 +40203,9 @@ class BridgedDeviceBasicInformationKeepActive : public ClusterCommand { __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; __auto_type * params = [[MTRBridgedDeviceBasicInformationClusterKeepActiveParams alloc] init]; params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.stayActiveDuration = [NSNumber numberWithUnsignedInt:mRequest.stayActiveDuration]; +#endif // MTR_ENABLE_PROVISIONAL uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { @@ -39547,6 +40226,7 @@ class BridgedDeviceBasicInformationKeepActive : public ClusterCommand { } private: + chip::app::Clusters::BridgedDeviceBasicInformation::Commands::KeepActive::Type mRequest; }; #endif // MTR_ENABLE_PROVISIONAL @@ -106873,7 +107553,6 @@ class SubscribeAttributePumpConfigurationAndControlClusterRevision : public Subs | * StartPresetsSchedulesEditRequest | 0x07 | | * CancelPresetsSchedulesEditRequest | 0x08 | | * CommitPresetsSchedulesRequest | 0x09 | -| * SetTemperatureSetpointHoldPolicy | 0x0B | |------------------------------------------------------------------------------| | Attributes: | | | * LocalTemperature | 0x0000 | @@ -106936,8 +107615,7 @@ class SubscribeAttributePumpConfigurationAndControlClusterRevision : public Subs | * Presets | 0x0050 | | * Schedules | 0x0051 | | * PresetsSchedulesEditable | 0x0052 | -| * TemperatureSetpointHoldPolicy | 0x0053 | -| * SetpointHoldExpiryTimestamp | 0x0054 | +| * SetpointHoldExpiryTimestamp | 0x0053 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -107420,59 +108098,6 @@ class ThermostatCommitPresetsSchedulesRequest : public ClusterCommand { private: }; -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL -/* - * Command SetTemperatureSetpointHoldPolicy - */ -class ThermostatSetTemperatureSetpointHoldPolicy : public ClusterCommand { -public: - ThermostatSetTemperatureSetpointHoldPolicy() - : ClusterCommand("set-temperature-setpoint-hold-policy") - { -#if MTR_ENABLE_PROVISIONAL - AddArgument("TemperatureSetpointHoldPolicy", 0, UINT8_MAX, &mRequest.temperatureSetpointHoldPolicy); -#endif // MTR_ENABLE_PROVISIONAL - ClusterCommand::AddArguments(); - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::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 = [[MTRBaseClusterThermostat alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams alloc] init]; - params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; -#if MTR_ENABLE_PROVISIONAL - params.temperatureSetpointHoldPolicy = [NSNumber numberWithUnsignedChar:mRequest.temperatureSetpointHoldPolicy.Raw()]; -#endif // MTR_ENABLE_PROVISIONAL - uint16_t repeatCount = mRepeatCount.ValueOr(1); - uint16_t __block responsesNeeded = repeatCount; - while (repeatCount--) { - [cluster setTemperatureSetpointHoldPolicyWithParams: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::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::Type mRequest; -}; - #endif // MTR_ENABLE_PROVISIONAL /* @@ -113736,91 +114361,6 @@ class SubscribeAttributeThermostatPresetsSchedulesEditable : public SubscribeAtt #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute TemperatureSetpointHoldPolicy - */ -class ReadThermostatTemperatureSetpointHoldPolicy : public ReadAttribute { -public: - ReadThermostatTemperatureSetpointHoldPolicy() - : ReadAttribute("temperature-setpoint-hold-policy") - { - } - - ~ReadThermostatTemperatureSetpointHoldPolicy() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Thermostat::Attributes::TemperatureSetpointHoldPolicy::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 = [[MTRBaseClusterThermostat alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeTemperatureSetpointHoldPolicyWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"Thermostat.TemperatureSetpointHoldPolicy response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Thermostat TemperatureSetpointHoldPolicy read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeThermostatTemperatureSetpointHoldPolicy : public SubscribeAttribute { -public: - SubscribeAttributeThermostatTemperatureSetpointHoldPolicy() - : SubscribeAttribute("temperature-setpoint-hold-policy") - { - } - - ~SubscribeAttributeThermostatTemperatureSetpointHoldPolicy() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Thermostat::Attributes::TemperatureSetpointHoldPolicy::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 = [[MTRBaseClusterThermostat 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 subscribeAttributeTemperatureSetpointHoldPolicyWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"Thermostat.TemperatureSetpointHoldPolicy 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 SetpointHoldExpiryTimestamp */ @@ -146700,7 +147240,8 @@ class SubscribeAttributeRadonConcentrationMeasurementClusterRevision : public Su | * NetworkPassphraseRequest | 0x00 | |------------------------------------------------------------------------------| | Attributes: | | -| * Ssid | 0x0001 | +| * Ssid | 0x0000 | +| * PassphraseSurrogate | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -146851,6 +147392,91 @@ class SubscribeAttributeWiFiNetworkManagementSsid : public SubscribeAttribute { #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL +/* + * Attribute PassphraseSurrogate + */ +class ReadWiFiNetworkManagementPassphraseSurrogate : public ReadAttribute { +public: + ReadWiFiNetworkManagementPassphraseSurrogate() + : ReadAttribute("passphrase-surrogate") + { + } + + ~ReadWiFiNetworkManagementPassphraseSurrogate() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::PassphraseSurrogate::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 = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributePassphraseSurrogateWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.PassphraseSurrogate response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WiFiNetworkManagement PassphraseSurrogate read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWiFiNetworkManagementPassphraseSurrogate : public SubscribeAttribute { +public: + SubscribeAttributeWiFiNetworkManagementPassphraseSurrogate() + : SubscribeAttribute("passphrase-surrogate") + { + } + + ~SubscribeAttributeWiFiNetworkManagementPassphraseSurrogate() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::PassphraseSurrogate::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 = [[MTRBaseClusterWiFiNetworkManagement 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 subscribeAttributePassphraseSurrogateWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WiFiNetworkManagement.PassphraseSurrogate 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 */ @@ -190651,6 +191277,9 @@ void registerClusterAccessControl(Commands & commands) 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), // @@ -190666,6 +191295,14 @@ void registerClusterAccessControl(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#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(), // make_unique(), // make_unique(), // @@ -191132,6 +191769,9 @@ void registerClusterGeneralCommissioning(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(Id), // make_unique(Id), // make_unique(Id), // @@ -191146,6 +191786,22 @@ void registerClusterGeneralCommissioning(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#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(), // make_unique(), // make_unique(), // @@ -194926,9 +195582,6 @@ void registerClusterThermostat(Commands & commands) #endif // MTR_ENABLE_PROVISIONAL #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), // @@ -195104,10 +195757,6 @@ void registerClusterThermostat(Commands & commands) 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(), // @@ -196257,6 +196906,10 @@ void registerClusterWiFiNetworkManagement(Commands & commands) 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(), //