diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index d3c222df06c380..935040ce64155c 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -54,9 +54,9 @@ RUN curl https://raw.githubusercontent.com/restyled-io/restyler/master/bin/resty && chmod +x /usr/local/bin/restyle-path \ && : -RUN mkdir -p /opt/sdk/sdks/ \ +RUN mkdir -p /opt/android/sdk \ && chown -R $USERNAME:$USERNAME \ - /opt/sdk/sdks/ `# NXP uses a patch_sdk script to change SDK files` \ + /opt/android/sdk `# NXP uses a patch_sdk script to change SDK files` \ $ANDROID_HOME \ $IDF_TOOLS_PATH \ && find $AMEBA_PATH -name "inc_lp" -print0 | xargs -0 chown -R $USERNAME:$USERNAME \ @@ -64,14 +64,14 @@ RUN mkdir -p /opt/sdk/sdks/ \ && find $AMEBA_PATH -name "project_lp" -print0 | xargs -0 chown -R $USERNAME:$USERNAME \ && find $AMEBA_PATH -name "project_hp" -print0 | xargs -0 chown -R $USERNAME:$USERNAME \ && chmod -R +x \ - $ANDROID_HOME/tools/bin `# sdkmanager for accepting licenses`\ + $ANDROID_HOME/cmdline-tools/10.0/bin `# sdkmanager for accepting licenses`\ && chmod -R +w \ $IDF_TOOLS_PATH \ && find $AMEBA_PATH -name "inc_lp" -print0 | xargs -0 chmod -R +w \ && find $AMEBA_PATH -name "inc_hp" -print0 | xargs -0 chmod -R +w \ && find $AMEBA_PATH -name "project_lp" -print0 | xargs -0 chmod -R +w \ && find $AMEBA_PATH -name "project_hp" -print0 | xargs -0 chmod -R +w \ - # Safe directory is preffered over chown. + # Safe directory is preferred over chown. && git config --global --add safe.directory "*" \ && : diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 1d4c1dfb5b77e1..7b4d3a061aed20 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -49,6 +49,7 @@ amebad amebaiot AmebaZ amebaz2 +ANC announcementReason AnnounceOTAProvider AnnounceOTAProviderRequest @@ -85,6 +86,7 @@ ASR AssertionError AST ASYNC +ATL ATLs atomics att @@ -114,6 +116,7 @@ avahi avL AwaitNextAction AXXXF +Axxxx AYNJV babaf backend @@ -507,6 +510,7 @@ entrypoint enum Enums env +EP epochKey epochStartTime eq @@ -538,6 +542,7 @@ ExtendedPAN ExtensionEntry extern extpanid +Exx FabricId fabricIdx fabricIndex @@ -585,6 +590,7 @@ fuzzer fuzzers fuzztest FW +Fxx gbl gcloud GDB @@ -684,6 +690,7 @@ ICMP IDF IDL IDLs +IDM idt idx ifconfig @@ -1236,6 +1243,7 @@ RPi's RPis RSA rsn +Rsp RSSI RST rsync @@ -1623,6 +1631,7 @@ xFFFF xfffff xFFFFFFEFFFFFFFFF XMLPICSValidator +XMLs xtensa xvzf xwayland diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 8c618416fba4c1..a5c0d35f94ee73 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -38,6 +38,7 @@ updates: - dependency-name: "third_party/java_deps/repo" - dependency-name: "third_party/jlink/repo" - dependency-name: "third_party/jsoncpp/repo" + - dependency-name: "third_party/libdatachannel/repo" - dependency-name: "third_party/libwebsockets/repo" - dependency-name: "third_party/lwip/repo" - dependency-name: "third_party/mbed-mcu-boot/repo" diff --git a/.github/workflows/bloat_check.yaml b/.github/workflows/bloat_check.yaml index a49cfbd58fa686..2d84b86316af9a 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:104 + image: ghcr.io/project-chip/chip-build:112 steps: - name: Checkout diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 24ef4842fbe76a..4c6b6733cb56f5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -43,7 +43,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -131,7 +131,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -211,11 +211,16 @@ jobs: - name: Find changed files id: changed-files uses: tj-actions/changed-files@v45 + with: + # Exclude all files under "third_party/" + files-ignore: | + third_party/ + - name: Clang-tidy validation # NOTE: clang-tidy crashes on CodegenDataModel_Write due to Nullable/std::optional check. # See https://github.com/llvm/llvm-project/issues/97426 env: - ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.all_changed_files }} + ALL_CHANGED_FILES: ${{ steps.changed-files.outputs.changed_files }} run: | touch out/changed_files.txt for file in ${ALL_CHANGED_FILES}; do @@ -300,7 +305,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -365,7 +370,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -487,7 +492,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" @@ -502,4 +507,3 @@ jobs: - name: Run Build Coverage run: ./scripts/build_coverage.sh --yaml - diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index b80aad17e2f7f2..f5eff507755c00 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 options: --user root steps: @@ -57,7 +57,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:104 + image: ghcr.io/project-chip/chip-build-esp32:112 options: --user root steps: @@ -78,7 +78,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nrf-platform:104 + image: ghcr.io/project-chip/chip-build-nrf-platform:112 options: --user root steps: @@ -99,7 +99,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-telink:104 + image: ghcr.io/project-chip/chip-build-telink:112 options: --user root steps: @@ -111,7 +111,7 @@ jobs: platform: telink # - name: Update Zephyr to specific revision (for developers purpose) # shell: bash - # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 52c23bb5bfa7b08fb2499fda8c34cbd3418e0c1d" + # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py ce4027fc0768b8509758af2e43f74e3fd2c7d58d" - name: CI Examples Telink shell: bash run: | diff --git a/.github/workflows/doxygen.yaml b/.github/workflows/doxygen.yaml index 21c0d452c1f7f9..a6b2a6675d4a0e 100644 --- a/.github/workflows/doxygen.yaml +++ b/.github/workflows/doxygen.yaml @@ -84,7 +84,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-doxygen:104 + image: ghcr.io/project-chip/chip-build-doxygen:112 if: github.actor != 'restyled-io[bot]' diff --git a/.github/workflows/examples-ameba.yaml b/.github/workflows/examples-ameba.yaml index 6bb87fd97257bb..e05532bc40cb18 100644 --- a/.github/workflows/examples-ameba.yaml +++ b/.github/workflows/examples-ameba.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-ameba:104 + image: ghcr.io/project-chip/chip-build-ameba:112 options: --user root steps: diff --git a/.github/workflows/examples-asr.yaml b/.github/workflows/examples-asr.yaml index a753d338c4c212..f662d863d97547 100644 --- a/.github/workflows/examples-asr.yaml +++ b/.github/workflows/examples-asr.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-asr:104 + image: ghcr.io/project-chip/chip-build-asr:112 options: --user root steps: diff --git a/.github/workflows/examples-bouffalolab.yaml b/.github/workflows/examples-bouffalolab.yaml index 2d1ec2d7a2cd2c..e9494d58aa7e1b 100644 --- a/.github/workflows/examples-bouffalolab.yaml +++ b/.github/workflows/examples-bouffalolab.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-bouffalolab:104 + image: ghcr.io/project-chip/chip-build-bouffalolab:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-cc13xx_26xx.yaml b/.github/workflows/examples-cc13xx_26xx.yaml index 35bdccbe274475..b5ee872c7ed038 100644 --- a/.github/workflows/examples-cc13xx_26xx.yaml +++ b/.github/workflows/examples-cc13xx_26xx.yaml @@ -42,7 +42,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-ti:104 + image: ghcr.io/project-chip/chip-build-ti:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-cc32xx.yaml b/.github/workflows/examples-cc32xx.yaml index cb874238157362..7a5217033664c8 100644 --- a/.github/workflows/examples-cc32xx.yaml +++ b/.github/workflows/examples-cc32xx.yaml @@ -41,7 +41,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-ti:104 + image: ghcr.io/project-chip/chip-build-ti:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 855be84ced625f..83d37f0130541b 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -41,7 +41,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:104 + image: ghcr.io/project-chip/chip-build-efr32:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index b65df551436f92..58abb0f19ed9f5 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-esp32:104 + image: ghcr.io/project-chip/chip-build-esp32:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -132,7 +132,7 @@ jobs: if: github.actor != 'restyled-io[bot]' && github.repository_owner == 'espressif' container: - image: ghcr.io/project-chip/chip-build-esp32:104 + image: ghcr.io/project-chip/chip-build-esp32:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-infineon.yaml b/.github/workflows/examples-infineon.yaml index 4cf54ff65960f7..f4a9cdca73a431 100644 --- a/.github/workflows/examples-infineon.yaml +++ b/.github/workflows/examples-infineon.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-infineon:104 + image: ghcr.io/project-chip/chip-build-infineon:112 env: # TODO: this should probably be part of the dockerfile itself CY_TOOLS_PATHS: /opt/Tools/ModusToolbox/tools_3.2 diff --git a/.github/workflows/examples-linux-arm.yaml b/.github/workflows/examples-linux-arm.yaml index 7c576dd68cd993..752902e2c95fbf 100644 --- a/.github/workflows/examples-linux-arm.yaml +++ b/.github/workflows/examples-linux-arm.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-crosscompile:104 + image: ghcr.io/project-chip/chip-build-crosscompile:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-linux-imx.yaml b/.github/workflows/examples-linux-imx.yaml index 72458c39656c2e..f07eb0e25eb0a1 100644 --- a/.github/workflows/examples-linux-imx.yaml +++ b/.github/workflows/examples-linux-imx.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-imx:104 + image: ghcr.io/project-chip/chip-build-imx:112 steps: - name: Checkout diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index 0e5a6d3e6ef876..3bd4f307cf5b2d 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 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 392f7aadb440be..c2b681a370591d 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 steps: - name: Checkout diff --git a/.github/workflows/examples-mw320.yaml b/.github/workflows/examples-mw320.yaml index 1b745f9ce6cd3c..c10767964df59b 100644 --- a/.github/workflows/examples-mw320.yaml +++ b/.github/workflows/examples-mw320.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index 0f946882891aff..55491d5c125b0a 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nrf-platform:104 + image: ghcr.io/project-chip/chip-build-nrf-platform:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" diff --git a/.github/workflows/examples-nuttx.yaml b/.github/workflows/examples-nuttx.yaml index f32610349e11f2..fe9f7f0f564d5c 100644 --- a/.github/workflows/examples-nuttx.yaml +++ b/.github/workflows/examples-nuttx.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nuttx:104 + image: ghcr.io/project-chip/chip-build-nuttx:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index adfeb2196e03ce..f7c54f20fab196 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nxp:104 + image: ghcr.io/project-chip/chip-build-nxp:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -239,7 +239,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nxp-zephyr:104 + image: ghcr.io/project-chip/chip-build-nxp-zephyr:112 steps: - name: Checkout diff --git a/.github/workflows/examples-openiotsdk.yaml b/.github/workflows/examples-openiotsdk.yaml index d0a0a46d79463b..171bb7de0b3032 100644 --- a/.github/workflows/examples-openiotsdk.yaml +++ b/.github/workflows/examples-openiotsdk.yaml @@ -36,7 +36,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-openiotsdk:104 + image: ghcr.io/project-chip/chip-build-openiotsdk:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" options: --privileged diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index adfd33920c5a30..53df87c2b896bd 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -40,7 +40,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-stm32.yaml b/.github/workflows/examples-stm32.yaml index 387d6bba6e2307..e7c2b696f05877 100644 --- a/.github/workflows/examples-stm32.yaml +++ b/.github/workflows/examples-stm32.yaml @@ -41,7 +41,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 22905124813572..610f3a79cbb814 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -39,7 +39,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-telink:104 + image: ghcr.io/project-chip/chip-build-telink:112 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -58,7 +58,7 @@ jobs: gh-context: ${{ toJson(github) }} # - name: Update Zephyr to specific revision (for developers purpose) - # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 52c23bb5bfa7b08fb2499fda8c34cbd3418e0c1d" + # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py ce4027fc0768b8509758af2e43f74e3fd2c7d58d" - name: Build example Telink (B92 retention) Air Quality Sensor App # Run test for master and s07641069 PRs @@ -77,7 +77,6 @@ jobs: - name: Build example Telink (W91) All Clusters App # Run test for master and s07641069 PRs if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' - continue-on-error: true run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9118bdk40d-all-clusters' build" @@ -142,7 +141,6 @@ jobs: - name: Build example Telink (W91) Lighting App with OTA, Factory Data # Run test for master and all PRs - continue-on-error: true run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9118bdk40d-light-ota-factory-data' build" @@ -154,7 +152,7 @@ jobs: - name: clean out build output (keep tools) run: rm -rf ./out/telink* - - name: Build example Telink (B91) Lighting App with OTA, RPC, Factory Data and 4Mb flash + - name: Build example Telink (B91) Lighting App with OTA, RPC, Factory Data, 4Mb flash # Run test for master and all PRs run: | ./scripts/run_in_build_env.sh \ @@ -331,16 +329,15 @@ jobs: - name: clean out build output run: rm -rf ./out - - name: Build example Telink (W91) Window Covering App + - name: Build example Telink (tl721x) Window Covering App # Run test for master and s07641069 PRs if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' - continue-on-error: true run: | ./scripts/run_in_build_env.sh \ - "./scripts/build/build_examples.py --target 'telink-tlsr9118bdk40d-window-covering' build" + "./scripts/build/build_examples.py --target 'telink-tl7218x-window-covering' build" .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - telink tlsr9118bdk40d window-covering \ - out/telink-tlsr9118bdk40d-window-covering/zephyr/zephyr.elf \ + telink tl7218x window-covering \ + out/telink-tl7218x-window-covering/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 bc94b0f3375af3..3fec2561c67c45 100644 --- a/.github/workflows/examples-tizen.yaml +++ b/.github/workflows/examples-tizen.yaml @@ -37,7 +37,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-tizen:98 + image: ghcr.io/project-chip/chip-build-tizen:112 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 c0a2692b0beb1b..35a261a4258e60 100644 --- a/.github/workflows/full-android.yaml +++ b/.github/workflows/full-android.yaml @@ -33,13 +33,13 @@ jobs: name: Run env: - JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64/ + JAVA_HOME: /usr/lib/jvm/java-11-openjdk-amd64/ runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-android:108 + image: ghcr.io/project-chip/chip-build-android:113 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/fuzzing-build.yaml b/.github/workflows/fuzzing-build.yaml index 8a1ffbc248bb3a..3e44a6dd7aa7ac 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:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/java-tests.yaml b/.github/workflows/java-tests.yaml index ad95d3dec7ad03..265c2763944693 100644 --- a/.github/workflows/java-tests.yaml +++ b/.github/workflows/java-tests.yaml @@ -43,7 +43,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-java:104 + image: ghcr.io/project-chip/chip-build-java:113 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=0 net.ipv6.conf.all.forwarding=0" @@ -75,7 +75,7 @@ jobs: # TODO: this direct path loading is not maintainable. Our build system should define and # support test classes. run: | - $JAVA_PATH/bin/java \ + $JAVA_HOME/bin/java \ -cp 'third_party/java_deps/artifacts/*:out/linux-x64-tests/lib/src/controller/java/*' \ org.junit.runner.JUnitCore \ matter.tlv.TlvWriterTest \ diff --git a/.github/workflows/minimal-build.yaml b/.github/workflows/minimal-build.yaml index c921662e1b4bc3..b5cfa0356e7c79 100644 --- a/.github/workflows/minimal-build.yaml +++ b/.github/workflows/minimal-build.yaml @@ -34,7 +34,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-minimal:104 + image: ghcr.io/project-chip/chip-build-minimal:112 steps: - name: Checkout @@ -56,7 +56,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-minimal:104 + image: ghcr.io/project-chip/chip-build-minimal:112 steps: - name: Checkout diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml index 8624b06bbd5c11..0edf53710180c2 100644 --- a/.github/workflows/qemu.yaml +++ b/.github/workflows/qemu.yaml @@ -41,7 +41,7 @@ jobs: if: github.actor != 'restyled-io[bot]' && github.repository_owner == 'espressif' container: - image: ghcr.io/project-chip/chip-build-esp32-qemu:104 + image: ghcr.io/project-chip/chip-build-esp32-qemu:112 volumes: - "/tmp/log_output:/tmp/test_logs" @@ -79,7 +79,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-tizen-qemu:98 + image: ghcr.io/project-chip/chip-build-tizen-qemu:112 options: --user root volumes: - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index bfa311bf17f7e0..88b49a341d5741 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:104 + image: ghcr.io/project-chip/chip-build-esp32:112 steps: - name: Checkout @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-efr32:104 + image: ghcr.io/project-chip/chip-build-efr32:112 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.github/workflows/smoketest-android.yaml b/.github/workflows/smoketest-android.yaml index 5712f3427dc848..c2adf9f4093a51 100644 --- a/.github/workflows/smoketest-android.yaml +++ b/.github/workflows/smoketest-android.yaml @@ -31,13 +31,13 @@ jobs: name: Smoke Run - Android env: - JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64/ + JAVA_HOME: /usr/lib/jvm/java-11-openjdk-amd64/ runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-android:108 + image: ghcr.io/project-chip/chip-build-android:113 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 9e87e73b7a4dbf..d742598edb1614 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -50,7 +50,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 options: --privileged --sysctl "net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1" @@ -461,7 +461,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 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/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index 0b0860afe7f995..6f9a1117e412ec 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -40,7 +40,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 volumes: - "/:/runner-root-volume" - "/tmp/log_output:/tmp/test_logs" @@ -52,7 +52,7 @@ jobs: - name: Checkout submodules & Bootstrap uses: ./.github/actions/checkout-submodules-and-bootstrap with: - platform: linux + platform: linux unit_tests bootstrap-log-name: bootstrap-logs-unittest-${{ matrix.type }} - name: Artifact suffix id: outsuffix @@ -66,11 +66,11 @@ jobs: # TODO: If rotating_device_id is ever removed/combined, we have to cover boringssl otherwise run: | case $BUILD_TYPE in - "main") GN_ARGS='';; - "clang") GN_ARGS='is_clang=true';; - "mbedtls") GN_ARGS='chip_crypto="mbedtls"';; - "rotating_device_id") GN_ARGS='chip_crypto="boringssl" chip_enable_rotating_device_id=true';; - "icd") GN_ARGS='chip_enable_icd_server=true chip_enable_icd_lit=true';; + "main") GN_ARGS='chip_build_all_platform_tests=true';; + "clang") GN_ARGS='is_clang=true chip_build_all_platform_tests=true';; + "mbedtls") GN_ARGS='chip_crypto="mbedtls" chip_build_all_platform_tests=true';; + "rotating_device_id") GN_ARGS='chip_crypto="boringssl" chip_enable_rotating_device_id=true chip_build_all_platform_tests=true';; + "icd") GN_ARGS='chip_enable_icd_server=true chip_enable_icd_lit=true chip_build_all_platform_tests=true';; *) ;; esac diff --git a/.github/workflows/zap_regeneration.yaml b/.github/workflows/zap_regeneration.yaml index d899b05b8a7cb8..bce5cdf93a2eb7 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:104 + image: ghcr.io/project-chip/chip-build:112 defaults: run: shell: sh diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index f03aa04605b2af..4052d128b303e5 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-20.04 container: - image: ghcr.io/project-chip/chip-build:104 + image: ghcr.io/project-chip/chip-build:112 defaults: run: shell: sh diff --git a/.gitmodules b/.gitmodules index 31325764cdc285..35f9375f59cfe8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -209,7 +209,7 @@ path = third_party/silabs/matter_support url = https://github.com/SiliconLabsSoftware/matter_support.git branch = main - platforms = silabs,silabs_docker + platforms = silabs,silabs_docker,unit_tests [submodule "third_party/silabs/simplicity_sdk"] path = third_party/silabs/simplicity_sdk url = https://github.com/SiliconLabs/simplicity_sdk.git @@ -357,4 +357,4 @@ [submodule "third_party/openthread/ot-realtek"] path = third_party/openthread/ot-realtek url = https://github.com/rtkconnectivity/ot-realtek.git - platforms = realtek_bee \ No newline at end of file + platforms = realtek_bee diff --git a/.vscode/launch.json b/.vscode/launch.json index 97ba95d77f0bad..e3cdb19266ea6c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,14 @@ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ + { + "name": "Python Debugger: test_dcl_server", + "type": "debugpy", + "request": "launch", + "program": "/workspace/connectedhomeip/examples/chip-tool/commands/dcl/test_dcl_server.py", + "args": [], + "console": "integratedTerminal" + }, { "name": "Attach to running process", "type": "lldb", diff --git a/BUILD.gn b/BUILD.gn index a777fa84b32c99..9f57b05c0cf659 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -163,8 +163,13 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { } if (chip_build_tests) { - deps += [ "//src:tests" ] - deps += [ "//examples:example_tests" ] + deps += [ + "//examples:example_tests", + "//src:tests", + + # Platform test group locations. + "//src/platform/silabs/tests:silabs_platform_tests", + ] if (current_os == "android" && current_toolchain == default_toolchain) { deps += [ "${chip_root}/build/chip/java/tests:java_build_test" ] @@ -251,6 +256,9 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { "//scripts/py_matter_yamltests:matter_yamltests.tests", "//src:tests_run", "//src/python_testing/matter_testing_infrastructure:chip-testing.tests", + + # Platform test group locations. + "//src/platform/silabs/tests:silabs_platform_tests_run", ] if (current_os == "linux" || current_os == "mac") { diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index 553b963a74191d..ce138edc3b7494 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -18,8 +18,11 @@ import("//build_overrides/googletest.gni") import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/tests.gni") +import("${dir_pw_build}/python.gni") import("${dir_pw_unit_test}/test.gni") +# Need access to build options (specifically build_coverage) +import("${build_root}/config/compiler/compiler.gni") assert(chip_build_tests) declare_args() { @@ -112,6 +115,26 @@ template("chip_test_suite") { _test_output_dir = invoker.output_dir } + if (use_coverage && is_clang) { + # Generates clang coverage to ".profraw" instead of "deafault.profraw" + _clang_coverage_setup = "${root_build_dir}/clang_static_coverage_config/${_test_name}ClangCoverageConfig.cpp" + pw_python_action("${_test_name}-clang-coverage") { + script = "${chip_root}/scripts/build/clang_coverage_wrapper.py" + outputs = [ _clang_coverage_setup ] + args = [ + "--output", + rebase_path(_clang_coverage_setup), + "--raw-profile-filename", + "coverage/${_test_name}.profraw", + ] + } + + source_set("${_test_name}-clang-coverage-src") { + sources = [ _clang_coverage_setup ] + deps = [ ":${_test_name}-clang-coverage" ] + } + } + pw_test(_test_name) { # Forward certain variables from the invoker. forward_variables_from(invoker, @@ -125,6 +148,10 @@ template("chip_test_suite") { # Link to the common lib for this suite so we get its `sources`. public_deps += [ ":${_suite_name}.lib" ] + if (use_coverage && is_clang) { + public_deps += [ ":${_test_name}-clang-coverage-src" ] + } + if (pw_unit_test_BACKEND == "$dir_pw_unit_test:googletest") { test_main = "$dir_pigweed/third_party/googletest:gmock_main" } diff --git a/build/chip/java/config.gni b/build/chip/java/config.gni index 350b7fdee34717..fc0d5d99cd92be 100644 --- a/build/chip/java/config.gni +++ b/build/chip/java/config.gni @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -java_path = getenv("JAVA_PATH") +java_home = getenv("JAVA_HOME") declare_args() { java_matter_controller_dependent_paths = [] @@ -24,15 +24,15 @@ declare_args() { matter_enable_tlv_decoder_api = true matter_enable_java_compilation = false - if (java_path != "" && (current_os == "linux" || current_os == "mac")) { - java_matter_controller_dependent_paths += [ "${java_path}/include/" ] + if (java_home != "" && (current_os == "linux" || current_os == "mac")) { + java_matter_controller_dependent_paths += [ "${java_home}/include/" ] if (current_os == "mac") { java_matter_controller_dependent_paths += - [ "${java_path}/include/darwin/" ] + [ "${java_home}/include/darwin/" ] } else { java_matter_controller_dependent_paths += - [ "${java_path}/include/linux/" ] + [ "${java_home}/include/linux/" ] } matter_enable_java_generated_api = false diff --git a/build/chip/java/jar_runner.py b/build/chip/java/jar_runner.py index bd8e1762d36c2b..7d3d52e1d37c75 100755 --- a/build/chip/java/jar_runner.py +++ b/build/chip/java/jar_runner.py @@ -79,8 +79,8 @@ def FindCommand(command): def main(): - java_path = FindCommand('jar') - if not java_path: + java_home = FindCommand('jar') + if not java_home: sys.stderr.write('jar: command not found\n') sys.exit(EXIT_FAILURE) @@ -89,7 +89,7 @@ def main(): sys.stderr.write('usage: %s [jar_args]...\n' % sys.argv[0]) sys.exit(EXIT_FAILURE) - return subprocess.check_call([java_path] + args) + return subprocess.check_call([java_home] + args) if __name__ == '__main__': diff --git a/build/chip/java/javac_runner.py b/build/chip/java/javac_runner.py index 0e03aa53e8aab9..026153d9b5271d 100755 --- a/build/chip/java/javac_runner.py +++ b/build/chip/java/javac_runner.py @@ -93,8 +93,8 @@ def ComputeClasspath(build_config_json): def main(): - java_path = FindCommand('javac') - if not java_path: + java_home = FindCommand('javac') + if not java_home: sys.stderr.write('javac: command not found\n') sys.exit(EXIT_FAILURE) @@ -123,7 +123,7 @@ def main(): build_config_json = ReadBuildConfig(args.build_config) classpath = ComputeClasspath(build_config_json) - java_args = [java_path] + java_args = [java_home] if classpath: java_args += ["-classpath", classpath] diff --git a/build/chip/java/rules.gni b/build/chip/java/rules.gni index 9a2075fe45046f..dc0d35ccba0177 100644 --- a/build/chip/java/rules.gni +++ b/build/chip/java/rules.gni @@ -22,7 +22,7 @@ jar_runner = "${chip_root}/build/chip/java/jar_runner.py" write_build_config = "${chip_root}/build/chip/java/write_build_config.py" assert(android_sdk_root != "" || matter_enable_java_compilation, - "android_sdk_root must be specified or JAVA_PATH must be set.") + "android_sdk_root must be specified or JAVA_HOME must be set.") # Declare a java library target # @@ -104,10 +104,7 @@ template("java_library") { # Building from sources - perform Java compilation and JAR creation. if (!_is_prebuilt) { # Additional flags - _javac_flags = [ - "-Werror", - "-Xlint:all", - ] + _javac_flags = [ "-Xlint:all" ] if (defined(invoker.javac_flags)) { _javac_flags += invoker.javac_flags } diff --git a/build/chip/tests.gni b/build/chip/tests.gni index 57d0311694f9be..c932439d87066e 100755 --- a/build/chip/tests.gni +++ b/build/chip/tests.gni @@ -27,6 +27,11 @@ declare_args() { # Enable building tests. chip_build_tests = current_os != "freertos" + # Enable building all platform specific tests. + # This argument should set the default value for platform specific tests build arguments. + # See src/platform/silabs/tests/args.gni as an example. + chip_build_all_platform_tests = false + # Enabling useful support functions when building using GoogleTest framework (used in unit tests and pw_fuzzer FuzzTests) # For unit tests: this should only be enabled through build_examples.py, see PR #36268 chip_build_tests_googletest = false diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn index 909219fcffd24d..073adcba4a683c 100644 --- a/build/config/compiler/BUILD.gn +++ b/build/config/compiler/BUILD.gn @@ -549,6 +549,15 @@ config("coverage") { cflags = [ "--coverage" ] } ldflags = cflags + + if (is_clang) { + # Looking to add buildid which _could_ be used for coverage + # file format using `%b` (see + # https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program) + # however at the time of writing this, linux clang used during bootstrap + # does not seem to support this. + ldflags += [ "-Wl,--build-id" ] + } } config("coverage_default") { diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index f8885b77e9739f..8beb6fb590e765 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -228,14 +228,15 @@ menu "CHIP Core" help Enable this option to start a UDP Endpoint queue filter for mDNS Broadcast packets - config ENABLE_LWIP_THREAD_SAFETY - bool "Enable LwIP Thread safety options" + config USE_TCPIP_CORE_LOCK_FOR_THREAD_SAFETY + bool "Use TCPIP core locking for LwIP thread safety" default y select LWIP_TCPIP_CORE_LOCKING select LWIP_CHECK_THREAD_SAFETY help CHIP SDK performs LwIP core locking before calling an LwIP API. To make the calls thread safe we have to enable LWIP_TCPIP_CORE_LOCKING. + Otherwise CHIP SDK will post LwIP APIs to TCPIP task to ensure thread safety. Here, we are also enabling LWIP_CHECK_THREAD_SAFETY which will assert when LwIP code gets called from any other context or without holding the LwIP lock. diff --git a/config/telink/app/bootloader.conf b/config/telink/app/bootloader.conf index 0ffacc8c0b052b..f6895c54c08731 100644 --- a/config/telink/app/bootloader.conf +++ b/config/telink/app/bootloader.conf @@ -33,12 +33,10 @@ CONFIG_BOOT_VALIDATE_SLOT0=y # Maximum signed image size: 512 * 4096 = 2M Bytes CONFIG_BOOT_MAX_IMG_SECTORS=512 -# Sets log level for modules which don't specify it explicitly. -# When set to 0 it means log will not be activated for those modules. -# Levels are: -# - 0 OFF, do not write by default -# - 1 ERROR, default to only write LOG_LEVEL_ERR -# - 2 WARNING, default to write LOG_LEVEL_WRN -# - 3 INFO, default to write LOG_LEVEL_INFO -# - 4 DEBUG, default to write LOG_LEVEL_DBG -CONFIG_LOG_DEFAULT_LEVEL=3 +# MCUBOOT log levels are: +# - OFF, LOG_LEVEL_ERR_OFF +# - ERROR, LOG_LEVEL_ERR +# - WARNING, LOG_LEVEL_WRN +# - INFO, LOG_LEVEL_INF +# - DEBUG, LOG_LEVEL_DBG +CONFIG_MCUBOOT_LOG_LEVEL_INF=y diff --git a/config/telink/app/bootloader_compress_lzma.conf b/config/telink/app/bootloader_compress_lzma.conf index cb349eed0ce387..7a8d9ec950faf4 100644 --- a/config/telink/app/bootloader_compress_lzma.conf +++ b/config/telink/app/bootloader_compress_lzma.conf @@ -26,15 +26,13 @@ CONFIG_BOOT_VALIDATE_SLOT0=y # Maximum signed image size: 512 * 4096 = 2M Bytes CONFIG_BOOT_MAX_IMG_SECTORS=512 -# Sets log level for modules which don't specify it explicitly. -# When set to 0 it means log will not be activated for those modules. -# Levels are: -# - 0 OFF, do not write by default -# - 1 ERROR, default to only write LOG_LEVEL_ERR -# - 2 WARNING, default to write LOG_LEVEL_WRN -# - 3 INFO, default to write LOG_LEVEL_INFO -# - 4 DEBUG, default to write LOG_LEVEL_DBG -CONFIG_LOG_DEFAULT_LEVEL=3 +# MCUBOOT log levels are: +# - OFF, LOG_LEVEL_ERR_OFF +# - ERROR, LOG_LEVEL_ERR +# - WARNING, LOG_LEVEL_WRN +# - INFO, LOG_LEVEL_INF +# - DEBUG, LOG_LEVEL_DBG +CONFIG_MCUBOOT_LOG_LEVEL_INF=y # LZMA used sys_heap based allocators CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=78000 diff --git a/config/telink/app/enable-gnu-std.cmake b/config/telink/app/enable-gnu-std.cmake index b165900d31866a..6ed9507ad9fd4e 100644 --- a/config/telink/app/enable-gnu-std.cmake +++ b/config/telink/app/enable-gnu-std.cmake @@ -1,19 +1,6 @@ -# -# 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. -# - add_library(gnu17 INTERFACE) -target_compile_options(gnu17 INTERFACE $<$:-std=gnu++17> $<$:-Wno-register> -D_DEFAULT_SOURCE) +target_compile_options(gnu17 + INTERFACE + $<$:-std=gnu++17> + -D_DEFAULT_SOURCE) target_link_libraries(app PRIVATE gnu17) diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index bb42a26b6ffc06..f6800790deddac 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -174,7 +174,7 @@ add_dependencies(process_binaries ${ZEPHYR_FINAL_EXECUTABLE}) # Define 'build_mcuboot' target for building the MCUBoot bootloader # ============================================================================== -if (CONFIG_BOOTLOADER_MCUBOOT AND (CONFIG_SOC_SERIES_RISCV_TELINK_B9X OR CONFIG_SOC_SERIES_RISCV_TELINK_TLX)) +if (CONFIG_BOOTLOADER_MCUBOOT AND (CONFIG_SOC_RISCV_TELINK_B9X OR CONFIG_SOC_RISCV_TELINK_TLX)) add_custom_target(build_mcuboot ALL COMMAND west build -b ${BASE_BOARD} -d build_mcuboot ${ZEPHYR_BASE}/../bootloader/mcuboot/boot/zephyr diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index 7e20a82c481142..4bf5c4928670c2 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -225,15 +225,7 @@ config CHIP_ENABLE_PM_DURING_BLE help Enable PM during BLE operation. -config CHIP_OPENTHREAD_TX_POWER - int "OpenThread Transmission power" - range -30 9 - default 0 - help - OpenThread Transmission power in dBm. - config SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE - int default 255 if SHELL_BACKEND_SERIAL config CHIP_ENABLE_POWER_ON_FACTORY_RESET @@ -252,5 +244,5 @@ config CHIP_TASK_STACK_SIZE config CHIP_USE_MARS_SENSOR bool "Use Mars board sensor" - depends on SOC_SERIES_RISCV_TELINK_B9X && (BOARD_TLSR9518ADK80D || BOARD_TLSR9518ADK80D_RETENTION) + depends on SOC_RISCV_TELINK_B9X && (BOARD_TLSR9518ADK80D || BOARD_TLSR9518ADK80D_RETENTION) default n diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index baafafa38a525d..aec634c3544d45 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -149,9 +149,6 @@ config BT_BUF_ACL_TX_SIZE default 107 if SOC_RISCV_TELINK_TL321X default 251 - -#ifdef CONFIG_SOC_RISCV_TELINK_TL321X - config BT_BUF_EVT_RX_COUNT default 4 @@ -159,12 +156,8 @@ config BT_BUF_ACL_RX_COUNT default 4 config BT_GATT_CACHING - bool default n - -#endif - config BT_RX_STACK_SIZE default 1352 if BT_B9X || BT_TLX default 2048 if BT_W91 @@ -174,10 +167,9 @@ config BT_HCI_TX_STACK_SIZE default 2048 if BT_W91 config BT_DEVICE_NAME_GATT_WRITABLE - bool default n -if SOC_SERIES_RISCV_TELINK_B9X || SOC_SERIES_RISCV_TELINK_TLX +if SOC_RISCV_TELINK_B9X || SOC_RISCV_TELINK_TLX config TL_BLE_CTRL_THREAD_STACK_SIZE default 648 @@ -197,7 +189,7 @@ choice TL_BLE_CTRL_MAC_TYPE default TL_BLE_CTRL_MAC_TYPE_RANDOM_STATIC endchoice -endif # SOC_SERIES_RISCV_TELINK_B9X || SOC_SERIES_RISCV_TELINK_TLX +endif # SOC_RISCV_TELINK_B9X || SOC_RISCV_TELINK_TLX endif # BT @@ -245,8 +237,8 @@ config CHIP_OTA_REQUESTOR default y config MCUBOOT_SIGNATURE_KEY_FILE - default "bootloader/mcuboot/root-ec-p256.pem" if BOARD_TLSR9118BDK40D - depends on BOOTLOADER_MCUBOOT + default "bootloader/mcuboot/root-ec-p256.pem" if BOARD_TLSR9118BDK40D + depends on BOOTLOADER_MCUBOOT # In current config/zephyr/Kconfig # next deprecated values are selected @@ -290,22 +282,22 @@ choice CHIP_THREAD_DEVICE_ROLE prompt "Thread network device role" default CHIP_THREAD_DEVICE_ROLE_ROUTER config CHIP_THREAD_DEVICE_ROLE_ROUTER - depends on !PM - bool "thread device router" + depends on !PM + bool "thread device router" config CHIP_THREAD_DEVICE_ROLE_END_DEVICE - depends on !PM - bool "thread end device" + depends on !PM + bool "thread end device" config CHIP_THREAD_DEVICE_ROLE_SLEEPY_END_DEVICE - bool "thread sleepy end device" + bool "thread sleepy end device" endchoice choice OPENTHREAD_DEVICE_TYPE - default OPENTHREAD_FTD if CHIP_THREAD_DEVICE_ROLE_ROUTER - default OPENTHREAD_MTD if CHIP_THREAD_DEVICE_ROLE_END_DEVICE || CHIP_THREAD_DEVICE_ROLE_SLEEPY_END_DEVICE + default OPENTHREAD_FTD if CHIP_THREAD_DEVICE_ROLE_ROUTER + default OPENTHREAD_MTD if CHIP_THREAD_DEVICE_ROLE_END_DEVICE || CHIP_THREAD_DEVICE_ROLE_SLEEPY_END_DEVICE endchoice config CHIP_ENABLE_ICD_SUPPORT - default y if CHIP_THREAD_DEVICE_ROLE_SLEEPY_END_DEVICE + default y if CHIP_THREAD_DEVICE_ROLE_SLEEPY_END_DEVICE config OPENTHREAD_THREAD_STACK_SIZE default 2400 if PM || SOC_RISCV_TELINK_TL321X @@ -338,7 +330,6 @@ config NET_RX_STACK_SIZE # Disable certain parts of Zephyr IPv6 stack config NET_IPV6_NBR_CACHE - bool default n config NET_MAX_CONN @@ -352,69 +343,69 @@ config NET_CONFIG_INIT_TIMEOUT config CHIP_WIFI - bool "Enable Telink Wi-Fi support" - default y if BOARD_TLSR9118BDK40D || BOARD_TLSR9118BDK40D_V1 - select WIFI_W91 - select WIFI - select NET_STATISTICS - select NET_IPV6_ND # enable Neighbor Discovery to handle Router Advertisements - select NET_IPV6_NBR_CACHE - select NET_STATISTICS_USER_API + bool "Enable Telink Wi-Fi support" + default y if BOARD_TLSR9118BDK40D || BOARD_TLSR9118BDK40D_V1 + select WIFI_W91 + select WIFI + select NET_STATISTICS + select NET_IPV6_ND # enable Neighbor Discovery to handle Router Advertisements + select NET_IPV6_NBR_CACHE + select NET_STATISTICS_USER_API if CHIP_WIFI config DEFAULT_WIFI_SSID - string "Default WiFi SSID" - depends on CHIP_WIFI - default "" - help - The SSID of network to connect to if no WiFi station configuration exists in NV storage - at the time the device boots. - This option is for testing only and should be disabled in production releases + string "Default WiFi SSID" + depends on CHIP_WIFI + default "" + help + The SSID of network to connect to if no WiFi station configuration exists in NV storage + at the time the device boots. + This option is for testing only and should be disabled in production releases config DEFAULT_WIFI_PASSWORD - string "Default WiFi Password" - depends on CHIP_WIFI - default "" - help - The password for the default WiFi network. - This option is for testing only and should be disabled in production releases. + string "Default WiFi Password" + depends on CHIP_WIFI + default "" + help + The password for the default WiFi network. + This option is for testing only and should be disabled in production releases. config CHIP_WIFI_CONNECTION_RECOVERY_MINIMUM_INTERVAL - int "Define the minimum connection recovery time interval in milliseconds" - depends on CHIP_WIFI - default 500 - help - Specifies the minimum connection recovery interval (in milliseconds). + int "Define the minimum connection recovery time interval in milliseconds" + depends on CHIP_WIFI + default 500 + help + Specifies the minimum connection recovery interval (in milliseconds). config CHIP_WIFI_CONNECTION_RECOVERY_MAXIMUM_INTERVAL - int "Define the maximum connection recovery time interval in milliseconds" - depends on CHIP_WIFI - default 3600000 # 1 hour - help - Specifies the maximum connection recovery interval (in milliseconds). + int "Define the maximum connection recovery time interval in milliseconds" + depends on CHIP_WIFI + default 3600000 # 1 hour + help + Specifies the maximum connection recovery interval (in milliseconds). config CHIP_WIFI_CONNECTION_RECOVERY_MAX_RETRIES_NUMBER - int "Define the maximum amount of connection recovery occurrences" - depends on CHIP_WIFI - default 0 - help - Specifies the maximum number of connection recovery attempts. - If set to 0, no limitation is applied and attempts - to recover the connection are performed indefinitely. + int "Define the maximum amount of connection recovery occurrences" + depends on CHIP_WIFI + default 0 + help + Specifies the maximum number of connection recovery attempts. + If set to 0, no limitation is applied and attempts + to recover the connection are performed indefinitely. config CHIP_WIFI_CONNECTION_RECOVERY_JITTER - int "Define the connection recovery jitter in milliseconds" - depends on CHIP_WIFI - default 2000 - help - Specifies the maximum connection recovery jitter interval (in milliseconds). - Once the wait time reaches the current maximum value (defined by CHIP_WIFI_CONNECTION_RECOVERY_MAXIMUM_INTERVAL), - a random jitter interval is added to it to avoid periodicity. The random jitter is selected - within range [-JITTER; +JITTER]. + int "Define the connection recovery jitter in milliseconds" + depends on CHIP_WIFI + default 2000 + help + Specifies the maximum connection recovery jitter interval (in milliseconds). + Once the wait time reaches the current maximum value (defined by CHIP_WIFI_CONNECTION_RECOVERY_MAXIMUM_INTERVAL), + a random jitter interval is added to it to avoid periodicity. The random jitter is selected + within range [-JITTER; +JITTER]. config NET_MGMT_EVENT_STACK_SIZE - default 1128 + default 1128 endif # CHIP_WIFI @@ -427,7 +418,7 @@ config CHIP_ENABLE_PAIRING_AUTOSTART # Configure MBEDTLS lib config MBEDTLS - default y + default y config MBEDTLS_USER_CONFIG_ENABLE default y @@ -436,22 +427,22 @@ config MBEDTLS_USER_CONFIG_FILE default "telink-mbedtls-config.h" config MBEDTLS_CIPHER_CCM_ENABLED - default y + default y config MBEDTLS_PK_WRITE_C default y config MBEDTLS_ECP_C - default y + default y config MBEDTLS_ECP_DP_SECP256R1_ENABLED - default y + default y config MBEDTLS_ECDH_C - default y + default y config MBEDTLS_ECDSA_C - default y + default y # getopt version config GETOPT_LONG diff --git a/config/zephyr/chip-module/Kconfig.mbedtls b/config/zephyr/chip-module/Kconfig.mbedtls index 72b1563b1e808d..f4b3947db6a22e 100644 --- a/config/zephyr/chip-module/Kconfig.mbedtls +++ b/config/zephyr/chip-module/Kconfig.mbedtls @@ -22,9 +22,6 @@ config MBEDTLS config MBEDTLS_ENTROPY_ENABLED default y -config MBEDTLS_ENTROPY_ENABLED - default y - config MBEDTLS_ZEPHYR_ENTROPY default y @@ -68,4 +65,3 @@ config MBEDTLS_PK_WRITE_C default y endif #CHIP - diff --git a/data_model/master/clusters/ACL-Cluster.xml b/data_model/master/clusters/ACL-Cluster.xml index 15eebb425286a4..0d45beb6437dd2 100644 --- a/data_model/master/clusters/ACL-Cluster.xml +++ b/data_model/master/clusters/ACL-Cluster.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,7 @@ Davis, CA 95616, USA - + @@ -83,14 +85,11 @@ Davis, CA 95616, USA - + - - - - - + + @@ -137,18 +136,26 @@ Davis, CA 95616, USA - + - + + + + + - + + + + + @@ -156,7 +163,9 @@ Davis, CA 95616, USA - + + + @@ -183,11 +192,13 @@ Davis, CA 95616, USA - + - + + + @@ -207,10 +218,12 @@ Davis, CA 95616, USA - + - + + + @@ -219,7 +232,9 @@ Davis, CA 95616, USA - + + + @@ -227,42 +242,54 @@ Davis, CA 95616, USA - + + + - + - + + + - + - + + + - + - + + + - + - + - + + + - + - + + + @@ -274,7 +301,9 @@ Davis, CA 95616, USA - + + + @@ -293,12 +322,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -316,12 +349,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -341,12 +378,16 @@ 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 6205fb6cb73261..c4eedae608d9e4 100644 --- a/data_model/master/clusters/AccountLogin.xml +++ b/data_model/master/clusters/AccountLogin.xml @@ -1,61 +1,61 @@ - @@ -72,7 +72,12 @@ Davis, CA 95616, USA - + + + + + + @@ -80,7 +85,9 @@ Davis, CA 95616, USA - + + + @@ -88,11 +95,18 @@ Davis, CA 95616, USA - + + + + + + - + + + @@ -115,4 +129,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/AdminCommissioningCluster.xml b/data_model/master/clusters/AdminCommissioningCluster.xml index 77a8862b2eedc7..67e19d51e4ef1c 100644 --- a/data_model/master/clusters/AdminCommissioningCluster.xml +++ b/data_model/master/clusters/AdminCommissioningCluster.xml @@ -1,59 +1,61 @@ - @@ -82,7 +84,17 @@ Davis, CA 95616, USA - + + + + + + + + + + + @@ -91,12 +103,12 @@ Davis, CA 95616, USA - + - + @@ -106,22 +118,39 @@ Davis, CA 95616, USA - + + + - + + + + + + - + + + + + + - + + + + + + @@ -131,7 +160,9 @@ Davis, CA 95616, USA - + + + @@ -139,4 +170,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/AirQuality.xml b/data_model/master/clusters/AirQuality.xml index 69387d451a38c0..929921bacbd169 100644 --- a/data_model/master/clusters/AirQuality.xml +++ b/data_model/master/clusters/AirQuality.xml @@ -1,61 +1,61 @@ - @@ -116,7 +116,9 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/AlarmBase.xml b/data_model/master/clusters/AlarmBase.xml index e374dcc382d208..b712980033c3b5 100644 --- a/data_model/master/clusters/AlarmBase.xml +++ b/data_model/master/clusters/AlarmBase.xml @@ -1,63 +1,63 @@ - - + @@ -71,7 +71,7 @@ Davis, CA 95616, USA - + @@ -80,7 +80,7 @@ Davis, CA 95616, USA - + @@ -91,7 +91,7 @@ Davis, CA 95616, USA - + @@ -131,4 +131,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/ApplicationBasic.xml b/data_model/master/clusters/ApplicationBasic.xml index 93ffeeb958ad3a..f2ef33bfd11f3e 100644 --- a/data_model/master/clusters/ApplicationBasic.xml +++ b/data_model/master/clusters/ApplicationBasic.xml @@ -1,61 +1,61 @@ - @@ -92,48 +92,58 @@ Davis, CA 95616, USA - + - + + + - + - + - + + + - + - + - + + + - + + + - + - + + + - + - \ No newline at end of file + diff --git a/data_model/master/clusters/ApplicationLauncher.xml b/data_model/master/clusters/ApplicationLauncher.xml index 51fcde769007e9..82450d0e4ccc5e 100644 --- a/data_model/master/clusters/ApplicationLauncher.xml +++ b/data_model/master/clusters/ApplicationLauncher.xml @@ -1,61 +1,61 @@ - @@ -113,16 +113,18 @@ Davis, CA 95616, USA - + - + - + + + @@ -133,7 +135,9 @@ Davis, CA 95616, USA - + + + @@ -146,7 +150,9 @@ Davis, CA 95616, USA - + + + @@ -156,7 +162,9 @@ Davis, CA 95616, USA - + + + @@ -169,4 +177,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/AudioOutput.xml b/data_model/master/clusters/AudioOutput.xml index 9972a8a87e7a6f..243d1d4ae6669e 100644 --- a/data_model/master/clusters/AudioOutput.xml +++ b/data_model/master/clusters/AudioOutput.xml @@ -1,61 +1,61 @@ - @@ -97,7 +97,9 @@ Davis, CA 95616, USA - + + + @@ -136,4 +138,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/BallastConfiguration.xml b/data_model/master/clusters/BallastConfiguration.xml deleted file mode 100644 index 9dbf4e61887d76..00000000000000 --- a/data_model/master/clusters/BallastConfiguration.xml +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/master/clusters/BasicInformationCluster.xml b/data_model/master/clusters/BasicInformationCluster.xml index 168a0353761159..0bad75b2fedf35 100644 --- a/data_model/master/clusters/BasicInformationCluster.xml +++ b/data_model/master/clusters/BasicInformationCluster.xml @@ -1,66 +1,69 @@ - - + - + + @@ -155,11 +158,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -175,139 +182,188 @@ Davis, CA 95616, USA - + - + + + - + - + + + - + - + - + + + - + - + - + - + + + - + - + + + - + - + - + + + + + + - + - + + + - + - + + + + + + - + - + + + + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + - + - + - + + + - + - + - + - + + + - + - + + + - + - + + + + + + + + + @@ -326,14 +382,22 @@ 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 72fc1eb6b3282d..81e96e25bb31bd 100644 --- a/data_model/master/clusters/Binding-Cluster.xml +++ b/data_model/master/clusters/Binding-Cluster.xml @@ -1,61 +1,61 @@ - @@ -69,21 +69,23 @@ Davis, CA 95616, USA - + - + - + + + - + @@ -94,12 +96,14 @@ Davis, CA 95616, USA - + - + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/BooleanState.xml b/data_model/master/clusters/BooleanState.xml index 9754a7af60b57a..f9c269123d5a67 100644 --- a/data_model/master/clusters/BooleanState.xml +++ b/data_model/master/clusters/BooleanState.xml @@ -1,61 +1,61 @@ - @@ -68,7 +68,7 @@ Davis, CA 95616, USA - + @@ -81,4 +81,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/BooleanStateConfiguration.xml b/data_model/master/clusters/BooleanStateConfiguration.xml index d4ae791ad7649f..dfa4b0cda1c765 100644 --- a/data_model/master/clusters/BooleanStateConfiguration.xml +++ b/data_model/master/clusters/BooleanStateConfiguration.xml @@ -1,61 +1,61 @@ - @@ -106,27 +106,36 @@ Davis, CA 95616, USA - + - + + + - + - + + + + + + - + - + + + @@ -145,7 +154,7 @@ Davis, CA 95616, USA - + @@ -155,7 +164,7 @@ Davis, CA 95616, USA - + @@ -217,4 +226,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/CameraAVSettingsUserLevelManagement.xml b/data_model/master/clusters/CameraAVSettingsUserLevelManagement.xml new file mode 100644 index 00000000000000..4202c02b599c53 --- /dev/null +++ b/data_model/master/clusters/CameraAVSettingsUserLevelManagement.xml @@ -0,0 +1,396 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/CameraAVStreamManagement.xml b/data_model/master/clusters/CameraAVStreamManagement.xml new file mode 100644 index 00000000000000..e99b91936c2db1 --- /dev/null +++ b/data_model/master/clusters/CameraAVStreamManagement.xml @@ -0,0 +1,1239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/Channel.xml b/data_model/master/clusters/Channel.xml index 02bfcf3b25c854..d51713fc67db45 100644 --- a/data_model/master/clusters/Channel.xml +++ b/data_model/master/clusters/Channel.xml @@ -1,61 +1,61 @@ - @@ -167,7 +167,9 @@ Davis, CA 95616, USA - + + + @@ -176,37 +178,51 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + - + + + - + + + @@ -219,47 +235,69 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + @@ -273,27 +311,37 @@ Davis, CA 95616, USA - + + + - + + + - + - + + + - + + + - + + + @@ -307,17 +355,21 @@ Davis, CA 95616, USA - + - + + + - + - + + + @@ -342,7 +394,9 @@ Davis, CA 95616, USA - + + + @@ -379,7 +433,9 @@ Davis, CA 95616, USA - + + + @@ -390,13 +446,17 @@ Davis, CA 95616, USA - + - + + + - + + + @@ -421,19 +481,25 @@ Davis, CA 95616, USA - + + + - + - + + + - + + + @@ -446,20 +512,26 @@ Davis, CA 95616, USA - + + + - + - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ValidProxies-Cluster.xml b/data_model/master/clusters/Chime.xml similarity index 72% rename from data_model/master/clusters/ValidProxies-Cluster.xml rename to data_model/master/clusters/Chime.xml index 51cfeedb46926d..159d87f3b1f419 100644 --- a/data_model/master/clusters/ValidProxies-Cluster.xml +++ b/data_model/master/clusters/Chime.xml @@ -1,98 +1,114 @@ - - + - + - - - + - + - - - + + + + + + + + + + + - - + + + + + + + + + + + + + - + + + + + + - - + - - - - - - - - \ No newline at end of file + diff --git a/data_model/master/clusters/ClosureControl.xml b/data_model/master/clusters/ClosureControl.xml new file mode 100644 index 00000000000000..406f90ec46799d --- /dev/null +++ b/data_model/master/clusters/ClosureControl.xml @@ -0,0 +1,454 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/ClosureDimension.xml b/data_model/master/clusters/ClosureDimension.xml new file mode 100644 index 00000000000000..f7bef1399eee11 --- /dev/null +++ b/data_model/master/clusters/ClosureDimension.xml @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/ColorControl.xml b/data_model/master/clusters/ColorControl.xml index fa14aca0f8b5f4..ecdabe7b763258 100644 --- a/data_model/master/clusters/ColorControl.xml +++ b/data_model/master/clusters/ColorControl.xml @@ -1,61 +1,61 @@ - @@ -65,10 +65,7 @@ Davis, CA 95616, USA - + @@ -246,78 +243,96 @@ Davis, CA 95616, USA - + - + + + - + - + + + - + - + + + - + - + - + + + - + - + - + + + - + - + - + + + - + - + - + + + - + - + + + - + - + + + - + @@ -327,11 +342,13 @@ Davis, CA 95616, USA - + + + - + @@ -341,11 +358,13 @@ Davis, CA 95616, USA - + + + - + @@ -358,7 +377,7 @@ Davis, CA 95616, USA - + @@ -368,11 +387,13 @@ Davis, CA 95616, USA - + + + - + @@ -382,11 +403,13 @@ Davis, CA 95616, USA - + + + - + @@ -399,7 +422,7 @@ Davis, CA 95616, USA - + @@ -409,11 +432,13 @@ Davis, CA 95616, USA - + + + - + @@ -423,11 +448,13 @@ Davis, CA 95616, USA - + + + - + @@ -440,7 +467,7 @@ Davis, CA 95616, USA - + @@ -450,11 +477,13 @@ Davis, CA 95616, USA - + + + - + @@ -464,11 +493,13 @@ Davis, CA 95616, USA - + + + - + @@ -481,7 +512,7 @@ Davis, CA 95616, USA - + @@ -491,11 +522,13 @@ Davis, CA 95616, USA - + + + - + @@ -505,11 +538,13 @@ Davis, CA 95616, USA - + + + - + @@ -522,7 +557,7 @@ Davis, CA 95616, USA - + @@ -532,11 +567,13 @@ Davis, CA 95616, USA - + + + - + @@ -546,11 +583,13 @@ Davis, CA 95616, USA - + + + - + @@ -564,89 +603,109 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + - + + + - + + + - + - + + + - + + + - + - + - + - + - + + + - + - + + + - + @@ -666,21 +725,30 @@ Davis, CA 95616, USA - + + + - + + + + + + - + + + @@ -690,18 +758,28 @@ Davis, CA 95616, USA - + + + + + + - + - + + + + + + @@ -712,22 +790,30 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -743,11 +829,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -766,11 +856,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -780,19 +874,27 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -808,11 +910,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -831,11 +937,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -845,23 +955,33 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + @@ -871,23 +991,33 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + @@ -903,11 +1033,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -923,15 +1057,21 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -941,19 +1081,27 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -969,15 +1117,21 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -987,18 +1141,24 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -1008,22 +1168,30 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -1036,19 +1204,27 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -1073,11 +1249,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -1091,11 +1271,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -1111,19 +1295,27 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -1139,24 +1331,34 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/CommissionerControlCluster.xml b/data_model/master/clusters/CommissionerControlCluster.xml index d3b8380aaba929..a0d392a652b3b6 100644 --- a/data_model/master/clusters/CommissionerControlCluster.xml +++ b/data_model/master/clusters/CommissionerControlCluster.xml @@ -1,59 +1,61 @@ - @@ -91,7 +93,9 @@ Davis, CA 95616, USA - + + + @@ -102,29 +106,48 @@ Davis, CA 95616, USA - + + + + + + - + + + - + + + - + + + + + + - + + + + + + @@ -140,8 +163,10 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ConcentrationMeasurement.xml b/data_model/master/clusters/ConcentrationMeasurement.xml index 68d4b7937bf717..7985bcc2de5077 100644 --- a/data_model/master/clusters/ConcentrationMeasurement.xml +++ b/data_model/master/clusters/ConcentrationMeasurement.xml @@ -1,61 +1,63 @@ - - + @@ -76,10 +78,10 @@ Davis, CA 95616, USA - + - + @@ -181,76 +183,101 @@ Davis, CA 95616, USA - + - + + + + + + - + - + - + + + + + - + - + + + + + + - + - + + + - + - + + + + + + - + - + + + - + + + - + - + @@ -260,4 +287,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/ContentAppObserver.xml b/data_model/master/clusters/ContentAppObserver.xml index 7ffe0b11d04377..d7fa594a3288f6 100644 --- a/data_model/master/clusters/ContentAppObserver.xml +++ b/data_model/master/clusters/ContentAppObserver.xml @@ -1,61 +1,61 @@ - @@ -81,11 +81,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -95,12 +99,16 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ContentControl.xml b/data_model/master/clusters/ContentControl.xml index 6b72a298ebeead..7f4237f66bf698 100644 --- a/data_model/master/clusters/ContentControl.xml +++ b/data_model/master/clusters/ContentControl.xml @@ -1,59 +1,61 @@ - @@ -92,8 +94,39 @@ Davis, CA 95616, USA - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -142,29 +175,53 @@ Davis, CA 95616, USA - + + + - + + + - + - + + + + + + - + + + + + + - + + + + + + - + + + + + + @@ -172,14 +229,18 @@ Davis, CA 95616, USA - + - + + + - + - + + + @@ -200,7 +261,9 @@ Davis, CA 95616, USA - + + + @@ -214,21 +277,27 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -256,7 +325,9 @@ Davis, CA 95616, USA - + + + @@ -267,11 +338,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -286,7 +361,9 @@ Davis, CA 95616, USA - + + + @@ -304,11 +381,15 @@ Davis, CA 95616, USA - + + + - + - + + + @@ -318,7 +399,9 @@ Davis, CA 95616, USA - + + + @@ -340,7 +423,9 @@ Davis, CA 95616, USA - + + + @@ -350,7 +435,9 @@ Davis, CA 95616, USA - + + + @@ -427,4 +514,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/ContentLauncher.xml b/data_model/master/clusters/ContentLauncher.xml index 5470a14ce1da64..9d64888756dcec 100644 --- a/data_model/master/clusters/ContentLauncher.xml +++ b/data_model/master/clusters/ContentLauncher.xml @@ -1,61 +1,61 @@ - @@ -105,15 +105,10 @@ Davis, CA 95616, USA - + - + @@ -182,17 +177,23 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -233,7 +234,9 @@ Davis, CA 95616, USA - + + + @@ -264,12 +267,18 @@ Davis, CA 95616, USA - + + + - - + + + + + + @@ -278,10 +287,12 @@ Davis, CA 95616, USA - + + + - + @@ -296,18 +307,22 @@ Davis, CA 95616, USA - + + + - + - + + + - + @@ -321,11 +336,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -333,9 +352,11 @@ Davis, CA 95616, USA - + - + + + @@ -371,4 +392,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/DemandResponseLoadControl.xml b/data_model/master/clusters/DemandResponseLoadControl.xml index 1acd1ea26c6088..71c38ca9bb379f 100644 --- a/data_model/master/clusters/DemandResponseLoadControl.xml +++ b/data_model/master/clusters/DemandResponseLoadControl.xml @@ -1,59 +1,61 @@ - @@ -68,22 +70,22 @@ Davis, CA 95616, USA - + - + - + - + - + - + @@ -191,7 +193,12 @@ Davis, CA 95616, USA - + + + + + + @@ -207,73 +214,106 @@ Davis, CA 95616, USA - + + + - - + + + - - - - - - + + + + + - - + + + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - + + + - + + + - + + + - @@ -281,13 +321,13 @@ Davis, CA 95616, USA - + - + @@ -310,54 +350,72 @@ Davis, CA 95616, USA - - + + - + + + + + - + - + + + - - + + - + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + @@ -373,7 +431,9 @@ Davis, CA 95616, USA - + + + @@ -388,7 +448,9 @@ Davis, CA 95616, USA - + + + @@ -401,7 +463,9 @@ Davis, CA 95616, USA - + + + @@ -450,4 +514,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Descriptor-Cluster.xml b/data_model/master/clusters/Descriptor-Cluster.xml index fabc3a2a16c658..25597accd43bc2 100644 --- a/data_model/master/clusters/Descriptor-Cluster.xml +++ b/data_model/master/clusters/Descriptor-Cluster.xml @@ -1,61 +1,61 @@ - @@ -77,7 +77,9 @@ Davis, CA 95616, USA - + + + @@ -85,20 +87,22 @@ Davis, CA 95616, USA - + - + + + - + - + @@ -107,19 +111,26 @@ Davis, CA 95616, USA - + - + - + + + + + + - + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/DeviceEnergyManagement.xml b/data_model/master/clusters/DeviceEnergyManagement.xml index 776a06f20b3fd4..1754e9abf02de2 100644 --- a/data_model/master/clusters/DeviceEnergyManagement.xml +++ b/data_model/master/clusters/DeviceEnergyManagement.xml @@ -1,61 +1,61 @@ - @@ -65,18 +65,14 @@ Davis, CA 95616, USA - - - + - + - + @@ -94,33 +90,27 @@ Davis, CA 95616, USA - + - + - + - + - + - @@ -139,7 +129,7 @@ Davis, CA 95616, USA - + @@ -260,24 +250,30 @@ Davis, CA 95616, USA - + - + + + - + + + - + + + @@ -302,7 +298,9 @@ Davis, CA 95616, USA - + + + @@ -336,7 +334,9 @@ Davis, CA 95616, USA - + + + @@ -347,7 +347,9 @@ Davis, CA 95616, USA - + + + @@ -359,30 +361,44 @@ Davis, CA 95616, USA - + + + + + - + + + + + - + + + - + + + - + + + @@ -444,7 +460,9 @@ Davis, CA 95616, USA - + + + @@ -475,20 +493,23 @@ Davis, CA 95616, USA - + + - + - + - + + + @@ -497,18 +518,22 @@ Davis, CA 95616, USA - + + + + + - + - + @@ -527,7 +552,9 @@ Davis, CA 95616, USA - + + + @@ -538,15 +565,21 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -562,11 +595,12 @@ Davis, CA 95616, USA - + + + - @@ -576,11 +610,12 @@ Davis, CA 95616, USA - + + + - @@ -600,11 +635,12 @@ Davis, CA 95616, USA - + + + - @@ -615,11 +651,12 @@ Davis, CA 95616, USA - + + + - @@ -671,4 +708,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/DiagnosticLogsCluster.xml b/data_model/master/clusters/DiagnosticLogsCluster.xml index 9dc7f4c7ef448d..d9c22c1117829d 100644 --- a/data_model/master/clusters/DiagnosticLogsCluster.xml +++ b/data_model/master/clusters/DiagnosticLogsCluster.xml @@ -1,59 +1,61 @@ - @@ -113,7 +115,9 @@ Davis, CA 95616, USA - + + + @@ -123,14 +127,16 @@ Davis, CA 95616, USA - + + + - + - \ No newline at end of file + diff --git a/data_model/master/clusters/DiagnosticsEthernet.xml b/data_model/master/clusters/DiagnosticsEthernet.xml index f000669f64156c..dcbb3b8c5d6140 100644 --- a/data_model/master/clusters/DiagnosticsEthernet.xml +++ b/data_model/master/clusters/DiagnosticsEthernet.xml @@ -1,59 +1,61 @@ - @@ -110,57 +112,57 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + @@ -175,4 +177,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/DiagnosticsGeneral.xml b/data_model/master/clusters/DiagnosticsGeneral.xml index 1266705ba6d0dc..149ef842088d98 100644 --- a/data_model/master/clusters/DiagnosticsGeneral.xml +++ b/data_model/master/clusters/DiagnosticsGeneral.xml @@ -1,59 +1,61 @@ - @@ -75,7 +77,7 @@ Davis, CA 95616, USA - + @@ -183,7 +185,9 @@ Davis, CA 95616, USA - + + + @@ -196,18 +200,28 @@ Davis, CA 95616, USA - - + + + + + + + + - + - + + + - + - + + + @@ -219,21 +233,23 @@ Davis, CA 95616, USA - + + + - + - + - + @@ -244,19 +260,25 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -272,7 +294,9 @@ Davis, CA 95616, USA - + + + @@ -284,10 +308,10 @@ Davis, CA 95616, USA - + - + @@ -299,14 +323,18 @@ Davis, CA 95616, USA - + + + - + + + @@ -315,7 +343,9 @@ Davis, CA 95616, USA - + + + @@ -326,12 +356,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -340,12 +374,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -354,12 +392,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -370,4 +412,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/DiagnosticsSoftware.xml b/data_model/master/clusters/DiagnosticsSoftware.xml index 55e865af040763..e5331844a66057 100644 --- a/data_model/master/clusters/DiagnosticsSoftware.xml +++ b/data_model/master/clusters/DiagnosticsSoftware.xml @@ -1,59 +1,61 @@ - @@ -77,7 +79,9 @@ Davis, CA 95616, USA - + + + @@ -95,7 +99,9 @@ Davis, CA 95616, USA - + + + @@ -129,12 +135,16 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/DiagnosticsThread.xml b/data_model/master/clusters/DiagnosticsThread.xml index a55412d7fd3eff..9874ffcd0806d9 100644 --- a/data_model/master/clusters/DiagnosticsThread.xml +++ b/data_model/master/clusters/DiagnosticsThread.xml @@ -1,59 +1,61 @@ - @@ -145,25 +147,50 @@ Davis, CA 95616, USA - + + + + + + - + + + + + + - + + + + + + - + + + + + + - + + + + + + @@ -260,421 +287,441 @@ Davis, CA 95616, USA - + - + - + - + - + + + - + - + - + - + - + - + - + - + - + + + - + - + + + - + - + + + - + - + + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + - + - + + + - - + + + + + - - + + + + + @@ -699,13 +746,17 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/DiagnosticsWiFi.xml b/data_model/master/clusters/DiagnosticsWiFi.xml index 87f7e44dc92b55..19a1e6658b7f8a 100644 --- a/data_model/master/clusters/DiagnosticsWiFi.xml +++ b/data_model/master/clusters/DiagnosticsWiFi.xml @@ -1,59 +1,61 @@ - @@ -143,81 +145,88 @@ Davis, CA 95616, USA - + - + + + - + - + - + - + - + + + + + + - + - + - + - + - + - + - + - + @@ -257,4 +266,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/DishwasherAlarm.xml b/data_model/master/clusters/DishwasherAlarm.xml index bdc399f9399486..0df7564b04a9d5 100644 --- a/data_model/master/clusters/DishwasherAlarm.xml +++ b/data_model/master/clusters/DishwasherAlarm.xml @@ -1,61 +1,61 @@ - @@ -70,36 +70,36 @@ Davis, CA 95616, USA - + - + - + - + - + - + - \ No newline at end of file + diff --git a/data_model/master/clusters/DoorLock.xml b/data_model/master/clusters/DoorLock.xml index 46d659da94a690..14f1d3816f2483 100644 --- a/data_model/master/clusters/DoorLock.xml +++ b/data_model/master/clusters/DoorLock.xml @@ -1,63 +1,63 @@ - - + @@ -66,8 +66,8 @@ Davis, CA 95616, USA - + + @@ -89,7 +89,7 @@ Davis, CA 95616, USA - + @@ -125,10 +125,10 @@ Davis, CA 95616, USA - + - + @@ -215,19 +215,17 @@ Davis, CA 95616, USA - + - + - + @@ -511,8 +509,7 @@ Davis, CA 95616, USA - + @@ -532,7 +529,14 @@ Davis, CA 95616, USA - + + + + + + + + @@ -600,9 +604,6 @@ Davis, CA 95616, USA - - - @@ -718,14 +719,18 @@ Davis, CA 95616, USA - + - + + + - + + + @@ -733,11 +738,13 @@ Davis, CA 95616, USA - + - + + + @@ -759,178 +766,198 @@ Davis, CA 95616, USA - + - + - + - + - + + + - + - + + + - + - + + + - + - + - + - + - + - + - + - + + + - + - + - + - + - + + + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + - + - + + + + + + - + - + @@ -940,9 +967,9 @@ Davis, CA 95616, USA - + - + @@ -956,88 +983,104 @@ Davis, CA 95616, USA - + - - - - - - + + + + + + - + - + + + - + - + + + - + - + + + - + + + - + - + + + - + - + + + - + + + - + - + + + - + - + - + @@ -1099,12 +1142,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -1126,7 +1173,9 @@ Davis, CA 95616, USA - + + + @@ -1140,17 +1189,23 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -1169,8 +1224,14 @@ Davis, CA 95616, USA - - + + + + + + + + @@ -1200,11 +1261,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -1223,7 +1288,9 @@ Davis, CA 95616, USA - + + + @@ -1234,7 +1301,9 @@ Davis, CA 95616, USA - + + + @@ -1247,30 +1316,46 @@ Davis, CA 95616, USA - + + + + + - + + + + + - + + + - + + + - + + + - + + + @@ -1280,11 +1365,19 @@ Davis, CA 95616, USA - + + + + + - + + + + + @@ -1293,34 +1386,52 @@ Davis, CA 95616, USA - + + + + + - + + + + + - + + + - + + + - + + + - + + + - + + + @@ -1330,12 +1441,22 @@ Davis, CA 95616, USA - - + + + + + + + + - + + + + + @@ -1345,11 +1466,19 @@ Davis, CA 95616, USA - + + + + + - + + + + + @@ -1365,11 +1494,19 @@ Davis, CA 95616, USA - + + + + + - + + + + + @@ -1378,18 +1515,25 @@ Davis, CA 95616, USA - + + + + + - + + + + + - - - - + + + @@ -1402,12 +1546,22 @@ Davis, CA 95616, USA - - + + + + + + + + - + + + + + @@ -1417,7 +1571,11 @@ Davis, CA 95616, USA - + + + + + @@ -1436,7 +1594,11 @@ Davis, CA 95616, USA - + + + + + @@ -1445,17 +1607,23 @@ Davis, CA 95616, USA - + + + + + - + + + - + @@ -1471,8 +1639,14 @@ Davis, CA 95616, USA - - + + + + + + + + @@ -1491,7 +1665,9 @@ Davis, CA 95616, USA - + + + @@ -1513,7 +1689,9 @@ Davis, CA 95616, USA - + + + @@ -1524,7 +1702,9 @@ Davis, CA 95616, USA - + + + @@ -1542,17 +1722,23 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -1570,7 +1756,9 @@ Davis, CA 95616, USA - + + + @@ -1584,17 +1772,23 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -1613,8 +1807,14 @@ Davis, CA 95616, USA - - + + + + + + + + @@ -1635,17 +1835,31 @@ Davis, CA 95616, USA - - + + + + + + + + + + - + + + + + - + + + @@ -1654,19 +1868,55 @@ Davis, CA 95616, USA - - + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1680,7 +1930,11 @@ Davis, CA 95616, USA - + + + + + @@ -1689,12 +1943,18 @@ Davis, CA 95616, USA - + + + + + - + + + @@ -1711,13 +1971,19 @@ Davis, CA 95616, USA - + + + - + + + + + @@ -1730,7 +1996,11 @@ Davis, CA 95616, USA - + + + + + @@ -1740,8 +2010,14 @@ Davis, CA 95616, USA - - + + + + + + + + @@ -1751,37 +2027,87 @@ Davis, CA 95616, USA - - + + + + + + + + + + - + + + - + + + + + - - + + + + + + + + + + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1790,17 +2116,25 @@ Davis, CA 95616, USA - + + + - + + + + + - + + + @@ -1822,7 +2156,11 @@ Davis, CA 95616, USA - + + + + + @@ -1835,14 +2173,18 @@ Davis, CA 95616, USA - + + + - + + + @@ -1853,7 +2195,9 @@ Davis, CA 95616, USA - + + + @@ -1877,21 +2221,29 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -1909,7 +2261,7 @@ Davis, CA 95616, USA - + @@ -1918,7 +2270,7 @@ Davis, CA 95616, USA - + @@ -1945,10 +2297,14 @@ Davis, CA 95616, USA - + + + + + - + @@ -1978,7 +2334,11 @@ Davis, CA 95616, USA - + + + + + @@ -1994,10 +2354,26 @@ Davis, CA 95616, USA - - - - + + + + + + + + + + + + + + + + + + + + @@ -2017,4 +2393,4 @@ 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/EcosystemInformationCluster.xml similarity index 86% rename from data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml rename to data_model/master/clusters/EcosystemInformationCluster.xml index ddebe95679370e..24458e11fb41c7 100644 --- a/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml +++ b/data_model/master/clusters/EcosystemInformationCluster.xml @@ -1,61 +1,61 @@ - @@ -70,32 +70,47 @@ Davis, CA 95616, USA - + + + + + + - + + + - + + + - + - + + + - + + + - + + + @@ -107,9 +122,11 @@ Davis, CA 95616, USA - + + + - + @@ -124,14 +141,14 @@ Davis, CA 95616, USA - + - + - \ No newline at end of file + diff --git a/data_model/master/clusters/ElectricalEnergyMeasurement.xml b/data_model/master/clusters/ElectricalEnergyMeasurement.xml index 259f9f512aec02..66bc0d28800eff 100644 --- a/data_model/master/clusters/ElectricalEnergyMeasurement.xml +++ b/data_model/master/clusters/ElectricalEnergyMeasurement.xml @@ -1,65 +1,66 @@ - - + + @@ -67,16 +68,22 @@ Davis, CA 95616, USA - + - + - + - + + + + + + + @@ -109,27 +116,58 @@ Davis, CA 95616, USA - + + + + + + - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + @@ -139,7 +177,7 @@ Davis, CA 95616, USA - + @@ -149,7 +187,7 @@ Davis, CA 95616, USA - + @@ -159,7 +197,7 @@ Davis, CA 95616, USA - + @@ -169,7 +207,7 @@ Davis, CA 95616, USA - + @@ -221,4 +259,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/ElectricalPowerMeasurement.xml b/data_model/master/clusters/ElectricalPowerMeasurement.xml index 5953d36b9d992e..da5fd55718e07a 100644 --- a/data_model/master/clusters/ElectricalPowerMeasurement.xml +++ b/data_model/master/clusters/ElectricalPowerMeasurement.xml @@ -1,65 +1,66 @@ - - + + @@ -67,10 +68,10 @@ Davis, CA 95616, USA - + - + @@ -103,63 +104,88 @@ Davis, CA 95616, USA - + + + - + + + + + + - + - + + + + + + - + + + + + + - + - + + + - + - + - + + + - + - + + + - + - + - + + + @@ -170,148 +196,230 @@ Davis, CA 95616, USA - + - + + + - + - + - + + + + + - + - + + + + + - + - + + + + + + - + - + + + + + + - + - + + + + + + - + - + + + + + + - + - + + + + + + - + - + - + + + + + + - + - + - + + + + + + - + - + + + + + + - + - + + + + + + - + - + + + + + + - + - + + + + + + - + - + + + - + - + + + - + - + + + + + + - + - + + + + + + - + + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/EnergyCalendar.xml b/data_model/master/clusters/EnergyCalendar.xml deleted file mode 100644 index 2ba93203618609..00000000000000 --- a/data_model/master/clusters/EnergyCalendar.xml +++ /dev/null @@ -1,287 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/master/clusters/EnergyEVSE.xml b/data_model/master/clusters/EnergyEVSE.xml index a4c865c3096a60..203fab7502230a 100644 --- a/data_model/master/clusters/EnergyEVSE.xml +++ b/data_model/master/clusters/EnergyEVSE.xml @@ -1,61 +1,61 @@ - @@ -69,10 +69,7 @@ Davis, CA 95616, USA - - - - + @@ -97,8 +94,6 @@ Davis, CA 95616, USA - - @@ -184,7 +179,7 @@ Davis, CA 95616, USA - + @@ -200,12 +195,10 @@ Davis, CA 95616, USA - + - + @@ -240,25 +233,28 @@ Davis, CA 95616, USA - - + + + - + + + - + @@ -266,16 +262,18 @@ Davis, CA 95616, USA - + - + + + - + @@ -288,137 +286,161 @@ Davis, CA 95616, USA - + - + - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + - + - + + + - + - + - + + + - + - + - + + + - + - + + + - + - + - + - + + + - + - + + + @@ -429,7 +451,9 @@ Davis, CA 95616, USA - + + + @@ -445,11 +469,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -463,7 +491,9 @@ Davis, CA 95616, USA - + + + @@ -478,7 +508,9 @@ Davis, CA 95616, USA - + + + @@ -516,13 +548,17 @@ Davis, CA 95616, USA - + + + - + + + @@ -536,13 +572,17 @@ Davis, CA 95616, USA - + + + - + + + @@ -559,13 +599,17 @@ Davis, CA 95616, USA - + + + - + + + @@ -592,8 +636,10 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ProxyConfiguration-Cluster.xml b/data_model/master/clusters/EnergyMetering.xml similarity index 74% rename from data_model/master/clusters/ProxyConfiguration-Cluster.xml rename to data_model/master/clusters/EnergyMetering.xml index 6796e79ac9bf59..3c13cd3941df80 100644 --- a/data_model/master/clusters/ProxyConfiguration-Cluster.xml +++ b/data_model/master/clusters/EnergyMetering.xml @@ -1,91 +1,92 @@ - - + - + - - - + - + - - - + + + - - - - + - - - - - + + + + + + + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/EnergyPreference.xml b/data_model/master/clusters/EnergyPreference.xml index 2534ccfc8474c6..26c17221027427 100644 --- a/data_model/master/clusters/EnergyPreference.xml +++ b/data_model/master/clusters/EnergyPreference.xml @@ -1,61 +1,61 @@ - @@ -69,10 +69,10 @@ Davis, CA 95616, USA - + - + @@ -92,11 +92,15 @@ Davis, CA 95616, USA + + - + + + @@ -104,15 +108,20 @@ Davis, CA 95616, USA - + - + + + + + + - + @@ -120,27 +129,34 @@ Davis, CA 95616, USA - + - + + + - + - + + + + + + - + - \ No newline at end of file + diff --git a/data_model/master/clusters/EnergyPrice.xml b/data_model/master/clusters/EnergyPrice.xml index aae07641398eeb..69d61200f92c6e 100644 --- a/data_model/master/clusters/EnergyPrice.xml +++ b/data_model/master/clusters/EnergyPrice.xml @@ -1,61 +1,61 @@ - @@ -74,41 +74,7 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -116,20 +82,25 @@ Davis, CA 95616, USA - - + + - + - + + + + + + - + @@ -137,40 +108,37 @@ Davis, CA 95616, USA - - - - - - - + - - + - + + + - - + + - + + + - + - + - + - + @@ -181,7 +149,7 @@ Davis, CA 95616, USA - + @@ -189,7 +157,7 @@ Davis, CA 95616, USA - + @@ -199,7 +167,7 @@ Davis, CA 95616, USA - + @@ -208,7 +176,7 @@ Davis, CA 95616, USA - + @@ -217,7 +185,7 @@ Davis, CA 95616, USA - + @@ -225,9 +193,9 @@ Davis, CA 95616, USA - + - \ No newline at end of file + diff --git a/data_model/master/clusters/EnergyTariff.xml b/data_model/master/clusters/EnergyTariff.xml new file mode 100644 index 00000000000000..6b00047d173fea --- /dev/null +++ b/data_model/master/clusters/EnergyTariff.xml @@ -0,0 +1,568 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/FanControl.xml b/data_model/master/clusters/FanControl.xml index ec05b6f74e069d..325d0f5316e8ab 100644 --- a/data_model/master/clusters/FanControl.xml +++ b/data_model/master/clusters/FanControl.xml @@ -1,68 +1,69 @@ - - + + @@ -101,8 +102,14 @@ Davis, CA 95616, USA - - + + + + + + + + @@ -134,17 +141,17 @@ Davis, CA 95616, USA - + - + - + @@ -187,95 +194,118 @@ Davis, CA 95616, USA - + - - - - - - - + + + - + - + - + + + - + + + - + - + + + + + + - + - + + + + + - + - + + + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + @@ -295,4 +325,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/FlowMeasurement.xml b/data_model/master/clusters/FlowMeasurement.xml index 7ee97f586e708a..4742dbfd95c80c 100644 --- a/data_model/master/clusters/FlowMeasurement.xml +++ b/data_model/master/clusters/FlowMeasurement.xml @@ -1,61 +1,61 @@ - @@ -70,26 +70,37 @@ Davis, CA 95616, USA - + - + + + + + + - + - + + + - + - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/GeneralCommissioningCluster.xml b/data_model/master/clusters/GeneralCommissioningCluster.xml index 2342e6704c25c8..ada2cbb5ea8041 100644 --- a/data_model/master/clusters/GeneralCommissioningCluster.xml +++ b/data_model/master/clusters/GeneralCommissioningCluster.xml @@ -1,59 +1,61 @@ - @@ -66,7 +68,7 @@ Davis, CA 95616, USA - + @@ -74,34 +76,51 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + @@ -119,7 +138,9 @@ Davis, CA 95616, USA - + + + @@ -130,58 +151,90 @@ Davis, CA 95616, USA - + - + + + - + + - + + - + - + - - - - + + + + + + + - - - - + + + + + + + - - - - + + + + + + + - - - - + + + + + + + - - - - + + + + + + + + + + + + + + + + + + + + @@ -197,12 +250,14 @@ Davis, CA 95616, USA - + - + - + + + @@ -213,7 +268,9 @@ Davis, CA 95616, USA - + + + @@ -221,10 +278,10 @@ Davis, CA 95616, USA - + - + @@ -234,18 +291,21 @@ Davis, CA 95616, USA - + - + - - - + + + + + + @@ -254,12 +314,15 @@ Davis, CA 95616, USA - - - - + + + + + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/Group-Key-Management-Cluster.xml b/data_model/master/clusters/Group-Key-Management-Cluster.xml index 784bdc903ec186..31b3fb153e81ed 100644 --- a/data_model/master/clusters/Group-Key-Management-Cluster.xml +++ b/data_model/master/clusters/Group-Key-Management-Cluster.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,7 @@ Davis, CA 95616, USA - + @@ -95,11 +97,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -109,7 +115,12 @@ Davis, CA 95616, USA - + + + + + + @@ -125,7 +136,9 @@ Davis, CA 95616, USA - + + + @@ -136,7 +149,9 @@ Davis, CA 95616, USA - + + + @@ -147,7 +162,9 @@ Davis, CA 95616, USA - + + + @@ -167,64 +184,73 @@ Davis, CA 95616, USA - + - + + + - + + + - + - + - + + + + + + - + - + - + - + - + - + - + @@ -232,4 +258,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Groups.xml b/data_model/master/clusters/Groups.xml index 214e6c18280afa..e580c607c273b6 100644 --- a/data_model/master/clusters/Groups.xml +++ b/data_model/master/clusters/Groups.xml @@ -1,61 +1,61 @@ - @@ -83,9 +83,11 @@ Davis, CA 95616, USA - + - + + + @@ -94,22 +96,30 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -117,22 +127,30 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -140,7 +158,9 @@ Davis, CA 95616, USA - + + + @@ -153,7 +173,9 @@ Davis, CA 95616, USA - + + + @@ -163,18 +185,24 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -186,12 +214,16 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/Humidistat.xml b/data_model/master/clusters/Humidistat.xml deleted file mode 100644 index 1af54698489d31..00000000000000 --- a/data_model/master/clusters/Humidistat.xml +++ /dev/null @@ -1,283 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/data_model/master/clusters/ICDManagement.xml b/data_model/master/clusters/ICDManagement.xml index 830f62fba2a63f..160a57675e9faa 100644 --- a/data_model/master/clusters/ICDManagement.xml +++ b/data_model/master/clusters/ICDManagement.xml @@ -1,61 +1,61 @@ - @@ -64,13 +64,12 @@ Davis, CA 95616, USA - + - @@ -79,7 +78,6 @@ Davis, CA 95616, USA - @@ -87,23 +85,23 @@ Davis, CA 95616, USA - - - - + - - - - - - + + + - - + + + + + + + + @@ -112,13 +110,68 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -126,6 +179,7 @@ Davis, CA 95616, USA + @@ -134,76 +188,87 @@ Davis, CA 95616, USA - + - + + + + + + - + - + - + - + - + + + - + - + - + + + - - - - - - - - + + + + + + + - + - - + + + + - - - - - - + + + - + - + + + + + @@ -220,11 +285,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -248,7 +317,9 @@ Davis, CA 95616, USA - + + + @@ -272,8 +343,10 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/Identify.xml b/data_model/master/clusters/Identify.xml index ddc3e33e9d28d3..4e334059260fe6 100644 --- a/data_model/master/clusters/Identify.xml +++ b/data_model/master/clusters/Identify.xml @@ -1,61 +1,61 @@ - @@ -74,18 +74,16 @@ Davis, CA 95616, USA - - - - + + + + @@ -113,8 +111,7 @@ Davis, CA 95616, USA - + @@ -127,7 +124,9 @@ Davis, CA 95616, USA - + + + @@ -143,12 +142,16 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/IlluminanceMeasurement.xml b/data_model/master/clusters/IlluminanceMeasurement.xml index d7cb9a993d0e4e..49e12a15d34b03 100644 --- a/data_model/master/clusters/IlluminanceMeasurement.xml +++ b/data_model/master/clusters/IlluminanceMeasurement.xml @@ -1,61 +1,61 @@ - @@ -75,40 +75,53 @@ Davis, CA 95616, USA - - - - + - - + + + + + + + + + - + - + + + + + + - + - + + + - + + + - + - \ No newline at end of file + diff --git a/data_model/master/clusters/JointFabricDatastoreCluster.xml b/data_model/master/clusters/JointFabricDatastoreCluster.xml index 137edd2857f74d..2518224ce49d7d 100644 --- a/data_model/master/clusters/JointFabricDatastoreCluster.xml +++ b/data_model/master/clusters/JointFabricDatastoreCluster.xml @@ -1,66 +1,70 @@ - - + + + @@ -74,160 +78,179 @@ Davis, CA 95616, USA + + + - + - - - + - - + - + - - - + + + - - - + + + - + + + + + + + + + + + + + + + + - - - - + + + - - + - - + + - - + + - + - - - + - + - - - + + + - - + + + + + + - - + + + + + + - - + + + + + + - - + - + - - - + + + - - + - - + + - - + - - + + - + - - - + - + - - - + + + + @@ -235,66 +258,72 @@ Davis, CA 95616, USA - + - + - + - + - + + + - - + + + - - + + + - - + + + - - + + + - - + + - + - + - + - + - + - + @@ -302,25 +331,42 @@ Davis, CA 95616, USA - + + + - + + + + + + - + + + + + + - + + + + + + - + - + @@ -329,43 +375,59 @@ Davis, CA 95616, USA - + + + - + + + + + + - + + + + + + - + + + + + + - + - - + - + - + - + @@ -375,22 +437,26 @@ Davis, CA 95616, USA - + + + - + + + - + - + @@ -398,17 +464,19 @@ Davis, CA 95616, USA - + + + - + - + @@ -416,17 +484,19 @@ Davis, CA 95616, USA - + + + - + - + @@ -437,10 +507,12 @@ Davis, CA 95616, USA - + + + - + @@ -453,7 +525,7 @@ Davis, CA 95616, USA - + @@ -466,7 +538,7 @@ Davis, CA 95616, USA - + @@ -475,11 +547,11 @@ Davis, CA 95616, USA - + - + @@ -492,17 +564,17 @@ Davis, CA 95616, USA - + - + - + @@ -513,4 +585,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/JointFabricPKICluster.xml b/data_model/master/clusters/JointFabricPKICluster.xml index 847d2548e3b1f1..3e703831c6fa7a 100644 --- a/data_model/master/clusters/JointFabricPKICluster.xml +++ b/data_model/master/clusters/JointFabricPKICluster.xml @@ -1,140 +1,147 @@ - - + + + - - + + - + - + - + - + - + - + - + - - + + - + - + - + - + - + + + - + - + - + - + + + - + - - + - + - + - \ No newline at end of file + diff --git a/data_model/master/clusters/KeypadInput.xml b/data_model/master/clusters/KeypadInput.xml index efeb92ba28fb73..faded2ff95b5fa 100644 --- a/data_model/master/clusters/KeypadInput.xml +++ b/data_model/master/clusters/KeypadInput.xml @@ -1,61 +1,61 @@ - @@ -81,100 +81,58 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -207,6 +165,18 @@ Davis, CA 95616, USA + + + + + + + + + + + + @@ -264,6 +234,24 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + @@ -318,6 +306,18 @@ Davis, CA 95616, USA + + + + + + + + + + + + @@ -344,7 +344,7 @@ Davis, CA 95616, USA - + @@ -364,4 +364,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml b/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml index a172d1e281eff5..12bec55222c379 100644 --- a/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-FixedLabelCluster.xml @@ -1,61 +1,61 @@ - @@ -65,13 +65,12 @@ Davis, CA 95616, USA - - + - \ No newline at end of file + diff --git a/data_model/master/clusters/Label-Cluster-LabelCluster.xml b/data_model/master/clusters/Label-Cluster-LabelCluster.xml index 2f8a371f74042c..b9cd9e7f440578 100644 --- a/data_model/master/clusters/Label-Cluster-LabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-LabelCluster.xml @@ -1,63 +1,63 @@ - - + @@ -69,20 +69,22 @@ Davis, CA 95616, USA - + + + - + + + - - - \ No newline at end of file + diff --git a/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml b/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml index 466550f12520f1..449e0b38b98f70 100644 --- a/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml +++ b/data_model/master/clusters/Label-Cluster-UserLabelCluster.xml @@ -1,61 +1,61 @@ - @@ -65,14 +65,12 @@ Davis, CA 95616, USA - - + - - \ No newline at end of file + diff --git a/data_model/master/clusters/LaundryDryerControls.xml b/data_model/master/clusters/LaundryDryerControls.xml index 85f7871b267be5..b7549bbeadf842 100644 --- a/data_model/master/clusters/LaundryDryerControls.xml +++ b/data_model/master/clusters/LaundryDryerControls.xml @@ -1,59 +1,61 @@ - @@ -84,13 +86,20 @@ Davis, CA 95616, USA - + + + + + + - + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/LaundryWasherControls.xml b/data_model/master/clusters/LaundryWasherControls.xml index 046ecc3c51d697..350b5c0da4fe1f 100644 --- a/data_model/master/clusters/LaundryWasherControls.xml +++ b/data_model/master/clusters/LaundryWasherControls.xml @@ -1,59 +1,61 @@ - @@ -66,10 +68,10 @@ Davis, CA 95616, USA - + - + @@ -99,28 +101,36 @@ Davis, CA 95616, USA - + + + - + + + - + - + + + - + + + @@ -128,7 +138,9 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/LevelControl.xml b/data_model/master/clusters/LevelControl.xml index de342812287b0f..4cb5e944963df1 100644 --- a/data_model/master/clusters/LevelControl.xml +++ b/data_model/master/clusters/LevelControl.xml @@ -1,86 +1,83 @@ - - + - + - + - + - + @@ -120,13 +117,18 @@ Davis, CA 95616, USA - + - + + + + + + - + @@ -136,7 +138,12 @@ Davis, CA 95616, USA - + + + + + + @@ -145,38 +152,55 @@ Davis, CA 95616, USA + + + - + + + + + - + - + + + + + + - - + + + + + - + + + @@ -184,33 +208,42 @@ Davis, CA 95616, USA - + - + + + + + + - + - + - + - + + + - + - + + + @@ -219,7 +252,9 @@ Davis, CA 95616, USA - + + + @@ -227,11 +262,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -239,7 +278,9 @@ Davis, CA 95616, USA - + + + @@ -247,11 +288,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -259,7 +304,9 @@ Davis, CA 95616, USA - + + + @@ -270,11 +317,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -282,11 +333,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -315,4 +370,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/LocalizationConfiguration.xml b/data_model/master/clusters/LocalizationConfiguration.xml index 6bc3abd50600ab..02860ea80d4241 100644 --- a/data_model/master/clusters/LocalizationConfiguration.xml +++ b/data_model/master/clusters/LocalizationConfiguration.xml @@ -1,59 +1,61 @@ - @@ -66,18 +68,24 @@ Davis, CA 95616, USA - + - + + + - + + + - + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/LocalizationTimeFormat.xml b/data_model/master/clusters/LocalizationTimeFormat.xml index 2de3724879701d..a9b3c47accef87 100644 --- a/data_model/master/clusters/LocalizationTimeFormat.xml +++ b/data_model/master/clusters/LocalizationTimeFormat.xml @@ -1,59 +1,61 @@ - @@ -71,43 +73,43 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -125,24 +127,26 @@ Davis, CA 95616, USA - + - + - + - + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/LocalizationUnit.xml b/data_model/master/clusters/LocalizationUnit.xml index e08ce0e8810f26..7a356c528e88db 100644 --- a/data_model/master/clusters/LocalizationUnit.xml +++ b/data_model/master/clusters/LocalizationUnit.xml @@ -1,59 +1,61 @@ - @@ -84,10 +86,10 @@ Davis, CA 95616, USA - + - \ No newline at end of file + diff --git a/data_model/master/clusters/LowPower.xml b/data_model/master/clusters/LowPower.xml index 2e91a02c16a4b3..f92019ed2b91ff 100644 --- a/data_model/master/clusters/LowPower.xml +++ b/data_model/master/clusters/LowPower.xml @@ -1,61 +1,61 @@ - @@ -71,4 +71,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/MediaInput.xml b/data_model/master/clusters/MediaInput.xml index c01567f6e1ae3e..1a60d075716047 100644 --- a/data_model/master/clusters/MediaInput.xml +++ b/data_model/master/clusters/MediaInput.xml @@ -1,61 +1,61 @@ - @@ -115,7 +115,9 @@ Davis, CA 95616, USA - + + + @@ -165,4 +167,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/MediaPlayback.xml b/data_model/master/clusters/MediaPlayback.xml index e37d5944aeb366..8971950ddb4b04 100644 --- a/data_model/master/clusters/MediaPlayback.xml +++ b/data_model/master/clusters/MediaPlayback.xml @@ -1,61 +1,61 @@ - @@ -161,15 +161,13 @@ Davis, CA 95616, USA - + - + @@ -192,7 +190,9 @@ Davis, CA 95616, USA - + + + @@ -202,13 +202,17 @@ Davis, CA 95616, USA - + + + - + + + @@ -219,88 +223,110 @@ Davis, CA 95616, USA - + + + - + - + + + - + - + + + - + - + + + - + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + @@ -368,7 +394,9 @@ Davis, CA 95616, USA - + + + @@ -390,7 +418,9 @@ Davis, CA 95616, USA - + + + @@ -406,7 +436,9 @@ Davis, CA 95616, USA - + + + @@ -422,54 +454,72 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/Messages.xml b/data_model/master/clusters/Messages.xml index d2dbd28ba87f81..780b77f6b43121 100644 --- a/data_model/master/clusters/Messages.xml +++ b/data_model/master/clusters/Messages.xml @@ -1,100 +1,61 @@ - @@ -125,7 +86,6 @@ Davis, CA 95616, USA - @@ -187,17 +147,24 @@ Davis, CA 95616, USA - + + + - + + + - + + + + @@ -220,7 +187,9 @@ Davis, CA 95616, USA - + + + @@ -228,7 +197,9 @@ Davis, CA 95616, USA - + + + @@ -238,21 +209,28 @@ Davis, CA 95616, USA - + + + - + - + + + - + + + + @@ -270,46 +248,61 @@ Davis, CA 95616, USA - + + + - + + + - + - + + + - + - + + + + - + - + + + + - + - + + + + @@ -322,7 +315,9 @@ Davis, CA 95616, USA - + + + @@ -330,4 +325,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/MeterIdentification.xml b/data_model/master/clusters/MeterIdentification.xml index 1ed47d5d3da3af..ebb0bcf7e7865a 100644 --- a/data_model/master/clusters/MeterIdentification.xml +++ b/data_model/master/clusters/MeterIdentification.xml @@ -1,61 +1,61 @@ - @@ -82,49 +82,43 @@ Davis, CA 95616, USA - - - - - - - - - - - - + - + - + - + - + + + - + - + - + + + - + - - - - + + + + + - + - + - \ No newline at end of file + diff --git a/data_model/master/clusters/MicrowaveOvenControl.xml b/data_model/master/clusters/MicrowaveOvenControl.xml index 2169f7b1437945..691ac0a971b898 100644 --- a/data_model/master/clusters/MicrowaveOvenControl.xml +++ b/data_model/master/clusters/MicrowaveOvenControl.xml @@ -1,61 +1,61 @@ - @@ -85,56 +85,84 @@ Davis, CA 95616, USA - + + + + + - + - + + + + + + - + + + - + - + + + + + + - + - + + + + + + - + - + + + - + - + + + + + + @@ -144,11 +172,13 @@ Davis, CA 95616, USA - + + + - + @@ -157,24 +187,37 @@ Davis, CA 95616, USA - - + + + + - - + + + + + + - + - + + + + + + - + - + + + @@ -185,8 +228,12 @@ Davis, CA 95616, USA - + + + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ModeBase.xml b/data_model/master/clusters/ModeBase.xml index c874eee69d3eb6..cb5bb20046838d 100644 --- a/data_model/master/clusters/ModeBase.xml +++ b/data_model/master/clusters/ModeBase.xml @@ -1,65 +1,66 @@ - - + - + @@ -73,22 +74,31 @@ Davis, CA 95616, USA + - + + + + + - + + + - + + + @@ -99,29 +109,40 @@ Davis, CA 95616, USA - + - + + + + + + - + - + + + - + - + + + - + - + + + @@ -130,29 +151,33 @@ Davis, CA 95616, USA - + + + - - - - - - - - - - - - + + + - + + + + + + + + + + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ModeSelect.xml b/data_model/master/clusters/ModeSelect.xml index 6e6f062182e503..32ce055135fdc6 100644 --- a/data_model/master/clusters/ModeSelect.xml +++ b/data_model/master/clusters/ModeSelect.xml @@ -1,59 +1,61 @@ - @@ -72,24 +74,35 @@ Davis, CA 95616, USA + - + + + + + - + + + + - + + + + @@ -97,42 +110,54 @@ Davis, CA 95616, USA - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + @@ -141,8 +166,10 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml index 48cf6df4955a15..0dce72ebf11bc1 100644 --- a/data_model/master/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/master/clusters/Mode_DeviceEnergyManagement.xml @@ -1,61 +1,61 @@ - @@ -63,9 +63,7 @@ Davis, CA 95616, USA - - - + @@ -74,6 +72,22 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + @@ -83,17 +97,18 @@ Davis, CA 95616, USA - + + + + + + - - - - - - + + @@ -101,4 +116,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Mode_Dishwasher.xml b/data_model/master/clusters/Mode_Dishwasher.xml index 1c3a99b9e3d245..6ded4ff2d5100c 100644 --- a/data_model/master/clusters/Mode_Dishwasher.xml +++ b/data_model/master/clusters/Mode_Dishwasher.xml @@ -1,66 +1,67 @@ - - + + @@ -72,6 +73,21 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + @@ -81,7 +97,12 @@ Davis, CA 95616, USA - + + + + + + @@ -99,4 +120,4 @@ 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 025e9de9884c89..2571699e61904b 100644 --- a/data_model/master/clusters/Mode_EVSE.xml +++ b/data_model/master/clusters/Mode_EVSE.xml @@ -1,66 +1,66 @@ - - + @@ -72,6 +72,22 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + @@ -81,17 +97,18 @@ Davis, CA 95616, USA - + + + + + + - - - - - - + + @@ -99,4 +116,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Mode_LaundryWasher.xml b/data_model/master/clusters/Mode_LaundryWasher.xml index b5f557a4b46a4b..7c1262bb8f3011 100644 --- a/data_model/master/clusters/Mode_LaundryWasher.xml +++ b/data_model/master/clusters/Mode_LaundryWasher.xml @@ -1,66 +1,67 @@ - - + + @@ -72,6 +73,22 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + @@ -81,7 +98,12 @@ Davis, CA 95616, USA - + + + + + + @@ -99,4 +121,4 @@ 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 24d682fecac68b..e8c7f8a0145cc3 100644 --- a/data_model/master/clusters/Mode_MicrowaveOven.xml +++ b/data_model/master/clusters/Mode_MicrowaveOven.xml @@ -1,65 +1,66 @@ - - + + @@ -70,13 +71,25 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + - - - - - - + + @@ -92,4 +105,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Mode_Oven.xml b/data_model/master/clusters/Mode_Oven.xml index a3e3323fe98777..d7180d0e6342b9 100644 --- a/data_model/master/clusters/Mode_Oven.xml +++ b/data_model/master/clusters/Mode_Oven.xml @@ -1,65 +1,66 @@ - - + + @@ -71,6 +72,28 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + @@ -80,17 +103,18 @@ Davis, CA 95616, USA - + + + + + + - - - - - - + + @@ -98,4 +122,4 @@ 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 4ead99f0915adf..c8d399b425e7bf 100644 --- a/data_model/master/clusters/Mode_RVCClean.xml +++ b/data_model/master/clusters/Mode_RVCClean.xml @@ -1,67 +1,68 @@ - - + + @@ -71,11 +72,27 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + @@ -85,17 +102,18 @@ Davis, CA 95616, USA - + + + + + + - - - - - - + + @@ -103,4 +121,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Mode_RVCRun.xml b/data_model/master/clusters/Mode_RVCRun.xml index f1d89e4c747106..dfd0bef99edec2 100644 --- a/data_model/master/clusters/Mode_RVCRun.xml +++ b/data_model/master/clusters/Mode_RVCRun.xml @@ -1,61 +1,61 @@ - @@ -71,11 +71,26 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + @@ -85,17 +100,18 @@ Davis, CA 95616, USA - + + + + + + - - - - - - + + @@ -103,4 +119,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Mode_Refrigerator.xml b/data_model/master/clusters/Mode_Refrigerator.xml index 2728ac0f42b8fb..49ac574a03cc78 100644 --- a/data_model/master/clusters/Mode_Refrigerator.xml +++ b/data_model/master/clusters/Mode_Refrigerator.xml @@ -1,66 +1,67 @@ - - + + @@ -72,6 +73,20 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + @@ -81,7 +96,12 @@ Davis, CA 95616, USA - + + + + + + @@ -99,4 +119,4 @@ 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 cc9c96e484bce2..b5ba06b62ade90 100644 --- a/data_model/master/clusters/Mode_WaterHeater.xml +++ b/data_model/master/clusters/Mode_WaterHeater.xml @@ -1,61 +1,61 @@ - @@ -71,6 +71,21 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + @@ -80,17 +95,18 @@ Davis, CA 95616, USA - + + + + + + - - - - - - + + @@ -98,4 +114,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/NetworkCommissioningCluster.xml b/data_model/master/clusters/NetworkCommissioningCluster.xml index 8eefb234a2920a..c30e0c569e0fe8 100644 --- a/data_model/master/clusters/NetworkCommissioningCluster.xml +++ b/data_model/master/clusters/NetworkCommissioningCluster.xml @@ -1,65 +1,66 @@ - - + - @@ -75,72 +76,67 @@ Davis, CA 95616, USA - - - - - - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -176,41 +172,29 @@ Davis, CA 95616, USA - - - - + + + + + + - - - - - - - - - - - - - - - - - + + + @@ -221,7 +205,12 @@ Davis, CA 95616, USA - + + + + + + @@ -237,6 +226,12 @@ Davis, CA 95616, USA + + + + + + @@ -259,13 +254,17 @@ Davis, CA 95616, USA - + + + - + + + @@ -287,78 +286,95 @@ Davis, CA 95616, USA - + - + + + - + + + + + - + - + + + - + - + + + - + - + - + - + + + + + + - + - + - + + + - + - + @@ -378,7 +394,12 @@ Davis, CA 95616, USA - + + + + + + @@ -393,25 +414,33 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + @@ -421,39 +450,19 @@ Davis, CA 95616, USA - + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - @@ -462,7 +471,9 @@ Davis, CA 95616, USA - + + + @@ -478,7 +489,12 @@ Davis, CA 95616, USA - + + + + + + @@ -493,27 +509,26 @@ Davis, CA 95616, USA - + + + - + + + - - - - - - - - - - - - - - + + + + + + + + + @@ -526,7 +541,12 @@ Davis, CA 95616, USA - + + + + + + @@ -560,42 +580,22 @@ Davis, CA 95616, USA - + + + + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file + diff --git a/data_model/master/clusters/OTAProvider.xml b/data_model/master/clusters/OTAProvider.xml index f300a419518675..8676524416ff93 100644 --- a/data_model/master/clusters/OTAProvider.xml +++ b/data_model/master/clusters/OTAProvider.xml @@ -1,59 +1,61 @@ - @@ -120,21 +122,27 @@ Davis, CA 95616, USA - + + + - + + + - + - + + + @@ -143,29 +151,68 @@ Davis, CA 95616, USA - + + + + + + - - + + + + + + + + + - + + + + + + - - + + + + + + + + + + + + - - + + + + + + + + + + + + - + - + + + @@ -173,7 +220,12 @@ Davis, CA 95616, USA - + + + + + + @@ -193,11 +245,16 @@ Davis, CA 95616, USA - + + + + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/OTARequestor.xml b/data_model/master/clusters/OTARequestor.xml index ea7ec03c717fd3..a95fa074397ebf 100644 --- a/data_model/master/clusters/OTARequestor.xml +++ b/data_model/master/clusters/OTARequestor.xml @@ -1,59 +1,61 @@ - @@ -71,8 +73,7 @@ Davis, CA 95616, USA - + @@ -133,26 +134,34 @@ Davis, CA 95616, USA - + - + - + + + - + - + + - + - + + + + + + @@ -170,7 +179,9 @@ Davis, CA 95616, USA - + + + @@ -217,7 +228,12 @@ Davis, CA 95616, USA - + + + + + + @@ -225,4 +241,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/OccupancySensing.xml b/data_model/master/clusters/OccupancySensing.xml index 7ca0d3631dbe05..3c34f3ab008c82 100644 --- a/data_model/master/clusters/OccupancySensing.xml +++ b/data_model/master/clusters/OccupancySensing.xml @@ -1,61 +1,61 @@ - @@ -63,13 +63,7 @@ Davis, CA 95616, USA - + @@ -77,28 +71,28 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + @@ -135,60 +129,94 @@ Davis, CA 95616, USA - + + + - - + + + + + + + + - + + + + + + - + - + + + + + + - + - + + + - + - + + + + + + - + - + - + + + + + + + + + + - + - + @@ -214,7 +242,7 @@ Davis, CA 95616, USA - + @@ -262,7 +290,7 @@ Davis, CA 95616, USA - + @@ -307,11 +335,16 @@ Davis, CA 95616, USA - + + + + + + - + @@ -324,7 +357,7 @@ Davis, CA 95616, USA - + @@ -344,7 +377,7 @@ Davis, CA 95616, USA - + @@ -361,11 +394,16 @@ Davis, CA 95616, USA - + + + + + + - + @@ -378,7 +416,7 @@ Davis, CA 95616, USA - + @@ -398,7 +436,7 @@ Davis, CA 95616, USA - + @@ -415,7 +453,12 @@ Davis, CA 95616, USA - + + + + + + @@ -427,4 +470,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/OnOff.xml b/data_model/master/clusters/OnOff.xml index b1ea6ebba4af7d..a58d4fcdf653c1 100644 --- a/data_model/master/clusters/OnOff.xml +++ b/data_model/master/clusters/OnOff.xml @@ -1,61 +1,61 @@ - @@ -78,7 +78,7 @@ Davis, CA 95616, USA - + @@ -128,11 +128,7 @@ Davis, CA 95616, USA - + @@ -143,12 +139,12 @@ Davis, CA 95616, USA - + - + - + @@ -168,11 +164,13 @@ Davis, CA 95616, USA - + - + + + @@ -203,11 +201,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -223,16 +225,25 @@ Davis, CA 95616, USA - + + + + + + - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/OperationalCredentialCluster.xml b/data_model/master/clusters/OperationalCredentialCluster.xml index 338a8af007c5b9..aa4f1f1be02cdd 100644 --- a/data_model/master/clusters/OperationalCredentialCluster.xml +++ b/data_model/master/clusters/OperationalCredentialCluster.xml @@ -1,74 +1,72 @@ - - + + - + - - - - - @@ -81,48 +79,52 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + - + - + - + - + - + + + - + + + @@ -130,23 +132,39 @@ Davis, CA 95616, USA - + - + + + + + + + + + - - + + + - - + + + + + + + + + @@ -155,37 +173,60 @@ Davis, CA 95616, USA - + - + + + + + - + - + + + + + - + - + + + + + + - + - + + + + + - + + + - + - + + + + + @@ -198,18 +239,26 @@ Davis, CA 95616, USA - + + + - + + + + + - + + + @@ -217,14 +266,18 @@ Davis, CA 95616, USA - + + + - + + + @@ -232,7 +285,9 @@ Davis, CA 95616, USA - + + + @@ -242,11 +297,17 @@ Davis, CA 95616, USA - + + + + + - + + + @@ -254,17 +315,23 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + @@ -276,11 +343,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -289,12 +360,27 @@ Davis, CA 95616, USA - - + + + + + + + + + + + + + + + - + + + @@ -302,7 +388,9 @@ Davis, CA 95616, USA - + + + @@ -310,7 +398,12 @@ Davis, CA 95616, USA - + + + + + + @@ -318,8 +411,75 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/OperationalState.xml b/data_model/master/clusters/OperationalState.xml index 354efa2400bda7..d4520a072e6a34 100644 --- a/data_model/master/clusters/OperationalState.xml +++ b/data_model/master/clusters/OperationalState.xml @@ -1,59 +1,61 @@ - @@ -67,24 +69,30 @@ Davis, CA 95616, USA - + - + - + + + + - + + + + - + - + @@ -93,11 +101,27 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + - + + + @@ -105,37 +129,61 @@ Davis, CA 95616, USA - + + + + + + + + + + + + + + + - + + + - + - + + + - + - + + + - + - + + + - + + + @@ -144,7 +192,9 @@ Davis, CA 95616, USA - + + + @@ -203,10 +253,7 @@ Davis, CA 95616, USA - - - - + @@ -220,4 +267,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/OperationalState_Oven.xml b/data_model/master/clusters/OperationalState_Oven.xml index 710dea9806bf57..c49426d6026dd0 100644 --- a/data_model/master/clusters/OperationalState_Oven.xml +++ b/data_model/master/clusters/OperationalState_Oven.xml @@ -1,65 +1,66 @@ - - + + @@ -76,4 +77,4 @@ 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 9b83bc4dfde257..2e334eeffec1e7 100644 --- a/data_model/master/clusters/OperationalState_RVC.xml +++ b/data_model/master/clusters/OperationalState_RVC.xml @@ -1,66 +1,67 @@ - - + + @@ -68,6 +69,18 @@ Davis, CA 95616, USA + + + + + + + + + + + + @@ -80,10 +93,10 @@ Davis, CA 95616, USA - + - + @@ -92,8 +105,41 @@ Davis, CA 95616, USA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -103,6 +149,18 @@ Davis, CA 95616, USA + + + + + + + + + + + + @@ -117,10 +175,7 @@ Davis, CA 95616, USA - - - - + - \ No newline at end of file + diff --git a/data_model/master/clusters/PowerSourceCluster.xml b/data_model/master/clusters/PowerSourceCluster.xml index a0b6b91c565dd8..a90b69a7756d3d 100644 --- a/data_model/master/clusters/PowerSourceCluster.xml +++ b/data_model/master/clusters/PowerSourceCluster.xml @@ -1,59 +1,61 @@ - @@ -67,10 +69,10 @@ Davis, CA 95616, USA - + - + @@ -553,58 +555,64 @@ Davis, CA 95616, USA - + + + - + - + - + + + - + - + - + - + + + - + - + - + @@ -621,26 +629,30 @@ Davis, CA 95616, USA - + + + - + - + - + + + - + @@ -650,7 +662,9 @@ Davis, CA 95616, USA - + + + @@ -660,7 +674,7 @@ Davis, CA 95616, USA - + @@ -677,51 +691,63 @@ Davis, CA 95616, USA - + + + - + - + + + - + - + + + - + - + + + - + - + + + - + - + + + - + @@ -731,7 +757,7 @@ Davis, CA 95616, USA - + @@ -741,11 +767,13 @@ Davis, CA 95616, USA - + + + - + @@ -758,7 +786,7 @@ Davis, CA 95616, USA - + @@ -769,7 +797,9 @@ Davis, CA 95616, USA - + + + @@ -786,12 +816,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -802,12 +836,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -818,13 +856,17 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/PowerSourceConfigurationCluster.xml b/data_model/master/clusters/PowerSourceConfigurationCluster.xml index 61df60149ca00f..6fdce527526462 100644 --- a/data_model/master/clusters/PowerSourceConfigurationCluster.xml +++ b/data_model/master/clusters/PowerSourceConfigurationCluster.xml @@ -1,59 +1,61 @@ - @@ -67,9 +69,11 @@ Davis, CA 95616, USA - + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/PowerTopology.xml b/data_model/master/clusters/PowerTopology.xml index eb0a2d74f5e585..077100432e55e0 100644 --- a/data_model/master/clusters/PowerTopology.xml +++ b/data_model/master/clusters/PowerTopology.xml @@ -1,59 +1,61 @@ - @@ -83,20 +85,24 @@ Davis, CA 95616, USA - + - + + + - + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/PressureMeasurement.xml b/data_model/master/clusters/PressureMeasurement.xml index 09b9577cc84585..8d299bd7c5e126 100644 --- a/data_model/master/clusters/PressureMeasurement.xml +++ b/data_model/master/clusters/PressureMeasurement.xml @@ -1,61 +1,61 @@ - @@ -75,64 +75,94 @@ Davis, CA 95616, USA - + - + + + + + + - + - + + + - + - + + + + + + - + + + - + - + + + + + + - + - + + + - + - + + + + + + - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/PumpConfigurationControl.xml b/data_model/master/clusters/PumpConfigurationControl.xml index 9b7e4ab56dc5c2..b652c5286f4b68 100644 --- a/data_model/master/clusters/PumpConfigurationControl.xml +++ b/data_model/master/clusters/PumpConfigurationControl.xml @@ -1,59 +1,61 @@ - @@ -68,19 +70,19 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -96,44 +98,37 @@ Davis, CA 95616, USA - + - + - + - + - + - + - + @@ -143,8 +138,7 @@ Davis, CA 95616, USA - + @@ -183,22 +177,22 @@ Davis, CA 95616, USA - + - + - + - + @@ -210,7 +204,7 @@ Davis, CA 95616, USA - + @@ -222,7 +216,7 @@ Davis, CA 95616, USA - + @@ -234,7 +228,7 @@ Davis, CA 95616, USA - + @@ -246,7 +240,7 @@ Davis, CA 95616, USA - + @@ -258,7 +252,7 @@ Davis, CA 95616, USA - + @@ -270,7 +264,7 @@ Davis, CA 95616, USA - + @@ -282,7 +276,7 @@ Davis, CA 95616, USA - + @@ -294,7 +288,7 @@ Davis, CA 95616, USA - + @@ -303,11 +297,13 @@ Davis, CA 95616, USA - + + + - + @@ -316,68 +312,77 @@ Davis, CA 95616, USA - + + + - + - + + + - + - + + + - + - + + + - + - + - + - + - + - + - + + + - + - + + + - - - + - @@ -450,4 +455,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/PushAVStreamTransport.xml b/data_model/master/clusters/PushAVStreamTransport.xml new file mode 100644 index 00000000000000..464ecebd5564c3 --- /dev/null +++ b/data_model/master/clusters/PushAVStreamTransport.xml @@ -0,0 +1,472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/RefrigeratorAlarm.xml b/data_model/master/clusters/RefrigeratorAlarm.xml index a3a75011813cd1..4504d587d4d80d 100644 --- a/data_model/master/clusters/RefrigeratorAlarm.xml +++ b/data_model/master/clusters/RefrigeratorAlarm.xml @@ -1,61 +1,61 @@ - @@ -72,7 +72,7 @@ Davis, CA 95616, USA - + @@ -82,4 +82,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/ResourceMonitoring.xml b/data_model/master/clusters/ResourceMonitoring.xml index 911ad11373b948..9fe85266ecb763 100644 --- a/data_model/master/clusters/ResourceMonitoring.xml +++ b/data_model/master/clusters/ResourceMonitoring.xml @@ -1,63 +1,63 @@ - - + @@ -120,11 +120,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -137,11 +141,13 @@ Davis, CA 95616, USA - + - + + + @@ -153,17 +159,19 @@ Davis, CA 95616, USA - + - + - + + + @@ -172,4 +180,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/Scenes.xml b/data_model/master/clusters/Scenes.xml index 1479d3ffd7de86..b7a0287260e565 100644 --- a/data_model/master/clusters/Scenes.xml +++ b/data_model/master/clusters/Scenes.xml @@ -1,61 +1,61 @@ - @@ -114,30 +114,9 @@ Davis, CA 95616, USA - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -147,19 +126,23 @@ Davis, CA 95616, USA - + + + - + - + + + @@ -167,20 +150,24 @@ Davis, CA 95616, USA - + - + - + + + - + + + @@ -192,34 +179,46 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + - + + + @@ -230,30 +229,58 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + + + + + + + - + + + + + + + + + + + + + + + @@ -264,21 +291,27 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -292,7 +325,9 @@ Davis, CA 95616, USA - + + + @@ -306,21 +341,27 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -331,12 +372,16 @@ Davis, CA 95616, USA - + + + - + + + @@ -350,7 +395,9 @@ Davis, CA 95616, USA - + + + @@ -361,6 +408,12 @@ Davis, CA 95616, USA + + + + + + @@ -368,19 +421,27 @@ Davis, CA 95616, USA - + + + - + + + + - + + + + @@ -389,15 +450,19 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ServiceArea.xml b/data_model/master/clusters/ServiceArea.xml index 2533d4b549d2f0..7e93ff6f7ac318 100644 --- a/data_model/master/clusters/ServiceArea.xml +++ b/data_model/master/clusters/ServiceArea.xml @@ -1,59 +1,61 @@ - @@ -76,26 +78,49 @@ Davis, CA 95616, USA - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -111,7 +136,9 @@ Davis, CA 95616, USA - + + + @@ -132,7 +159,9 @@ Davis, CA 95616, USA - + + + @@ -157,7 +186,9 @@ Davis, CA 95616, USA - + + + @@ -165,22 +196,28 @@ Davis, CA 95616, USA - + + + - + + + - - + + + + - + @@ -191,7 +228,9 @@ Davis, CA 95616, USA - + + + @@ -201,7 +240,9 @@ Davis, CA 95616, USA - + + + @@ -211,14 +252,24 @@ Davis, CA 95616, USA - + + + + + + + + + - + + + @@ -227,12 +278,13 @@ Davis, CA 95616, USA - - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/SmokeCOAlarm.xml b/data_model/master/clusters/SmokeCOAlarm.xml index 482a8a82f2abf5..dc0d35b795cfe0 100644 --- a/data_model/master/clusters/SmokeCOAlarm.xml +++ b/data_model/master/clusters/SmokeCOAlarm.xml @@ -1,61 +1,61 @@ - @@ -67,10 +67,10 @@ Davis, CA 95616, USA - + - + @@ -163,31 +163,31 @@ Davis, CA 95616, USA - + - + - + - + - + @@ -196,12 +196,12 @@ Davis, CA 95616, USA - + - + @@ -226,7 +226,7 @@ Davis, CA 95616, USA - + @@ -305,4 +305,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/ProxyDiscovery-Cluster.xml b/data_model/master/clusters/SoilMeasurement.xml similarity index 69% rename from data_model/master/clusters/ProxyDiscovery-Cluster.xml rename to data_model/master/clusters/SoilMeasurement.xml index 7353386929c109..a222a15686c622 100644 --- a/data_model/master/clusters/ProxyDiscovery-Cluster.xml +++ b/data_model/master/clusters/SoilMeasurement.xml @@ -1,100 +1,107 @@ - - + - - - + - - - - + + + + + - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/Switch.xml b/data_model/master/clusters/Switch.xml index 8662d262f0b50e..e2b0d123806b3c 100644 --- a/data_model/master/clusters/Switch.xml +++ b/data_model/master/clusters/Switch.xml @@ -1,66 +1,66 @@ - - + @@ -116,23 +116,29 @@ Davis, CA 95616, USA - + - + + + - + - + + + - + - + + + @@ -143,7 +149,12 @@ Davis, CA 95616, USA - + + + + + + @@ -153,7 +164,12 @@ Davis, CA 95616, USA - + + + + + + @@ -163,7 +179,12 @@ Davis, CA 95616, USA - + + + + + + @@ -173,7 +194,12 @@ Davis, CA 95616, USA - + + + + + + @@ -183,7 +209,12 @@ Davis, CA 95616, USA - + + + + + + @@ -198,11 +229,20 @@ Davis, CA 95616, USA - + + + + + + - + + + + + @@ -212,12 +252,21 @@ Davis, CA 95616, USA - + + + + + + - + + + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/TLSCertificateManagement.xml b/data_model/master/clusters/TLSCertificateManagement.xml new file mode 100644 index 00000000000000..c1eef378fb31ba --- /dev/null +++ b/data_model/master/clusters/TLSCertificateManagement.xml @@ -0,0 +1,275 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/NetworkIdentityManagement.xml b/data_model/master/clusters/TLSClientManagement.xml similarity index 51% rename from data_model/master/clusters/NetworkIdentityManagement.xml rename to data_model/master/clusters/TLSClientManagement.xml index cef2f88f6ddad9..a44a16e88bbb4f 100644 --- a/data_model/master/clusters/NetworkIdentityManagement.xml +++ b/data_model/master/clusters/TLSClientManagement.xml @@ -1,169 +1,189 @@ - - + - + - + - + - - - + + + + + + - - - - + + - - - - + - - + + + + + + + + - - - + - - - - + + + - - - - + + + - - - - - + + + - - - - - - - - - + + + - + + + + - - - + + + + + + + + + + - - + + - - - - - - + + - - + + + - + + - - - - - + + + + + + - - + + + + + + - - \ No newline at end of file + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/TargetNavigator.xml b/data_model/master/clusters/TargetNavigator.xml index b1fcff6d60cd1e..8de38e8eee9048 100644 --- a/data_model/master/clusters/TargetNavigator.xml +++ b/data_model/master/clusters/TargetNavigator.xml @@ -1,61 +1,61 @@ - @@ -81,7 +81,9 @@ Davis, CA 95616, USA - + + + @@ -97,7 +99,9 @@ Davis, CA 95616, USA - + + + @@ -131,12 +135,16 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/TemperatureControl.xml b/data_model/master/clusters/TemperatureControl.xml index 511761b24b9e89..c8828d45c3be30 100644 --- a/data_model/master/clusters/TemperatureControl.xml +++ b/data_model/master/clusters/TemperatureControl.xml @@ -1,59 +1,61 @@ - @@ -82,48 +84,65 @@ Davis, CA 95616, USA - + + + + + + - + - + + + - + - + + + - + - + + + - + + + - + + + - + + + @@ -134,14 +153,18 @@ Davis, CA 95616, USA - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/TemperatureMeasurement.xml b/data_model/master/clusters/TemperatureMeasurement.xml index 5c1df46ccbf115..9a7f7a713e003b 100644 --- a/data_model/master/clusters/TemperatureMeasurement.xml +++ b/data_model/master/clusters/TemperatureMeasurement.xml @@ -1,61 +1,61 @@ - @@ -71,26 +71,40 @@ Davis, CA 95616, USA - + - + + + + + + - + - + + + + + + - + - + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/Thermostat.xml b/data_model/master/clusters/Thermostat.xml index 6c5584e087d47c..805f49ed8e405f 100644 --- a/data_model/master/clusters/Thermostat.xml +++ b/data_model/master/clusters/Thermostat.xml @@ -1,61 +1,63 @@ - - + @@ -63,9 +65,9 @@ Davis, CA 95616, USA - + + @@ -77,7 +79,7 @@ Davis, CA 95616, USA - + @@ -85,7 +87,7 @@ Davis, CA 95616, USA - + @@ -114,11 +116,19 @@ Davis, CA 95616, USA + + + + + + + + - - - + + + @@ -197,7 +207,7 @@ Davis, CA 95616, USA - + @@ -325,12 +335,12 @@ Davis, CA 95616, USA - + - + @@ -385,22 +395,11 @@ Davis, CA 95616, USA - - - - - - - - - - - - + - + @@ -444,16 +443,16 @@ Davis, CA 95616, USA - + - + - + - + @@ -461,7 +460,11 @@ Davis, CA 95616, USA - + + + + + @@ -504,12 +507,12 @@ Davis, CA 95616, USA - + - + @@ -518,11 +521,24 @@ Davis, CA 95616, USA + + + + + + + + + + + - + + + @@ -530,19 +546,25 @@ Davis, CA 95616, USA - + + + - + - + + + - + - + + + @@ -564,24 +586,36 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + + + @@ -591,53 +625,89 @@ Davis, CA 95616, USA - + + + - + + + - + + + - + + + - + + + - + + + - + + + - + + + + + - + + + + + + + + + + + + + + + + + - + + + @@ -652,12 +722,12 @@ Davis, CA 95616, USA - + - + @@ -666,322 +736,417 @@ Davis, CA 95616, USA - + - + - + + + - + - + - + + + - + - + - + + + - + - + - + + + - + - + - + + + + + + - + - + - + + + + + + - + - + + + - + - + - + - + - + + + - + - + - + + + - + - + - + + + - + - + - + + + - + + - + - + + + - + + - + - + + + - + + - + - + + + - + + - + - + + + - + - + - + + + + + + - + - - + - + + + - + - - - - - - - - + + + - - - - + + + + + + + + + + + + + + - + - + - + + + - + - + - + - + + + - + - + + + - + - + + + - + - + + + - + + + - + - + - + - + - + - + + + + + + - + - + - + + + + + - + - + - + + + + + - + - + - + + + + + + - + - + - + + + + + - + - + - + + + + + - + - + - + - + + + - + - + - + + + - + - + + + @@ -989,106 +1154,151 @@ Davis, CA 95616, USA - + - + + + - + - + - + + + - + - + + + - + - + + + - + - + - + - + - + - + + + - + - + + + - + - + + + + + - + - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1096,7 +1306,9 @@ Davis, CA 95616, USA - + + + @@ -1111,16 +1323,22 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -1133,44 +1351,22 @@ Davis, CA 95616, USA - + + + - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + @@ -1180,11 +1376,15 @@ Davis, CA 95616, USA - + + + - + + + @@ -1193,12 +1393,6 @@ Davis, CA 95616, USA - - - - - - @@ -1206,7 +1400,9 @@ Davis, CA 95616, USA - + + + @@ -1217,8 +1413,223 @@ 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 d6a52248282321..68a59c38534f78 100644 --- a/data_model/master/clusters/ThermostatUserInterfaceConfiguration.xml +++ b/data_model/master/clusters/ThermostatUserInterfaceConfiguration.xml @@ -1,59 +1,61 @@ - @@ -103,20 +105,20 @@ Davis, CA 95616, USA - + + - - + + - - + + - - \ No newline at end of file + diff --git a/data_model/master/clusters/ThreadBorderRouterManagement.xml b/data_model/master/clusters/ThreadBorderRouterManagement.xml index 7ae4edab62f8b3..b0d2ee580f0abf 100644 --- a/data_model/master/clusters/ThreadBorderRouterManagement.xml +++ b/data_model/master/clusters/ThreadBorderRouterManagement.xml @@ -1,61 +1,61 @@ - @@ -74,31 +74,38 @@ Davis, CA 95616, USA - + + + + + + - + + + - + - + - + - + @@ -115,7 +122,9 @@ Davis, CA 95616, USA - + + + @@ -123,7 +132,9 @@ Davis, CA 95616, USA - + + + @@ -136,8 +147,10 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ThreadNetworkDirectory.xml b/data_model/master/clusters/ThreadNetworkDirectory.xml index e5112991e6ff06..a8011648f8f77b 100644 --- a/data_model/master/clusters/ThreadNetworkDirectory.xml +++ b/data_model/master/clusters/ThreadNetworkDirectory.xml @@ -1,61 +1,61 @@ - @@ -69,11 +69,18 @@ Davis, CA 95616, USA - + + + - + + + + + + @@ -86,22 +93,30 @@ Davis, CA 95616, USA - + - + + + - + - + + + + + - + - + + + @@ -110,7 +125,9 @@ Davis, CA 95616, USA - + + + @@ -118,7 +135,9 @@ Davis, CA 95616, USA - + + + @@ -126,15 +145,19 @@ 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 e72a9d32467983..7df4d9a7515b1b 100644 --- a/data_model/master/clusters/TimeSync.xml +++ b/data_model/master/clusters/TimeSync.xml @@ -1,62 +1,61 @@ - @@ -99,7 +98,11 @@ Davis, CA 95616, USA - + + + + + @@ -167,7 +170,9 @@ Davis, CA 95616, USA - + + + @@ -188,14 +193,24 @@ Davis, CA 95616, USA - + + + + + + - + + + + + + @@ -213,66 +228,80 @@ Davis, CA 95616, USA - + - + + - + + + - + + - + + + - + - + - + + + - + - + + + + + + - + - + - + - + + - + - + @@ -280,23 +309,30 @@ Davis, CA 95616, USA - + - + + + + + + - + - + + + - + - + @@ -334,14 +370,19 @@ Davis, CA 95616, USA - + + + + + + - + @@ -363,7 +404,9 @@ Davis, CA 95616, USA - + + + @@ -390,11 +433,15 @@ Davis, CA 95616, USA - + + + + + + - @@ -408,4 +455,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/ValveConfigurationControl.xml b/data_model/master/clusters/ValveConfigurationControl.xml index 6f38375a1a31c6..b1673a424ba1a8 100644 --- a/data_model/master/clusters/ValveConfigurationControl.xml +++ b/data_model/master/clusters/ValveConfigurationControl.xml @@ -1,61 +1,61 @@ - @@ -72,7 +72,11 @@ Davis, CA 95616, USA - + + + + + @@ -108,59 +112,68 @@ Davis, CA 95616, USA - + - + + + - + - + + + - + - + - + - + - + - + - + - + + + + + + @@ -168,11 +181,16 @@ Davis, CA 95616, USA - + - + + + + + + @@ -182,13 +200,17 @@ Davis, CA 95616, USA - + + + - + + + @@ -217,4 +239,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/WakeOnLAN.xml b/data_model/master/clusters/WakeOnLAN.xml index 092e0a8ea8f4de..e004fd9b2be129 100644 --- a/data_model/master/clusters/WakeOnLAN.xml +++ b/data_model/master/clusters/WakeOnLAN.xml @@ -1,82 +1,86 @@ - - + - + - + + + - + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/WaterContentMeasurement.xml b/data_model/master/clusters/WaterContentMeasurement.xml index b613bf4e1522fb..02f9ce596882ae 100644 --- a/data_model/master/clusters/WaterContentMeasurement.xml +++ b/data_model/master/clusters/WaterContentMeasurement.xml @@ -1,95 +1,109 @@ - - + - + - + - + + + + + + - + - + + + - + - + + + + + + - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/WaterHeaterManagement.xml b/data_model/master/clusters/WaterHeaterManagement.xml index 96dcc2b112461b..bdc39235b59dda 100644 --- a/data_model/master/clusters/WaterHeaterManagement.xml +++ b/data_model/master/clusters/WaterHeaterManagement.xml @@ -1,61 +1,61 @@ - @@ -103,20 +103,35 @@ Davis, CA 95616, USA - + + + - - + + + + + + + + + + + + + - + + + - + @@ -124,14 +139,21 @@ Davis, CA 95616, USA - + + + + + + + + - + @@ -149,7 +171,9 @@ Davis, CA 95616, USA - + + + @@ -157,7 +181,8 @@ Davis, CA 95616, USA - + + @@ -168,7 +193,6 @@ Davis, CA 95616, USA - @@ -182,7 +206,6 @@ Davis, CA 95616, USA - @@ -190,4 +213,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/WebRTC_Provider.xml b/data_model/master/clusters/WebRTC_Provider.xml new file mode 100644 index 00000000000000..ab81098d79734b --- /dev/null +++ b/data_model/master/clusters/WebRTC_Provider.xml @@ -0,0 +1,386 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/WebRTC_Requestor.xml b/data_model/master/clusters/WebRTC_Requestor.xml new file mode 100644 index 00000000000000..8ad0e61e325066 --- /dev/null +++ b/data_model/master/clusters/WebRTC_Requestor.xml @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/WiFiNetworkManagement.xml b/data_model/master/clusters/WiFiNetworkManagement.xml index 3aad5935d2843d..d6c7d589b9e232 100644 --- a/data_model/master/clusters/WiFiNetworkManagement.xml +++ b/data_model/master/clusters/WiFiNetworkManagement.xml @@ -1,61 +1,61 @@ - @@ -68,13 +68,18 @@ Davis, CA 95616, USA - + - + + + + + + - + @@ -87,8 +92,10 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/WindowCovering.xml b/data_model/master/clusters/WindowCovering.xml index 09133513af736a..0156ad55c30c81 100644 --- a/data_model/master/clusters/WindowCovering.xml +++ b/data_model/master/clusters/WindowCovering.xml @@ -1,61 +1,61 @@ - @@ -71,10 +71,10 @@ Davis, CA 95616, USA - + - + @@ -305,23 +305,33 @@ Davis, CA 95616, USA - - + + - + + + - + + + - + + + - + + + - + + + @@ -339,14 +349,18 @@ Davis, CA 95616, USA - + - - + + + + - - + + + + @@ -391,13 +405,15 @@ Davis, CA 95616, USA - + - + + + - + @@ -408,7 +424,7 @@ Davis, CA 95616, USA - + @@ -419,7 +435,7 @@ Davis, CA 95616, USA - + @@ -427,11 +443,16 @@ Davis, CA 95616, USA - + + + + + + - + @@ -439,31 +460,38 @@ Davis, CA 95616, USA - + + + + + + - + - + - + - + + + - + @@ -473,24 +501,22 @@ Davis, CA 95616, USA - + - - + - - + @@ -500,7 +526,7 @@ Davis, CA 95616, USA - + @@ -510,35 +536,41 @@ Davis, CA 95616, USA - + - + + + - + - + + + - + - + + + - + @@ -546,11 +578,13 @@ Davis, CA 95616, USA - + + + - + @@ -558,11 +592,13 @@ Davis, CA 95616, USA - + + + - + @@ -570,11 +606,13 @@ Davis, CA 95616, USA - + + + - + @@ -582,7 +620,9 @@ Davis, CA 95616, USA - + + + @@ -595,9 +635,8 @@ Davis, CA 95616, USA - + - @@ -607,9 +646,11 @@ Davis, CA 95616, USA - + - + + + @@ -635,7 +676,9 @@ Davis, CA 95616, USA - + + + @@ -653,7 +696,9 @@ Davis, CA 95616, USA - + + + @@ -666,7 +711,9 @@ Davis, CA 95616, USA - + + + @@ -684,8 +731,10 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/ZoneManagement.xml b/data_model/master/clusters/ZoneManagement.xml new file mode 100644 index 00000000000000..36e99ca1fb0f64 --- /dev/null +++ b/data_model/master/clusters/ZoneManagement.xml @@ -0,0 +1,312 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/clusters/bridge-clusters-ActionsCluster.xml b/data_model/master/clusters/bridge-clusters-ActionsCluster.xml index 4874aca26bc504..815b4621c13f68 100644 --- a/data_model/master/clusters/bridge-clusters-ActionsCluster.xml +++ b/data_model/master/clusters/bridge-clusters-ActionsCluster.xml @@ -1,61 +1,61 @@ - @@ -101,7 +101,7 @@ Davis, CA 95616, USA - + @@ -166,6 +166,12 @@ Davis, CA 95616, USA + + + + + + @@ -175,7 +181,12 @@ Davis, CA 95616, USA - + + + + + + @@ -183,22 +194,26 @@ Davis, CA 95616, USA - - + + + + + + - - - + + + @@ -207,18 +222,24 @@ Davis, CA 95616, USA - + + + - + + + - + + + @@ -377,4 +398,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml b/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml index 62633f55cf08cc..f4e55c7653caf4 100644 --- a/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml +++ b/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml @@ -1,68 +1,69 @@ - - + - + + @@ -74,75 +75,186 @@ Davis, CA 95616, USA - + + + + + + - - + + + + + + - - + + + - + + + + + + + + + + - - + + + + + + - + + + + + + - + + + - + + + + + + + + + - + + + + + + - + + + + + + + + + - + + + + + + + + + - + + + + + + - + + + + + + - + + + + + + - + + + + + + - + + + - + + - + + + + + + - + + + - + + + - + + + + + + - + + + + + + + + + + + - + + + + + + @@ -156,7 +268,12 @@ Davis, CA 95616, USA - + + + + + + @@ -187,8 +304,10 @@ Davis, CA 95616, USA - + + + - \ No newline at end of file + diff --git a/data_model/master/clusters/cluster_ids.json b/data_model/master/clusters/cluster_ids.json index ee34f4df93d55f..dd91f798138588 100644 --- a/data_model/master/clusters/cluster_ids.json +++ b/data_model/master/clusters/cluster_ids.json @@ -5,7 +5,7 @@ "8": "Level Control", "29": "Descriptor", "30": "Binding", - "31": "AccessControl", + "31": "Access Control", "37": "Actions", "40": "Basic Information", "41": "OTA Software Update Provider", @@ -28,14 +28,11 @@ "59": "Switch", "60": "Administrator Commissioning", "62": "Operational Credentials", - "63": "GroupKeyManagement", + "63": "Group Key Management", "64": "Fixed Label", "65": "User Label", - "66": "ProxyConfiguration", - "67": "ProxyDiscovery", - "68": "ValidProxies", "69": "Boolean State", - "70": "ICDManagement", + "70": "ICD Management", "72": "Oven Cavity Operational State", "73": "Oven Mode", "74": "Laundry Dryer Controls", @@ -69,7 +66,6 @@ "151": "Messages", "152": "Device Energy Management", "153": "Energy EVSE", - "154": "Energy Calendar", "155": "Energy Preference", "156": "Power Topology", "157": "Energy EVSE Mode", @@ -77,14 +73,18 @@ "159": "Device Energy Management Mode", "257": "Door Lock", "258": "Window Covering", + "260": "Closure Control", + "261": "Closure 1st Dimension", + "262": "Closure 2nd Dimension", + "263": "Closure 3rd Dimension", + "264": "Closure 4th Dimension", + "265": "Closure 5th Dimension", "336": "Service Area", "512": "Pump Configuration and Control", "513": "Thermostat", "514": "Fan Control", "516": "Thermostat User Interface Configuration", - "517": "Humidistat", "768": "Color Control", - "769": "Ballast Configuration", "1024": "Illuminance Measurement", "1026": "Temperature Measurement", "1027": "Pressure Measurement", @@ -101,11 +101,11 @@ "1069": "PM10 Concentration Measurement", "1070": "Total Volatile Organic Compounds Concentration Measurement", "1071": "Radon Concentration Measurement", - "1104": "Network Identity Management", + "1072": "Soil Measurement", "1105": "Wi-Fi Network Management", "1106": "Thread Border Router Management", "1107": "Thread Network Directory", - "1283": "Wake on LAN", + "1283": "Wake On LAN", "1284": "Channel", "1285": "Target Navigator", "1286": "Media Playback", @@ -119,9 +119,19 @@ "1294": "Account Login", "1295": "Content Control", "1296": "Content App Observer", + "1360": "Zone Management", + "1361": "Camera AV Stream Management", + "1362": "Camera AV Settings User Level Management", + "1363": "WebRTC Transport Provider", + "1364": "WebRTC Transport Requestor", + "1365": "Push AV Stream Transport", + "1366": "Chime", + "1792": "Energy Tariff", "1872": "Ecosystem Information", "1873": "Commissioner Control", - "1874": "Joint Fabric Datastore Cluster", + "1874": "Joint Fabric Datastore", "1875": "Joint Fabric PKI", + "2049": "TLS Certificate Management", + "2050": "TLS Client Management", "2822": "Meter Identification" } diff --git a/data_model/master/device_types/Aggregator.xml b/data_model/master/device_types/Aggregator.xml index a99ee1108c3b50..c61f62e816eb2f 100644 --- a/data_model/master/device_types/Aggregator.xml +++ b/data_model/master/device_types/Aggregator.xml @@ -1,66 +1,71 @@ - - + + - + + + @@ -68,5 +73,10 @@ Davis, CA 95616, USA + + + + + - \ No newline at end of file + diff --git a/data_model/master/device_types/AirPurifier.xml b/data_model/master/device_types/AirPurifier.xml index 62045f090c71a5..2b9b3f7b2532bd 100644 --- a/data_model/master/device_types/AirPurifier.xml +++ b/data_model/master/device_types/AirPurifier.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -82,4 +83,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/AirQualitySensor.xml b/data_model/master/device_types/AirQualitySensor.xml index 756b42e437ac9a..61763636f40361 100644 --- a/data_model/master/device_types/AirQualitySensor.xml +++ b/data_model/master/device_types/AirQualitySensor.xml @@ -1,66 +1,67 @@ - - @@ -105,4 +106,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/EnergyTariff.xml b/data_model/master/device_types/AudioDoorbell.xml similarity index 91% rename from data_model/master/device_types/EnergyTariff.xml rename to data_model/master/device_types/AudioDoorbell.xml index 887bfa420d8fd8..429e23fd158718 100644 --- a/data_model/master/device_types/EnergyTariff.xml +++ b/data_model/master/device_types/AudioDoorbell.xml @@ -1,64 +1,70 @@ - - + - + - - \ No newline at end of file + + + + + + diff --git a/data_model/master/device_types/BaseDeviceType.xml b/data_model/master/device_types/BaseDeviceType.xml index 272b74feb5ff67..292faf5db707be 100644 --- a/data_model/master/device_types/BaseDeviceType.xml +++ b/data_model/master/device_types/BaseDeviceType.xml @@ -1,73 +1,105 @@ - - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -87,4 +119,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/BasicVideoPlayer.xml b/data_model/master/device_types/BasicVideoPlayer.xml index d35bbed3211422..acf88741ac091f 100644 --- a/data_model/master/device_types/BasicVideoPlayer.xml +++ b/data_model/master/device_types/BasicVideoPlayer.xml @@ -1,59 +1,61 @@ - @@ -85,7 +87,7 @@ Davis, CA 95616, USA - + @@ -104,4 +106,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/BatteryStorage.xml b/data_model/master/device_types/BatteryStorage.xml index 5f09eeb1d2dac9..5c538446ba24c6 100644 --- a/data_model/master/device_types/BatteryStorage.xml +++ b/data_model/master/device_types/BatteryStorage.xml @@ -1,69 +1,70 @@ - - - \ No newline at end of file + diff --git a/data_model/master/device_types/BridgedNode.xml b/data_model/master/device_types/BridgedNode.xml index 6f309001975627..c1c1770ca9e0e4 100644 --- a/data_model/master/device_types/BridgedNode.xml +++ b/data_model/master/device_types/BridgedNode.xml @@ -1,67 +1,72 @@ - - + + - + + + @@ -79,5 +84,18 @@ Davis, CA 95616, USA + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/data_model/master/device_types/Camera.xml b/data_model/master/device_types/Camera.xml new file mode 100644 index 00000000000000..a559cdf8df632a --- /dev/null +++ b/data_model/master/device_types/Camera.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/CastingVideoClient.xml b/data_model/master/device_types/CastingVideoClient.xml index 949142a6bca151..5ff5a3e1d23a26 100644 --- a/data_model/master/device_types/CastingVideoClient.xml +++ b/data_model/master/device_types/CastingVideoClient.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -118,4 +119,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/CastingVideoPlayer.xml b/data_model/master/device_types/CastingVideoPlayer.xml index 5c88cf92947e0b..db4401683445e5 100644 --- a/data_model/master/device_types/CastingVideoPlayer.xml +++ b/data_model/master/device_types/CastingVideoPlayer.xml @@ -1,59 +1,61 @@ - @@ -62,9 +64,7 @@ Davis, CA 95616, USA - + @@ -88,7 +88,7 @@ launch Content Apps and represent these apps as separate endpoints."/> - + @@ -105,7 +105,7 @@ launch Content Apps and represent these apps as separate endpoints."/> - + @@ -123,4 +123,4 @@ launch Content Apps and represent these apps as separate endpoints."/> - \ No newline at end of file + diff --git a/data_model/master/device_types/EnergyTariffCalendar.xml b/data_model/master/device_types/Chime.xml similarity index 91% rename from data_model/master/device_types/EnergyTariffCalendar.xml rename to data_model/master/device_types/Chime.xml index 70d74b7239f41c..246d8a89d56f2c 100644 --- a/data_model/master/device_types/EnergyTariffCalendar.xml +++ b/data_model/master/device_types/Chime.xml @@ -1,64 +1,70 @@ - - + - + - - \ No newline at end of file + + + + + + diff --git a/data_model/master/device_types/ClosureBaseController.xml b/data_model/master/device_types/ClosureBaseController.xml new file mode 100644 index 00000000000000..99044ab57fd5cb --- /dev/null +++ b/data_model/master/device_types/ClosureBaseController.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Awning.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Awning.xml new file mode 100644 index 00000000000000..c4c18459fd1312 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Awning.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Barrier.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Barrier.xml new file mode 100644 index 00000000000000..c8389a85030ee5 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Barrier.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Blind.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Blind.xml new file mode 100644 index 00000000000000..e148b80fdcf64d --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Blind.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Cabinet.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Cabinet.xml new file mode 100644 index 00000000000000..775397161fc667 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Cabinet.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-ClosureBase.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-ClosureBase.xml new file mode 100644 index 00000000000000..b17d5325460c62 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-ClosureBase.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Curtain.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Curtain.xml new file mode 100644 index 00000000000000..2a5d5633889ba6 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Curtain.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Door.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Door.xml new file mode 100644 index 00000000000000..c6d7bb8fce1f4b --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Door.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-GarageDoor.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-GarageDoor.xml new file mode 100644 index 00000000000000..ac72e15a76a3b4 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-GarageDoor.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Gate.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Gate.xml new file mode 100644 index 00000000000000..0fac9ef75b108f --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Gate.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Pergola.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Pergola.xml new file mode 100644 index 00000000000000..7c1f2bd72dbc75 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Pergola.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Screen.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Screen.xml new file mode 100644 index 00000000000000..4ddec2e7c02356 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Screen.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Shade.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Shade.xml new file mode 100644 index 00000000000000..1346498e56208b --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Shade.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Shutter.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Shutter.xml new file mode 100644 index 00000000000000..c421c5ec51c5b7 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Shutter.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ClosureBaseDeviceTypes-Window.xml b/data_model/master/device_types/ClosureBaseDeviceTypes-Window.xml new file mode 100644 index 00000000000000..8d53f6c6a0f994 --- /dev/null +++ b/data_model/master/device_types/ClosureBaseDeviceTypes-Window.xml @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ColorDimmerSwitch.xml b/data_model/master/device_types/ColorDimmerSwitch.xml index abc027eaec711c..bc80755034fe42 100644 --- a/data_model/master/device_types/ColorDimmerSwitch.xml +++ b/data_model/master/device_types/ColorDimmerSwitch.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -89,4 +90,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/ColorTemperatureLight.xml b/data_model/master/device_types/ColorTemperatureLight.xml index 56db5416cf02c9..003a2a1b4a795a 100644 --- a/data_model/master/device_types/ColorTemperatureLight.xml +++ b/data_model/master/device_types/ColorTemperatureLight.xml @@ -1,59 +1,61 @@ - @@ -63,12 +65,11 @@ Davis, CA 95616, USA - - + @@ -95,14 +96,23 @@ Davis, CA 95616, USA - - + + + + + + + - - + + + + - - + + + + @@ -112,7 +122,7 @@ Davis, CA 95616, USA - + @@ -128,7 +138,7 @@ Davis, CA 95616, USA - + @@ -137,4 +147,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/ContactSensor.xml b/data_model/master/device_types/ContactSensor.xml index 2767e5e37a384b..79031c697106b2 100644 --- a/data_model/master/device_types/ContactSensor.xml +++ b/data_model/master/device_types/ContactSensor.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -73,4 +74,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/ContentApp.xml b/data_model/master/device_types/ContentApp.xml index 81b967db9c8dc1..0fe38d96e43728 100644 --- a/data_model/master/device_types/ContentApp.xml +++ b/data_model/master/device_types/ContentApp.xml @@ -1,59 +1,61 @@ - @@ -61,10 +63,13 @@ Davis, CA 95616, USA + + + - + @@ -98,8 +103,8 @@ Davis, CA 95616, USA - + - \ No newline at end of file + diff --git a/data_model/master/device_types/ControlBridge.xml b/data_model/master/device_types/ControlBridge.xml index ab07228e728f52..2c0d694f7e2881 100644 --- a/data_model/master/device_types/ControlBridge.xml +++ b/data_model/master/device_types/ControlBridge.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -95,4 +96,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/CookSurface.xml b/data_model/master/device_types/CookSurface.xml index 3a0e8f062c7495..b5fe7efe0a8158 100644 --- a/data_model/master/device_types/CookSurface.xml +++ b/data_model/master/device_types/CookSurface.xml @@ -1,66 +1,68 @@ - - + + - @@ -71,10 +73,18 @@ Davis, CA 95616, USA - + + + + + + + + + - + - \ No newline at end of file + diff --git a/data_model/master/device_types/Cooktop.xml b/data_model/master/device_types/Cooktop.xml index 9164641c06f2c1..744e7af1d5aa0b 100644 --- a/data_model/master/device_types/Cooktop.xml +++ b/data_model/master/device_types/Cooktop.xml @@ -1,66 +1,67 @@ - - @@ -74,4 +75,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/DeviceEnergyManagement.xml b/data_model/master/device_types/DeviceEnergyManagement.xml index 86efccc02f6b2d..529c19f1de8fa7 100644 --- a/data_model/master/device_types/DeviceEnergyManagement.xml +++ b/data_model/master/device_types/DeviceEnergyManagement.xml @@ -1,59 +1,61 @@ - @@ -61,28 +63,47 @@ Davis, CA 95616, USA + + + - - - - + - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - - + - \ No newline at end of file + diff --git a/data_model/master/device_types/DimmableLight.xml b/data_model/master/device_types/DimmableLight.xml index 4d6c53e4ae36fd..a59c966a9ec472 100644 --- a/data_model/master/device_types/DimmableLight.xml +++ b/data_model/master/device_types/DimmableLight.xml @@ -1,59 +1,61 @@ - @@ -62,12 +64,11 @@ Davis, CA 95616, USA - - + @@ -94,14 +95,23 @@ Davis, CA 95616, USA - - + + + + + + + - - + + + + - - + + + + @@ -111,7 +121,7 @@ Davis, CA 95616, USA - + @@ -123,4 +133,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/DimmablePlug-InUnit.xml b/data_model/master/device_types/DimmablePlug-InUnit.xml index 73fd2a37c48bab..3eb4d93dc5fc13 100644 --- a/data_model/master/device_types/DimmablePlug-InUnit.xml +++ b/data_model/master/device_types/DimmablePlug-InUnit.xml @@ -1,59 +1,61 @@ - @@ -63,12 +65,11 @@ Davis, CA 95616, USA - - + @@ -95,14 +96,23 @@ Davis, CA 95616, USA - - + + + + + + + - - + + + + - - + + + + @@ -112,7 +122,7 @@ Davis, CA 95616, USA - + @@ -124,4 +134,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/DimmerSwitch.xml b/data_model/master/device_types/DimmerSwitch.xml index 9dce28fdd7ce71..64e82939a44cde 100644 --- a/data_model/master/device_types/DimmerSwitch.xml +++ b/data_model/master/device_types/DimmerSwitch.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -86,4 +87,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/Dishwasher.xml b/data_model/master/device_types/Dishwasher.xml index b13f9a42ebcc49..49dfb7be2238d9 100644 --- a/data_model/master/device_types/Dishwasher.xml +++ b/data_model/master/device_types/Dishwasher.xml @@ -1,66 +1,68 @@ - - + + - @@ -84,7 +86,7 @@ Davis, CA 95616, USA - + @@ -94,6 +96,11 @@ Davis, CA 95616, USA + + + + + - \ No newline at end of file + diff --git a/data_model/master/device_types/DoorLock.xml b/data_model/master/device_types/DoorLock.xml index e2eb1e9152085d..8bbcf99979ce49 100644 --- a/data_model/master/device_types/DoorLock.xml +++ b/data_model/master/device_types/DoorLock.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -85,6 +86,7 @@ Davis, CA 95616, USA + @@ -96,13 +98,6 @@ 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 40749d77b3c783..4b54fcdc00cce0 100644 --- a/data_model/master/device_types/DoorLockController.xml +++ b/data_model/master/device_types/DoorLockController.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -80,4 +81,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/EVSE.xml b/data_model/master/device_types/EVSE.xml index d468cb8a180f22..da8e26b374f855 100644 --- a/data_model/master/device_types/EVSE.xml +++ b/data_model/master/device_types/EVSE.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -76,4 +77,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/ElectricalEnergyTariff.xml b/data_model/master/device_types/ElectricalEnergyTariff.xml new file mode 100644 index 00000000000000..ca9b340160d7b8 --- /dev/null +++ b/data_model/master/device_types/ElectricalEnergyTariff.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ElectricalMeter.xml b/data_model/master/device_types/ElectricalMeter.xml new file mode 100644 index 00000000000000..c548fd35853bea --- /dev/null +++ b/data_model/master/device_types/ElectricalMeter.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ElectricalSensor.xml b/data_model/master/device_types/ElectricalSensor.xml index 75c4b0bb7cbbed..d4a1f892e1a188 100644 --- a/data_model/master/device_types/ElectricalSensor.xml +++ b/data_model/master/device_types/ElectricalSensor.xml @@ -1,59 +1,61 @@ - @@ -62,13 +64,13 @@ Davis, CA 95616, USA - + - + - \ No newline at end of file + diff --git a/data_model/master/device_types/ElectricalUtilityMeter.xml b/data_model/master/device_types/ElectricalUtilityMeter.xml new file mode 100644 index 00000000000000..da7dcead6dcc76 --- /dev/null +++ b/data_model/master/device_types/ElectricalUtilityMeter.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ExtendedColorLight.xml b/data_model/master/device_types/ExtendedColorLight.xml index 0678094669459f..1a37ac7a6fb298 100644 --- a/data_model/master/device_types/ExtendedColorLight.xml +++ b/data_model/master/device_types/ExtendedColorLight.xml @@ -1,59 +1,61 @@ - @@ -63,12 +65,11 @@ Davis, CA 95616, USA - - + @@ -95,14 +96,23 @@ Davis, CA 95616, USA - - + + + + + + + - - + + + + - - + + + + @@ -112,7 +122,7 @@ Davis, CA 95616, USA - + @@ -132,7 +142,7 @@ Davis, CA 95616, USA - + @@ -140,7 +150,7 @@ Davis, CA 95616, USA - + @@ -149,4 +159,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/ExtractorHood.xml b/data_model/master/device_types/ExtractorHood.xml index 3e8064adb149f4..ff3b4819c7c24f 100644 --- a/data_model/master/device_types/ExtractorHood.xml +++ b/data_model/master/device_types/ExtractorHood.xml @@ -1,66 +1,67 @@ - - @@ -86,4 +87,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/Fan.xml b/data_model/master/device_types/Fan.xml index e5184cfe22aec7..eae97cb4119c90 100644 --- a/data_model/master/device_types/Fan.xml +++ b/data_model/master/device_types/Fan.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -76,8 +77,8 @@ Davis, CA 95616, USA - - + + @@ -86,4 +87,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/NetworkInfraIntro.xml b/data_model/master/device_types/FloodlightCamera.xml similarity index 88% rename from data_model/master/device_types/NetworkInfraIntro.xml rename to data_model/master/device_types/FloodlightCamera.xml index e5bc56b1f095ac..6ec3c6bc047b05 100644 --- a/data_model/master/device_types/NetworkInfraIntro.xml +++ b/data_model/master/device_types/FloodlightCamera.xml @@ -1,58 +1,70 @@ - - \ No newline at end of file + + + + + + + + + + + diff --git a/data_model/master/device_types/FlowSensor.xml b/data_model/master/device_types/FlowSensor.xml index 6a9023060e12f9..36c3d919ae1d65 100644 --- a/data_model/master/device_types/FlowSensor.xml +++ b/data_model/master/device_types/FlowSensor.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -75,4 +76,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/GenericSwitch.xml b/data_model/master/device_types/GenericSwitch.xml index b8bc394b96e2e8..b71b3861413d91 100644 --- a/data_model/master/device_types/GenericSwitch.xml +++ b/data_model/master/device_types/GenericSwitch.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -71,4 +72,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/HeatPump.xml b/data_model/master/device_types/HeatPump.xml index 61f556c6ed2a9b..5d8666d0903777 100644 --- a/data_model/master/device_types/HeatPump.xml +++ b/data_model/master/device_types/HeatPump.xml @@ -1,72 +1,73 @@ - - - + - \ 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 c6def400a2a6bb..685bcb45bbc7c0 100644 --- a/data_model/master/device_types/HumiditySensor.xml +++ b/data_model/master/device_types/HumiditySensor.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -75,4 +76,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/Intercom.xml b/data_model/master/device_types/Intercom.xml new file mode 100644 index 00000000000000..7029a62701ae90 --- /dev/null +++ b/data_model/master/device_types/Intercom.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/IrrigationSystem.xml b/data_model/master/device_types/IrrigationSystem.xml new file mode 100644 index 00000000000000..f7de739e013bc6 --- /dev/null +++ b/data_model/master/device_types/IrrigationSystem.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/JointFabricAdmin.xml b/data_model/master/device_types/JointFabricAdmin.xml index 6c63dc9bdd96a1..81d372a77c9862 100644 --- a/data_model/master/device_types/JointFabricAdmin.xml +++ b/data_model/master/device_types/JointFabricAdmin.xml @@ -1,59 +1,61 @@ - @@ -68,4 +70,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/LaundryDryer.xml b/data_model/master/device_types/LaundryDryer.xml index 36dc182c393bd7..2354c5e154c86c 100644 --- a/data_model/master/device_types/LaundryDryer.xml +++ b/data_model/master/device_types/LaundryDryer.xml @@ -1,66 +1,68 @@ - - + + - @@ -84,7 +86,7 @@ Davis, CA 95616, USA - + @@ -94,6 +96,11 @@ Davis, CA 95616, USA + + + + + - \ No newline at end of file + diff --git a/data_model/master/device_types/LaundryWasher.xml b/data_model/master/device_types/LaundryWasher.xml index d88ee7e9fd94ca..68b3909adc7cee 100644 --- a/data_model/master/device_types/LaundryWasher.xml +++ b/data_model/master/device_types/LaundryWasher.xml @@ -1,66 +1,68 @@ - - + + - @@ -81,7 +83,7 @@ Davis, CA 95616, USA - + @@ -94,6 +96,11 @@ Davis, CA 95616, USA + + + + + - \ No newline at end of file + diff --git a/data_model/master/device_types/LightSensor.xml b/data_model/master/device_types/LightSensor.xml index e7200e347726aa..7fcfb1257e94d7 100644 --- a/data_model/master/device_types/LightSensor.xml +++ b/data_model/master/device_types/LightSensor.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -76,4 +77,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/MicrowaveOven.xml b/data_model/master/device_types/MicrowaveOven.xml index 98d2902d049610..53092902c2f585 100644 --- a/data_model/master/device_types/MicrowaveOven.xml +++ b/data_model/master/device_types/MicrowaveOven.xml @@ -1,66 +1,68 @@ - - + + - @@ -74,10 +76,15 @@ Davis, CA 95616, USA - + + + + + + @@ -91,4 +98,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/ModeSelectDeviceType.xml b/data_model/master/device_types/ModeSelectDeviceType.xml index ad4cf56671243b..e14b840ea9e149 100644 --- a/data_model/master/device_types/ModeSelectDeviceType.xml +++ b/data_model/master/device_types/ModeSelectDeviceType.xml @@ -1,69 +1,70 @@ - - - \ No newline at end of file + diff --git a/data_model/master/device_types/MountedDimmableLoadControl.xml b/data_model/master/device_types/MountedDimmableLoadControl.xml index d0cee6e5ef37cd..6a4b2a81048e49 100644 --- a/data_model/master/device_types/MountedDimmableLoadControl.xml +++ b/data_model/master/device_types/MountedDimmableLoadControl.xml @@ -1,71 +1,72 @@ - - - + - + @@ -92,14 +93,23 @@ Davis, CA 95616, USA - - + + + + + + + - - + + + + - - + + + + @@ -109,7 +119,7 @@ Davis, CA 95616, USA - + @@ -121,4 +131,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/MountedOnOffControl.xml b/data_model/master/device_types/MountedOnOffControl.xml index 09628bb4e0e9f0..ae0900168e82c8 100644 --- a/data_model/master/device_types/MountedOnOffControl.xml +++ b/data_model/master/device_types/MountedOnOffControl.xml @@ -1,71 +1,72 @@ - - - + - + @@ -92,14 +93,23 @@ Davis, CA 95616, USA - - + + + + + + + - - + + + + - - + + + + @@ -109,7 +119,7 @@ Davis, CA 95616, USA - + @@ -121,4 +131,4 @@ Davis, CA 95616, USA - \ 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 58cbae2e7ab440..9f97ab3307c1bc 100644 --- a/data_model/master/device_types/NetworkInfraManager.xml +++ b/data_model/master/device_types/NetworkInfraManager.xml @@ -1,67 +1,75 @@ - - + - + + - + + + + + + @@ -72,4 +80,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/OccupancySensor.xml b/data_model/master/device_types/OccupancySensor.xml index f257bab38a7686..47d35935c55f16 100644 --- a/data_model/master/device_types/OccupancySensor.xml +++ b/data_model/master/device_types/OccupancySensor.xml @@ -1,59 +1,61 @@ - @@ -63,7 +65,6 @@ Davis, CA 95616, USA - @@ -75,4 +76,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/OnOffLight.xml b/data_model/master/device_types/OnOffLight.xml index c74f5f79000919..6d463ffbd160f8 100644 --- a/data_model/master/device_types/OnOffLight.xml +++ b/data_model/master/device_types/OnOffLight.xml @@ -1,59 +1,61 @@ - @@ -62,12 +64,11 @@ Davis, CA 95616, USA - - + @@ -94,14 +95,23 @@ Davis, CA 95616, USA - - + + + + + + + - - + + + + - - + + + + @@ -111,7 +121,7 @@ Davis, CA 95616, USA - + @@ -123,4 +133,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/OnOffLightSwitch.xml b/data_model/master/device_types/OnOffLightSwitch.xml index 0cfa5ba7a3702c..b0d2c4b72e1435 100644 --- a/data_model/master/device_types/OnOffLightSwitch.xml +++ b/data_model/master/device_types/OnOffLightSwitch.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -83,4 +84,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/OnOffPlug-inUnit.xml b/data_model/master/device_types/OnOffPlug-inUnit.xml index 946f7919516e2d..8eaf090f913ead 100644 --- a/data_model/master/device_types/OnOffPlug-inUnit.xml +++ b/data_model/master/device_types/OnOffPlug-inUnit.xml @@ -1,59 +1,61 @@ - @@ -62,12 +64,11 @@ Davis, CA 95616, USA - - + @@ -94,14 +95,23 @@ Davis, CA 95616, USA - - + + + + + + + - - + + + + - - + + + + @@ -111,7 +121,7 @@ Davis, CA 95616, USA - + @@ -123,4 +133,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/OnOffSensor.xml b/data_model/master/device_types/OnOffSensor.xml index 0fc76f8314a6b5..97f6fb5e92c52b 100644 --- a/data_model/master/device_types/OnOffSensor.xml +++ b/data_model/master/device_types/OnOffSensor.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -89,4 +90,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/OtaProvider.xml b/data_model/master/device_types/OtaProvider.xml index b148d27ebb74e5..f048fd9beb1cc1 100644 --- a/data_model/master/device_types/OtaProvider.xml +++ b/data_model/master/device_types/OtaProvider.xml @@ -1,59 +1,61 @@ - @@ -68,4 +70,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/OtaRequestor.xml b/data_model/master/device_types/OtaRequestor.xml index d782ee992c454b..b882eda30fd3a3 100644 --- a/data_model/master/device_types/OtaRequestor.xml +++ b/data_model/master/device_types/OtaRequestor.xml @@ -1,59 +1,61 @@ - @@ -68,4 +70,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/Oven.xml b/data_model/master/device_types/Oven.xml index d34bc4c52bfbb6..01ee5222f3fca4 100644 --- a/data_model/master/device_types/Oven.xml +++ b/data_model/master/device_types/Oven.xml @@ -1,59 +1,61 @@ - @@ -61,10 +63,9 @@ Davis, CA 95616, USA - - \ No newline at end of file + diff --git a/data_model/master/device_types/PowerSource.xml b/data_model/master/device_types/PowerSource.xml index 4e6c6defabccf9..38c6f268a55de8 100644 --- a/data_model/master/device_types/PowerSource.xml +++ b/data_model/master/device_types/PowerSource.xml @@ -1,68 +1,70 @@ - - + - \ No newline at end of file + diff --git a/data_model/master/device_types/PressureSensor.xml b/data_model/master/device_types/PressureSensor.xml index 5b7ef86c25cc3d..bc58e53e29144d 100644 --- a/data_model/master/device_types/PressureSensor.xml +++ b/data_model/master/device_types/PressureSensor.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -75,4 +76,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/Pump.xml b/data_model/master/device_types/Pump.xml index a39cd97b87e7ad..c27122ba2f24c4 100644 --- a/data_model/master/device_types/Pump.xml +++ b/data_model/master/device_types/Pump.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -107,4 +108,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/PumpController.xml b/data_model/master/device_types/PumpController.xml index 25e9a8e982b5ff..8dc958c3a5a000 100644 --- a/data_model/master/device_types/PumpController.xml +++ b/data_model/master/device_types/PumpController.xml @@ -1,59 +1,61 @@ - @@ -98,4 +100,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/RainSensor.xml b/data_model/master/device_types/RainSensor.xml index a03060c5415dc0..092291eb404199 100644 --- a/data_model/master/device_types/RainSensor.xml +++ b/data_model/master/device_types/RainSensor.xml @@ -1,66 +1,67 @@ - - @@ -68,7 +69,7 @@ Davis, CA 95616, USA - + @@ -77,4 +78,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/Refrigerator.xml b/data_model/master/device_types/Refrigerator.xml index c8bdf86e3ef737..9cbbc124103f3d 100644 --- a/data_model/master/device_types/Refrigerator.xml +++ b/data_model/master/device_types/Refrigerator.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -74,7 +75,7 @@ Davis, CA 95616, USA - + @@ -83,4 +84,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/RoboticVacuumCleaner.xml b/data_model/master/device_types/RoboticVacuumCleaner.xml index fd30668cd2e084..d657d01d1984af 100644 --- a/data_model/master/device_types/RoboticVacuumCleaner.xml +++ b/data_model/master/device_types/RoboticVacuumCleaner.xml @@ -1,67 +1,70 @@ - - + + + - @@ -74,6 +77,14 @@ Davis, CA 95616, USA + + + + + + + + - \ No newline at end of file + diff --git a/data_model/master/device_types/RoomAirConditioner.xml b/data_model/master/device_types/RoomAirConditioner.xml index e2b3061a42b515..60ced5dac421b8 100644 --- a/data_model/master/device_types/RoomAirConditioner.xml +++ b/data_model/master/device_types/RoomAirConditioner.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -92,7 +93,7 @@ Davis, CA 95616, USA - + @@ -104,4 +105,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/RootNodeDeviceType.xml b/data_model/master/device_types/RootNodeDeviceType.xml index c96759503bfb13..b01044c7fa3295 100644 --- a/data_model/master/device_types/RootNodeDeviceType.xml +++ b/data_model/master/device_types/RootNodeDeviceType.xml @@ -1,70 +1,84 @@ - - + + + + + + + + + + + + + @@ -102,7 +116,7 @@ Davis, CA 95616, USA - + @@ -152,18 +166,18 @@ Davis, CA 95616, USA - + + + + - - - - - - + + + - \ No newline at end of file + diff --git a/data_model/master/device_types/SecondaryNetworkInterface.xml b/data_model/master/device_types/SecondaryNetworkInterface.xml index 8217aea71529d0..febbe65c24e2fd 100644 --- a/data_model/master/device_types/SecondaryNetworkInterface.xml +++ b/data_model/master/device_types/SecondaryNetworkInterface.xml @@ -1,59 +1,61 @@ - @@ -80,4 +82,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/SmokeCOAlarm.xml b/data_model/master/device_types/SmokeCOAlarm.xml index 769e6f5f91bbe1..a0e0766163b199 100644 --- a/data_model/master/device_types/SmokeCOAlarm.xml +++ b/data_model/master/device_types/SmokeCOAlarm.xml @@ -1,66 +1,67 @@ - - @@ -81,4 +82,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/SnapshotCamera.xml b/data_model/master/device_types/SnapshotCamera.xml new file mode 100644 index 00000000000000..d439d9e7b39cfe --- /dev/null +++ b/data_model/master/device_types/SnapshotCamera.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/SoilSensor.xml b/data_model/master/device_types/SoilSensor.xml new file mode 100644 index 00000000000000..4cb22c147528d3 --- /dev/null +++ b/data_model/master/device_types/SoilSensor.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/SolarPower.xml b/data_model/master/device_types/SolarPower.xml index 7556fb519a685d..21bedacedfecfd 100644 --- a/data_model/master/device_types/SolarPower.xml +++ b/data_model/master/device_types/SolarPower.xml @@ -1,69 +1,70 @@ - - - \ No newline at end of file + diff --git a/data_model/master/device_types/Speaker.xml b/data_model/master/device_types/Speaker.xml index d3f9b1166e4458..fa2712c29c561d 100644 --- a/data_model/master/device_types/Speaker.xml +++ b/data_model/master/device_types/Speaker.xml @@ -1,66 +1,67 @@ - - @@ -69,4 +70,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/TemperatureControlledCabinet.xml b/data_model/master/device_types/TemperatureControlledCabinet.xml index 68788e22d7db06..91b8052b919055 100644 --- a/data_model/master/device_types/TemperatureControlledCabinet.xml +++ b/data_model/master/device_types/TemperatureControlledCabinet.xml @@ -1,84 +1,97 @@ - - + + + + + + + - + - + - + + + + + + - + @@ -86,14 +99,14 @@ Davis, CA 95616, USA - + - + @@ -101,16 +114,24 @@ Davis, CA 95616, USA - + + + + + + + + + - \ No newline at end of file + diff --git a/data_model/master/device_types/TemperatureSensor.xml b/data_model/master/device_types/TemperatureSensor.xml index bf3221858dc103..373613a8f1de3d 100644 --- a/data_model/master/device_types/TemperatureSensor.xml +++ b/data_model/master/device_types/TemperatureSensor.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -75,4 +76,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/Thermostat.xml b/data_model/master/device_types/Thermostat.xml index dfc55d628a5b6e..32a5df5d6790d9 100644 --- a/data_model/master/device_types/Thermostat.xml +++ b/data_model/master/device_types/Thermostat.xml @@ -1,59 +1,61 @@ - @@ -63,16 +65,18 @@ Davis, CA 95616, USA - - + + + + @@ -89,10 +93,10 @@ Davis, CA 95616, USA - + - + @@ -113,4 +117,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/ThermostatController.xml b/data_model/master/device_types/ThermostatController.xml new file mode 100644 index 00000000000000..e6aea8d34c086d --- /dev/null +++ b/data_model/master/device_types/ThermostatController.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data_model/master/device_types/ThreadBorderRouter.xml b/data_model/master/device_types/ThreadBorderRouter.xml index 792f002801b9a0..e1f6326d6bf9aa 100644 --- a/data_model/master/device_types/ThreadBorderRouter.xml +++ b/data_model/master/device_types/ThreadBorderRouter.xml @@ -1,67 +1,71 @@ - - + + + @@ -72,4 +76,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/HumidifierDehumidifier.xml b/data_model/master/device_types/VideoDoorbell.xml similarity index 89% rename from data_model/master/device_types/HumidifierDehumidifier.xml rename to data_model/master/device_types/VideoDoorbell.xml index 973919635fb4ae..54d30c751a4f30 100644 --- a/data_model/master/device_types/HumidifierDehumidifier.xml +++ b/data_model/master/device_types/VideoDoorbell.xml @@ -1,63 +1,70 @@ - - + - + - \ No newline at end of file + + + + + + diff --git a/data_model/master/device_types/VideoRemoteControl.xml b/data_model/master/device_types/VideoRemoteControl.xml index de83b02508a89f..57e29b9e838c33 100644 --- a/data_model/master/device_types/VideoRemoteControl.xml +++ b/data_model/master/device_types/VideoRemoteControl.xml @@ -1,59 +1,61 @@ - @@ -61,7 +63,6 @@ Davis, CA 95616, USA - @@ -109,4 +110,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/WaterFreezeDetector.xml b/data_model/master/device_types/WaterFreezeDetector.xml index b2f4a49a7847e4..ffc734c41ba3ff 100644 --- a/data_model/master/device_types/WaterFreezeDetector.xml +++ b/data_model/master/device_types/WaterFreezeDetector.xml @@ -1,66 +1,67 @@ - - @@ -68,7 +69,7 @@ Davis, CA 95616, USA - + @@ -77,4 +78,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/WaterHeater.xml b/data_model/master/device_types/WaterHeater.xml index 9d038d89c55563..014d5d934bc3c5 100644 --- a/data_model/master/device_types/WaterHeater.xml +++ b/data_model/master/device_types/WaterHeater.xml @@ -1,66 +1,67 @@ - - @@ -68,7 +69,7 @@ Davis, CA 95616, USA - + @@ -80,10 +81,7 @@ Davis, CA 95616, USA - - - - \ No newline at end of file + diff --git a/data_model/master/device_types/WaterLeakDetector.xml b/data_model/master/device_types/WaterLeakDetector.xml index 7277ce69908fb6..a03c7a6a69dd41 100644 --- a/data_model/master/device_types/WaterLeakDetector.xml +++ b/data_model/master/device_types/WaterLeakDetector.xml @@ -1,66 +1,67 @@ - - @@ -68,7 +69,7 @@ Davis, CA 95616, USA - + @@ -77,4 +78,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/WaterValve.xml b/data_model/master/device_types/WaterValve.xml index 21b77edf5fc614..5cecee354bf8b8 100644 --- a/data_model/master/device_types/WaterValve.xml +++ b/data_model/master/device_types/WaterValve.xml @@ -1,66 +1,67 @@ - - @@ -75,4 +76,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/WindowCovering.xml b/data_model/master/device_types/WindowCovering.xml index da8780b3c94be4..d850fe234c8970 100644 --- a/data_model/master/device_types/WindowCovering.xml +++ b/data_model/master/device_types/WindowCovering.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -70,7 +71,7 @@ Davis, CA 95616, USA - + @@ -86,4 +87,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/device_types/WindowCoveringController.xml b/data_model/master/device_types/WindowCoveringController.xml index 189fee3d9d6303..a42da098600f4b 100644 --- a/data_model/master/device_types/WindowCoveringController.xml +++ b/data_model/master/device_types/WindowCoveringController.xml @@ -1,59 +1,61 @@ - @@ -62,7 +64,6 @@ Davis, CA 95616, USA - @@ -73,7 +74,7 @@ Davis, CA 95616, USA - + @@ -89,4 +90,4 @@ Davis, CA 95616, USA - \ No newline at end of file + diff --git a/data_model/master/scraper_version b/data_model/master/scraper_version index c813fe116c9f9e..03d9cee03ac4d6 100644 --- a/data_model/master/scraper_version +++ b/data_model/master/scraper_version @@ -1 +1 @@ -1.2.5 +alchemy version: 1.5.2 (4717a32) diff --git a/data_model/master/spec_sha b/data_model/master/spec_sha index a399f222280c76..c04b09ccd3a6a2 100644 --- a/data_model/master/spec_sha +++ b/data_model/master/spec_sha @@ -1 +1 @@ -ec20ddf482db8deffe8b2eb745e34d2f9cea72b2 +b5beeff24d47b6b3d3ee59b513b6e54f7c85269f diff --git a/data_model/master/spec_tag b/data_model/master/spec_tag new file mode 100644 index 00000000000000..8e0e9f5f2cb002 --- /dev/null +++ b/data_model/master/spec_tag @@ -0,0 +1 @@ +0.7-summer-2025 diff --git a/docs/conf.py b/docs/conf.py index 52402d86518b80..cb389d6717df3c 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -72,6 +72,7 @@ (MATTER_BASE, "examples/**/*.JPG"), (MATTER_BASE, "src/tools/**/*.md"), (MATTER_BASE, "scripts/tools/**/*.md"), + (MATTER_BASE, "scripts/tools/**/*.png"), ] external_content_link_prefixes = [ "src/", diff --git a/docs/platforms/android/android_building.md b/docs/platforms/android/android_building.md index 830ff11ed3fb4b..c7b87372e38f84 100644 --- a/docs/platforms/android/android_building.md +++ b/docs/platforms/android/android_building.md @@ -56,11 +56,11 @@ downloaded. 4. Apply 3. Install Command Line Tools: 1. Tools -> SDK Manager -> SDK Tools Tab -> Android SDK Command Line Tools - (latest) + 10.0 2. Apply -4. Install SDK 26: - 1. Tools -> SDK Manager -> SDK Platforms Tab -> Android 8.0 (Oreo) SDK Level - 26 +4. Install SDK 30: + 1. Tools -> SDK Manager -> SDK Platforms Tab -> Android 11.0 (R) SDK Level + 30 2. Apply 5. Install Emulator: 1. Tools -> Device Manager -> Create device -> Pixel 5 -> Android S API 31 @@ -98,21 +98,21 @@ architecture: ### Gradle & JDK Version -All Android projects utilize Gradle version 7.3.3 and JDK version 17.0. +All Android projects utilize Gradle version 7.3.3 and JDK version 11.0. -For developer using openjdk-17-jdk in MacOS, the JAVA_HOME environment variable -can be configured as follows via `sdkman`: +For developer using java 11 in MacOS, the JAVA can be configured as follows via +`sdkman`: ``` -sdk install java 17.0.4.1-tem +sdk install java 11.0.26-tem ``` -For developer using openjdk-17-jdk in Linux, the JAVA_HOME environment variable +For developer using openjdk-11-jdk in Linux, the JAVA_HOME environment variable can be configured as follows: ``` -sudo apt-get install openjdk-17-jdk -export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 +sudo apt-get install openjdk-11-jdk +export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 ``` diff --git a/docs/platforms/bouffalolab/getting_started.md b/docs/platforms/bouffalolab/getting_started.md index eb96bc8da04728..08d61fce816c49 100644 --- a/docs/platforms/bouffalolab/getting_started.md +++ b/docs/platforms/bouffalolab/getting_started.md @@ -17,24 +17,34 @@ git clone --recurse-submodules https://github.com/project-chip/connectedhomeip.g git clone --depth=1 https://github.com/project-chip/connectedhomeip.git ``` -- check out `Bouffalo Lab` platform support repos as follows: +- Check out necessary submodules + + Checkout `BL_IOT_SDK` for `BL602`, `BL702` and `BL702L` platform: + + ``` + ./scripts/checkout_submodules.py --shallow --recursive --platform bouffalolab + ``` + + Checkout `bouffalo_sdk` for `BL616` platform: ``` - scripts/checkout_submodules.py --shallow --recursive --platform bouffalolab + ./scripts/checkout_submodules.py --shallow --recursive --platform bouffalo_sdk ``` + > Please contact `Bouffalo Lab` for `BL616` SDK access. + If you want to checkout Matter Linux example and development tools, please try as follows: ``` - scripts/checkout_submodules.py --shallow --recursive --platform linux bouffalolab + ./scripts/checkout_submodules.py --shallow --recursive --platform linux bouffalolab ``` Or if you want to checkout Matter Darwin example and development tools, please try as follows: ``` - scripts/checkout_submodules.py --shallow --recursive --platform darwin bouffalolab + ./scripts/checkout_submodules.py --shallow --recursive --platform darwin bouffalolab ``` # Setup build environment diff --git a/docs/platforms/bouffalolab/matter_factory_data.md b/docs/platforms/bouffalolab/matter_factory_data.md index 9021cd80f61815..b46cb4801bef50 100644 --- a/docs/platforms/bouffalolab/matter_factory_data.md +++ b/docs/platforms/bouffalolab/matter_factory_data.md @@ -71,7 +71,7 @@ Script tool call `chip-cert` to generate test certificates and verify certificates. Please run below command to compile `chip-cert` tool under `connnectedhomeip` -repo. +repo for Linux platform. ```shell ./scripts/build/build_examples.py --target linux-x64-chip-cert build @@ -111,9 +111,18 @@ repo. Please reference to `--help` for more detail. -## Generate with default test certificates +## Generate with default configuration -- Run following command to generate all plain text factory data +- Default setting uses the following parameters + + - PAI certification: + [test PAI certification](../../../credentials/test/attestation/Chip-Test-PAI-FFF1-8000-Key.pem) + + - Vendor ID for DAC: 0xFFF1; Vendor ID for CD: 0x130d + + - Product ID for DAC: 0x8000, Product ID for CD: 0x1001 + +* Run following command to generate all plain text factory data Please create output folder first. Here takes `out/test-cert` as example. @@ -121,14 +130,28 @@ Please reference to `--help` for more detail. ./scripts/tools/bouffalolab/generate_factory_data.py --output out/test-cert ``` -- Run following command to generate factory data which encrypt private of + - Check DAC certificate. Here takes `out_130d_1001_106_dac_cert.pem` as + generated test certificate. + + ```shell + openssl x509 -noout -text -in out/test-cert/out_130d_1001_106_dac_cert.pem + ``` + + - Check Certification Declare. Here takes `out_130d_1001_cd.der` as + generated test certificate. + + ```shell + ./out/linux-x64-chip-cert/chip-cert print-cd out/test-cert/out_130d_1001_cd.der + ``` + +* Run following command to generate factory data which encrypt private of device attestation data ```shell ./scripts/tools/bouffalolab/generate_factory_data.py --output out/test-cert --key ``` - > An example of hex string of 16 bytes: 12345678123456781234567812345678 + > An example of hex string of 16 bytes: 12345678123456781234567812345678. After command executes successfully, the output folder will has files as below: @@ -153,20 +176,26 @@ After command executes successfully, the output folder will has files as below: Self-defined PAA/PAI certificates may use in development and test scenario. But, user should know it has limit to work with real ecosystem. -- Export environment variables in terminal for easy operations +- Export environment variables in terminal for certificates generation ``` - export TEST_CERT_VENDOR_ID=130D # Vendor ID hex string - export TEST_CERT_CN=BFLB # Common Name + export TEST_CERT_VENDOR_ID=130D # Vendor ID hex string + export TEST_CERT_PRODUCT_ID=1001 # Product ID hex string + export TEST_CERT_CN=BFLB # Common Name ``` - Generate PAA certificate and key to `out/cert` folder. ```shell - mkdir out/test-cert ./out/linux-x64-chip-cert/chip-cert gen-att-cert --type a --subject-cn "${TEST_CERT_CN} PAA 01" --valid-from "2020-10-15 14:23:43" --lifetime 7305 --out-key out/test-cert/Chip-PAA-Key-${TEST_CERT_VENDOR_ID}.pem --out out/test-cert/Chip-PAA-Cert-${TEST_CERT_VENDOR_ID}.pem --subject-vid ${TEST_CERT_VENDOR_ID} ``` + - Check PAA certificate + + ```shell + openssl x509 -noout -text -in out/test-cert/Chip-PAA-Cert-${TEST_CERT_VENDOR_ID}.pem + ``` + - Convert PAA PEM format file to PAA DER format file ```shell @@ -182,14 +211,84 @@ user should know it has limit to work with real ecosystem. ./out/linux-x64-chip-cert/chip-cert gen-att-cert --type i --subject-cn "${TEST_CERT_CN} PAI 01" --subject-vid ${TEST_CERT_VENDOR_ID} --valid-from "2020-10-15 14:23:43" --lifetime 7305 --ca-key out/test-cert/Chip-PAA-Key-${TEST_CERT_VENDOR_ID}.pem --ca-cert out/test-cert/Chip-PAA-Cert-${TEST_CERT_VENDOR_ID}.pem --out-key out/test-cert/Chip-PAI-Key-${TEST_CERT_VENDOR_ID}.pem --out out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem ``` -- Generate `MFD` in plain text data + - Check PAI certificate - ```shell - ./scripts/tools/bouffalolab/generate_factory_data.py --output out/test-cert --paa_cert out/test-cert/Chip-PAA-Cert-${TEST_CERT_VENDOR_ID}.pem --paa_key out/test-cert/Chip-PAA-Key-${TEST_CERT_VENDOR_ID}.pem --pai_cert out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem --pai_key out/test-cert/Chip-PAI-Key-${TEST_CERT_VENDOR_ID}.pem - ``` + ```shell + openssl x509 -noout -text -in out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem + ``` - > Appending `--key ` option to enable encrypt - > private key of attestation device data. +- Generate `MFD` in plain text data with same VID/PID in DAC and CD + + - Use same environment variables `TEST_CERT_VENDOR_ID` and + `TEST_CERT_PRODUCT_ID` for CD. + + ```shell + ./scripts/tools/bouffalolab/generate_factory_data.py --output out/test-cert --paa_cert out/test-cert/Chip-PAA-Cert-${TEST_CERT_VENDOR_ID}.pem --paa_key out/test-cert/Chip-PAA-Key-${TEST_CERT_VENDOR_ID}.pem --pai_cert out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem --pai_key out/test-cert/Chip-PAI-Key-${TEST_CERT_VENDOR_ID}.pem --dac_pid 0x${TEST_CERT_PRODUCT_ID} --vendor_id 0x${TEST_CERT_VENDOR_ID} --product_id 0x${TEST_CERT_PRODUCT_ID} + ``` + + > Appending `--key ` option to enable encrypt + > private key of attestation device data. + + - Check DAC certificate. Here takes `out_130d_1001_1349_dac_cert.pem` as + generated test certification. + + ```shell + openssl x509 -noout -text -in out/test-cert/out_130d_1001_1349_dac_cert.pem + ``` + + - Check PAA/PAI/DAC certificate chain. + + ```shell + ./out/linux-x64-chip-cert/chip-cert validate-att-cert --dac out/test-cert/out_130d_1001_1349_dac_cert.pem --pai out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem --paa out/test-cert/Chip-PAA-Cert-${TEST_CERT_VENDOR_ID}.pem + ``` + + - Check Certification Declare. Here takes `out_130d_1001_cd.der` as + generated test certification. + + ```shell + ./out/linux-x64-chip-cert/chip-cert print-cd out/test-cert/out_130d_1001_cd.der + ``` + +- Generate `MFD` in plain text data with different VID/PID in DAC and CD + + - Export vendor ID and product ID for CD + + ```shell + export TEST_CD_VENDOR_ID=730D # Vendor ID hex string + export TEST_CD_PRODUCT_ID=7001 # Product ID hex string + ``` + + - Run script to generate DAC/CD and `MFD`. + + ```shell + ./scripts/tools/bouffalolab/generate_factory_data.py --output out/test-cert --paa_cert out/test-cert/Chip-PAA-Cert-${TEST_CERT_VENDOR_ID}.pem --paa_key out/test-cert/Chip-PAA-Key-${TEST_CERT_VENDOR_ID}.pem --pai_cert out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem --pai_key out/test-cert/Chip-PAI-Key-${TEST_CERT_VENDOR_ID}.pem --dac_pid 0x${TEST_CERT_PRODUCT_ID} --vendor_id 0x${TEST_CD_VENDOR_ID} --product_id 0x${TEST_CD_PRODUCT_ID} + ``` + + > Appending `--key ` option to enable encrypt + > private key of attestation device data. + > + > Please use --`vendor_name` and `--product_name` to change vendor name + > and product name. + + - Check DAC certificate. Here takes `out_130d_1001_1349_dac_cert.pem` as + generated test certification. + + ```shell + openssl x509 -noout -text -in out/test-cert/out_130d_1001_1349_dac_cert.pem + ``` + + - Check PAA/PAI/DAC certificate chain. + + ```shell + ./out/linux-x64-chip-cert/chip-cert validate-att-cert --dac out/test-cert/out_130d_1001_1349_dac_cert.pem --pai out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem --paa out/test-cert/Chip-PAA-Cert-${TEST_CERT_VENDOR_ID}.pem + ``` + + - Check Certification Declare. Here takes `out_730D_7001_cd.der` as + generated test certification. + + ```shell + ./out/linux-x64-chip-cert/chip-cert print-cd out/test-cert/out_130d_1001_cd.der + ``` ## Generate with self-defined DAC certificate and key @@ -200,14 +299,14 @@ user should know it has limit to work with real ecosystem. ``` export TEST_CERT_VENDOR_ID=130D # Vendor ID hex string - export TEST_CERT_PRODUCT_ID=1001 # Vendor ID hex string + export TEST_CERT_PRODUCT_ID=1001 # Product ID hex string export TEST_CERT_CN=BFLB # Common Name ``` - Generate DAC certificate and key ```shell - out/linux-x64-chip-cert/chip-cert gen-att-cert --type d --subject-cn "${TEST_CERT_CN} PAI 01" --subject-vid ${TEST_CERT_VENDOR_ID} --subject-pid ${TEST_CERT_VENDOR_ID} --valid-from "2020-10-16 14:23:43" --lifetime 5946 --ca-key out/test-cert/Chip-PAI-Key-${TEST_CERT_VENDOR_ID}.pem --ca-cert out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem --out-key out/test-cert/Chip-DAC-Key-${TEST_CERT_VENDOR_ID}-${TEST_CERT_PRODUCT_ID}.pem --out out/test-cert/Chip-DAC-Cert-${TEST_CERT_VENDOR_ID}-${TEST_CERT_PRODUCT_ID}.pem + out/linux-x64-chip-cert/chip-cert gen-att-cert --type d --subject-cn "${TEST_CERT_CN} PAI 01" --subject-vid ${TEST_CERT_VENDOR_ID} --subject-pid ${TEST_CERT_PRODUCT_ID} --valid-from "2020-10-16 14:23:43" --lifetime 5946 --ca-key out/test-cert/Chip-PAI-Key-${TEST_CERT_VENDOR_ID}.pem --ca-cert out/test-cert/Chip-PAI-Cert-${TEST_CERT_VENDOR_ID}.pem --out-key out/test-cert/Chip-DAC-Key-${TEST_CERT_VENDOR_ID}-${TEST_CERT_PRODUCT_ID}.pem --out out/test-cert/Chip-DAC-Cert-${TEST_CERT_VENDOR_ID}-${TEST_CERT_PRODUCT_ID}.pem ``` > **Note**, `--valid-from` and `--lifetime` should be in `--valid-from` and @@ -238,12 +337,5 @@ key. > If `MFD` file has cipher text data, please append > `--key ` option to program to this key to efuse. -- Limits on BL IOT SDK - - If developer would like to program `MFD` with all plain text data, option - `--key ` needs pass to script, otherwise, flash tool - will raise an error. And SoC BL602, BL702 and BL702L use BL IOT SDK for - Matter Application. - Please free contact to `Bouffalo Lab` for DAC provider service and higher security solution, such as SoC inside certificate requesting. diff --git a/docs/testing/pics_and_pixit.md b/docs/testing/pics_and_pixit.md index ee8901c66fecab..ede71a94ee3819 100644 --- a/docs/testing/pics_and_pixit.md +++ b/docs/testing/pics_and_pixit.md @@ -1,10 +1,194 @@ # PICS and PIXITs -Placeholder file for PICS and PIXIT info - -- PICS formats - XML vs. test harness -- PICS in CI -- PICS tool and how we practically use it in Matter -- PICS checker test -- PIXITs in tests and how to set them -- Why you should avoid using both of these things. +## What are PICS + +In many Standards Defining Organizations including the CSA, the concept of a +“Protocol Implementation Conformance Statement” or “PICS” code is introduced to +simplify description of protocol elements. + +Each PICS code is a binary value that describes the presence or absence of a +particular element or capability on a device. Each cluster has a defined PICS +prefix string and defines a set of PICS codes to describe whether the cluster is +present, and the presence of each feature, attribute, command, and event for +both the server and client side. + +For example if there was a cluster ANeatCluster with the PICS code ANC, two +features (bit 0 and 1), two attributes (0x0000 and 0x0001), two accepted +commands (0x00 and 0x01), a single command response (0x02) and one event (0x00), +the following PICS codes would be defined + +| CODE | Desc | +| ------------- | -------------------------------------------------------------------------- | +| ANC.S | Device implements the ANC cluster as a server | +| ANC.S.F00 | Device implements ANC feature at bit 0 on the ANC server cluster | +| ANC.S.F01 | Device implements ANC feature at bit 1 on the ANC server cluster | +| ANC.S.A0000 | Device implements ANC attribute 0x0000 on the ANC server cluster | +| ANC.S.A0001 | Device implements ANC attribute 0x0001 on the ANC server cluster | +| ANC.S.C00.Rsp | Device accepts ANC command 0x00 on the ANC server cluster | +| ANC.S.C01.Rsp | Device accepts ANC command 0x00 on the ANC server cluster | +| ANC.S.C02.Tx | Device generates ANC command response 0x02 on the ANC server cluster | +| ANC.S.E00 | Device generates ANC event 0x00 on the ANC server cluster | +| ANC.C | Device supports an ANC client | +| ANC.C.F00 | Device ANC client is capable of understanding the feature with bit 0 | +| ANC.C.F01 | Device ANC client is capable of understanding the feature with bit 0 | +| ANC.C.A0000 | Device ANC client is capable of reading or subscribing to attribute 0x0000 | +| ANC.C.A0001 | Device ANC client is capable of reading or subscribing to attribute 0x0001 | +| ANC.C.C00.Rsp | Device ANC client is capable of sending the command with id 0x00 | +| ANC.C.C01.Rsp | Device ANC client is capable of sending the command with id 0x01 | +| ANC.C.C02.Tx | Device ANC client understands the command response with id 0x02 | +| ANC.C.E00 | Device ANC client understands the event with id 0x00 | + +More information about the PICS code format can be found at +[PICS Guidelines](https://github.com/CHIP-Specifications/chip-test-plans/blob/master/docs/PICS%20Guidelines.md). + +In addition to these standard cluster PICS, other PICS may be defined to +describe capabilities that are not directly expressed via the data model. For +example, whether the device responds to manual operations that affect the Matter +data model. + +Additionally, there are node-level PICS, which appear as a part of the MCORE +PICS set. These PICS codes describe node level support such as the radio, +whether the device is commissionable, whether the device comes with a QR code +etc. + +PICS are used in testing in two ways. "Top level" PICS appear at the top of the +test plan and indicate whether an entire test case should be run. For example, a +test case for ANeatCluster would have a top-level PICS of ANC.S to indicate that +the test would only be run if the ANC cluster is present on the endpoint. Test +cases also use PICS to gate individual steps of the test which are not +applicable if a certain element or capability is not implemented. + +The entire collection of PICS codes for a specification release is provided as a +set of PICS XML files. These files are loaded into the PICS tool, which is used +to manually set all the PICS codes for a device. The PICS XML files and the PICS +tool are distributed as part of the official specification release package and +are available on +[Causeway](https://groups.csa-iot.org/wg/members-all/document/folder/2269). + +### PIXITs + +PIXIT stands for Protocol Implementation eXtra Information for Testing. A PIXIT +value provides an implementation-defined condition or value that is required by +the test. + +PIXIT values are used to convey information that is required for testing, but +not normally available to a client interacting with the device. For example, the +key for a test event trigger on the device, or the network credentials for the +test harness. + +More information on PIXITs and the PIXIT format can be found in the +[PICS Guidelines](https://github.com/CHIP-Specifications/chip-test-plans/blob/master/docs/PICS%20Guidelines.md). + +## Creating PICS conformance statements for Matter devices + +Because Matter devices may contain multiple, differing instances of the same +cluster on multiple endpoints, it it not possible to unambiguously describe a +Matter device with a single set of cluster-based PICS files. Instead, Matter +devices use a full set of PICS XML files to describe each endpoint. + +To create a conformance statement for a Matter device, for each endpoint, load +the full set of PICS XML files into the +[PICS tool](https://picstool.csa-iot.org/), and select each of the PICS elements +present for the endpoint being described. Documentation on how to use the PICS +tool can be found in the PICS tool readme in the tool menu. + +Some of of the full-node MCORE elements really only apply to the root node, +while others apply across all endpoints. For example, the entire device is +commissionable, but commissioning tests only need to be run against EP0, so +MCORE PICS should be set on the EP0 PICS set. Things like MCORE.IDM apply to +every endpoint. + +### Helper scripts + +The official tooling for CSA certification is the PICS tool provided as a part +of the release. PICS files need to pass validation on the PICS tool to be valid +for certification. + +However, in Matter, many of the PICS codes correspond directly to elements that +are exposed directly on the device. For example, cluster presence is determined +from the server list on an endpoint, feature maps, attribute and command lists +correspond directly to the PICS.S.Fxx, PICS.S.Axxxx and PICS.S.Cxx.Xx PICS +codes. The Matter SDK provides a tool to pre-fill these values in the PICS XML +files so they do not have to be individually, manually filled in the PICS tool. + +- [PICS Generator](https://github.com/project-chip/connectedhomeip/tree/master/src/tools/PICS-generator) + +PICS codes filled using this tool still need to be validated by the PICS tool. +Note that due to device limitations, the tool will NOT fill the following +categories of PICS codes, and these will need to be filled manually in the PICS +tool: + +- Event PICS (PICS.S.Exx) +- Client PICS +- MCORE (base.xml) PICS +- Manual or other non-element PICS +- PICS describing whether optionally-writable attributes are writable +- any other non-element PICS + +It is important to note that this script is NOT the official tool for PICS +generation, just a helper to assist with this manual process. It is very +important to go back and check that the values are as expected and to fill in +the other PICS. + +### Verifying PICS using the IDM-10.4 certification test + +While not all PICS are verifiable on the device, we do have tests that verify +the declared PICS against the device. This is one of the first tests that should +be run at certification, as the PICS files are what determine which set of tests +are required. + +To run these tests locally, follow the instructions at +[Running Python tests locally](./python.md#running-tests-locally). The PICS +checker test is TC-IDM-10.4, implemented in +[TC_pics_checker.py](https://github.com/project-chip/connectedhomeip/blob/master/src/python_testing/TC_pics_checker.py). +These tests run a single set of PICS XML files against an endpoint. The +`--endpoint` and `--PICS` flags are therefore required. + +Note that you can run tests locally against the PICS XMLs for an endpoint by +supplying the name of the directory containing the set of PICS XML files for +that endpoint. + +## Setting PIXITs for Matter devices + +Matter tests do not currently have support to read PIXIT values from the PICS +XML files. Instead, tests implement PIXITs as test-specific flags. When running +locally, these are specified on the command line. When running in the test +harness, these are specified in the test parameters section of the test +configuration. + +## PICS for test selection + +The official source that the CSA certification team uses to determine if all the +required tests have been run at certification is the submitted set of PICS XML +files and the PICS tool. + +To generate this set of tests for each endpoint, load all the filled PICS XML +files for a single endpoint into the PICS tool and validate the PICS files. The +PICS files should validate properly. This will also generate the list of test +cases. + +Note that the TH will also guide test selection by pre-selecting the required +tests based on the PICS file, but it is the responsibility of the testers and +the ATL to ensure that all the required tests are run and the results are +submitted. + +## Creating PICS / PIXITs for new cluster and use in test plans + +Placeholder for more information coming in a subsequent PR. Needs to cover + +- formatting (link out to test plans doc) +- requirement to have all the elements listed +- how to do conformance in a way the PICS tool can handle - (note - special + attention to choice conformance, otherwise conformance) +- why you shouldn't use PICS values in tests other than at the top level + +## Using PICS in test scripts + +Placeholder for more information coming in a subsequent PR. Needs to cover +top-level and step-wise pics in yaml and python and also where they should NOT +be used. + +## CI PICS format + +Placeholder for information about the CI PICS format, CI-only PICS and the +gotchas there. diff --git a/examples/all-clusters-app/ameba/README.md b/examples/all-clusters-app/ameba/README.md index d00ff787640d1a..c2a33bbb173a1b 100644 --- a/examples/all-clusters-app/ameba/README.md +++ b/examples/all-clusters-app/ameba/README.md @@ -27,11 +27,11 @@ The CHIP demo application is supported on - Pull docker image: - $ docker pull ghcr.io/project-chip/chip-build-ameba:104 + $ docker pull ghcr.io/project-chip/chip-build-ameba:112 - Run docker container: - $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:104 + $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:112 - Setup build environment: diff --git a/examples/all-clusters-minimal-app/ameba/README.md b/examples/all-clusters-minimal-app/ameba/README.md index e57074ae1621ec..f8d343a1d2f300 100644 --- a/examples/all-clusters-minimal-app/ameba/README.md +++ b/examples/all-clusters-minimal-app/ameba/README.md @@ -27,13 +27,13 @@ The CHIP demo application is supported on - Pull docker image: ``` - $ docker pull ghcr.io/project-chip/chip-build-ameba:104 + $ docker pull ghcr.io/project-chip/chip-build-ameba:112 ``` - Run docker container: ``` - $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:104 + $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:112 ``` - Setup build environment: diff --git a/examples/android/CHIPTest/BUILD.gn b/examples/android/CHIPTest/BUILD.gn index 7dee07e6f693c1..e465415a221f72 100644 --- a/examples/android/CHIPTest/BUILD.gn +++ b/examples/android/CHIPTest/BUILD.gn @@ -72,7 +72,7 @@ android_library("java") { } java_prebuilt("android") { - jar_path = "${android_sdk_root}/platforms/android-26/android.jar" + jar_path = "${android_sdk_root}/platforms/android-30/android.jar" } group("default") { diff --git a/examples/chip-tool/commands/dcl/test_dcl_server.py b/examples/chip-tool/commands/dcl/test_dcl_server.py index f22f2d2a8e9390..1b68904b4f64b0 100755 --- a/examples/chip-tool/commands/dcl/test_dcl_server.py +++ b/examples/chip-tool/commands/dcl/test_dcl_server.py @@ -211,19 +211,25 @@ def handle_tc_request(self, vendor_id, product_id): def run_https_server(cert_file="cert.pem", key_file="key.pem"): - httpd = http.server.HTTPServer( - (DEFAULT_HOSTNAME, DEFAULT_PORT), RESTRequestHandler) - - httpd.socket = ssl.wrap_socket( - httpd.socket, - server_side=True, - certfile=cert_file, - keyfile=key_file, - ssl_version=ssl.PROTOCOL_TLS, - ) - - print(f"Serving on https://{DEFAULT_HOSTNAME}:{DEFAULT_PORT}") - httpd.serve_forever() + # Creates a basic HTTP server instance that listens on DEFAULT_HOSTNAME and DEFAULT_PORT + # RESTRequestHandler handles incoming HTTP requests + httpd = http.server.HTTPServer((DEFAULT_HOSTNAME, DEFAULT_PORT), RESTRequestHandler) + + # Creates an SSL context using TLS protocol for secure communications + context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + + # Loads the SSL certificate and private key for the server + # cert_file: contains the server's public certificate + # key_file: contains the server's private key + context.load_cert_chain(certfile=cert_file, keyfile=key_file) + + # Uses a context manager (with statement) to wrap the HTTP server's socket with SSL + # server_side=True indicates this is a server socket + # The wrapped socket is automatically closed when exiting the with block + with context.wrap_socket(httpd.socket, server_side=True) as httpd.socket: + print(f"Serving on https://{DEFAULT_HOSTNAME}:{DEFAULT_PORT}") + # Starts the server and runs indefinitely, handling incoming HTTPS requests + httpd.serve_forever() # Generate self-signed certificates if needed diff --git a/examples/contact-sensor-app/bouffalolab/bl702l/app_pds.cpp b/examples/contact-sensor-app/bouffalolab/bl702l/app_pds.cpp index e3ed09ae6393c1..d6b2141108d75c 100644 --- a/examples/contact-sensor-app/bouffalolab/bl702l/app_pds.cpp +++ b/examples/contact-sensor-app/bouffalolab/bl702l/app_pds.cpp @@ -59,17 +59,9 @@ extern "C" void vApplicationSleep(TickType_t xExpectedIdleTime) extern BaseType_t TrapNetCounter, *pTrapNetCounter; if (app_pds_wakeup_source == PDS_WAKEUP_BY_RTC) { - extern void * pxCurrentTCB; - - ChipLogProgress(NotSpecified, "wakeup source: rtc. %lu vs %lu ms @ %lu\r\n", xExpectedIdleTime, - (uint32_t) (bl_rtc_get_timestamp_ms() - sleep_before), (uint32_t) bl_rtc_get_timestamp_ms()); - - ChipLogProgress(NotSpecified, "application_sleep; %lu, %lu, %lu\r\n", (uint32_t) sleep_calling_time, (uint32_t) sleep_time, - (uint32_t) wakeup_time); } else if (app_pds_wakeup_source == PDS_WAKEUP_BY_GPIO) { - if (((1 << CHIP_RESET_PIN) & app_pds_wakeup_pin) && app_pds_irq_handler) { app_pds_irq_handler(&gpio_key); @@ -79,10 +71,6 @@ extern "C" void vApplicationSleep(TickType_t xExpectedIdleTime) { app_pds_irq_handler(&gpio_contact); } - - ChipLogProgress(NotSpecified, "wakeup source: gpio -> 0x%08lX. %lu vs %lu ms @ %lu\r\n", app_pds_wakeup_pin, - xExpectedIdleTime, (uint32_t) (bl_rtc_get_timestamp_ms() - sleep_before), - (uint32_t) bl_rtc_get_timestamp_ms()); } app_pds_wakeup_source = -1; diff --git a/examples/fabric-admin/README.md b/examples/fabric-admin/README.md index 600d50cd5a4ffa..be8d5effa8d8b4 100644 --- a/examples/fabric-admin/README.md +++ b/examples/fabric-admin/README.md @@ -23,13 +23,13 @@ For Raspberry Pi 4 example: ### Pull Docker Images ``` -docker pull ghcr.io/project-chip/chip-build-crosscompile:104 +docker pull ghcr.io/project-chip/chip-build-crosscompile:112 ``` ### Run docker ``` -docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:104 /bin/bash +docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:112 /bin/bash ``` ### Build diff --git a/examples/fabric-bridge-app/linux/README.md b/examples/fabric-bridge-app/linux/README.md index 20889041007b97..1a9ee06bb8f596 100644 --- a/examples/fabric-bridge-app/linux/README.md +++ b/examples/fabric-bridge-app/linux/README.md @@ -100,13 +100,13 @@ defined: Pull Docker Images ``` - docker pull ghcr.io/project-chip/chip-build-crosscompile:104 + docker pull ghcr.io/project-chip/chip-build-crosscompile:112 ``` Run docker ``` - docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:104 /bin/bash + docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:112 /bin/bash ``` Build diff --git a/examples/fabric-sync/README.md b/examples/fabric-sync/README.md index 64fee61b3431de..9848d33d867d72 100644 --- a/examples/fabric-sync/README.md +++ b/examples/fabric-sync/README.md @@ -92,13 +92,13 @@ defined: Pull Docker Images ```sh - docker pull ghcr.io/project-chip/chip-build-crosscompile:104 + docker pull ghcr.io/project-chip/chip-build-crosscompile:112 ``` Run docker ```sh - docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:104 /bin/bash + docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:112 /bin/bash ``` Build diff --git a/examples/java-matter-controller/README.md b/examples/java-matter-controller/README.md index 7f557d5e82fc72..46234e02cf514e 100644 --- a/examples/java-matter-controller/README.md +++ b/examples/java-matter-controller/README.md @@ -9,8 +9,9 @@ cluster requests to a Matter device - [Matter Controller Java App Example](#matter-controller-java-app-example) - [Requirements for building](#requirements-for-building) + - [Linux](#linux) - [Preparing for build](#preparing-for-build) - - [Building & Running the app](#building--running-the-app) + - [Building \& Running the app](#building--running-the-app)
@@ -47,6 +48,8 @@ system. You can install it through the following command as root: sudo apt install default-jdk ``` +Note: Current matter controller java app example needs java 8+. + You also need to install kotlin compiler on your Ubuntu system: kotlin compiler version 1.8.10 or above is needed to compile @@ -93,7 +96,7 @@ export PATH="/usr/lib/kotlinc/bin:$PATH" ### Linux ```shell -export JAVA_PATH=[JDK path] +export JAVA_HOME=[JDK path] ```
diff --git a/examples/kotlin-matter-controller/README.md b/examples/kotlin-matter-controller/README.md index 71a954e711e0b5..624df71b544dce 100644 --- a/examples/kotlin-matter-controller/README.md +++ b/examples/kotlin-matter-controller/README.md @@ -7,8 +7,9 @@ control Matter accessory devices. - [Matter Controller Kotlin App Example](#matter-controller-kotlin-app-example) - [Requirements for building](#requirements-for-building) + - [Linux](#linux) - [Preparing for build](#preparing-for-build) - - [Building & Running the app](#building--running-the-app) + - [Building \& Running the app](#building--running-the-app)
@@ -82,7 +83,7 @@ export PATH="/usr/lib/kotlinc/bin:$PATH" ### Linux ```shell -export JAVA_PATH=[JDK path] +export JAVA_HOME=[JDK path] ```
diff --git a/examples/light-switch-app/ameba/README.md b/examples/light-switch-app/ameba/README.md index a57df10e44e032..9c15bb601ceb6d 100644 --- a/examples/light-switch-app/ameba/README.md +++ b/examples/light-switch-app/ameba/README.md @@ -26,11 +26,11 @@ The CHIP demo application is supported on - Pull docker image: - $ docker pull ghcr.io/project-chip/chip-build-ameba:104 + $ docker pull ghcr.io/project-chip/chip-build-ameba:112 - Run docker container: - $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:104 + $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:112 - Setup build environment: diff --git a/examples/lighting-app/ameba/README.md b/examples/lighting-app/ameba/README.md index ad6e173246489e..bca3ba5a828650 100644 --- a/examples/lighting-app/ameba/README.md +++ b/examples/lighting-app/ameba/README.md @@ -23,11 +23,11 @@ The CHIP demo application is supported on - Pull docker image: - $ docker pull ghcr.io/project-chip/chip-build-ameba:104 + $ docker pull ghcr.io/project-chip/chip-build-ameba:112 - Run docker container: - $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:104 + $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:112 - Setup build environment: diff --git a/examples/lighting-app/bouffalolab/bl602/BUILD.gn b/examples/lighting-app/bouffalolab/bl602/BUILD.gn index c45251824fefbb..fa35de6932f25b 100644 --- a/examples/lighting-app/bouffalolab/bl602/BUILD.gn +++ b/examples/lighting-app/bouffalolab/bl602/BUILD.gn @@ -76,7 +76,6 @@ bl_iot_sdk("sdk") { "OTA_AUTO_REBOOT_DELAY=${ota_auto_reboot_delay_seconds}", "CHIP_UART_BAUDRATE=${baudrate}", "SYS_AOS_LOOP_ENABLE", - "CHIP_SYSTEM_CRYPTO_HEADER_RESERVE_SIZE=48", ] defines += [ "PW_RPC_ENABLED=${chip_enable_pw_rpc}" ] @@ -97,7 +96,7 @@ bouffalolab_executable("lighting_app") { output_name = "chip-bl602-lighting-example.out" defines = [ - "APP_TASK_STACK_SIZE=2044", + "APP_TASK_STACK_SIZE=4096", "CHIP_UART_BAUDRATE=${baudrate}", "START_ENTRY=bfl_main", "SYS_AOS_LOOP_ENABLE", @@ -110,6 +109,10 @@ bouffalolab_executable("lighting_app") { defines += [ "CONFIG_BOUFFALOLAB_FACTORY_DATA_ENABLE=${chip_enable_factory_data}" ] + if (enable_lwip_pbuf_ram) { + defines += [ "CHIP_SYSTEM_CONFIG_PACKETBUFFER_LWIP_PBUF_RAM=1" ] + } + bl_plat_name = "bl602" sources = [ "${examples_plat_dir}/common/route_hook/bl_route_hook.c", @@ -228,6 +231,10 @@ bouffalolab_executable("lighting_app") { inputs = [ ldscript ] if (chip_print_memory_usage) { + if (enable_lwip_pbuf_ram) { + ldflags += [ "-Wl,--defsym=__RAM_PBUF_POOL=0" ] + } + ldflags += [ "-Wl,--print-memory-usage", "-fstack-usage", diff --git a/examples/lighting-app/bouffalolab/bl616/BUILD.gn b/examples/lighting-app/bouffalolab/bl616/BUILD.gn index 6671db3f9f7a6d..6890ad52000eee 100644 --- a/examples/lighting-app/bouffalolab/bl616/BUILD.gn +++ b/examples/lighting-app/bouffalolab/bl616/BUILD.gn @@ -121,6 +121,10 @@ bouffalolab_executable("lighting_app") { defines += [ "BOOT_PIN_RESET=2" ] } + if (enable_lwip_pbuf_ram) { + defines += [ "CHIP_SYSTEM_CONFIG_PACKETBUFFER_LWIP_PBUF_RAM=1" ] + } + defines += [ "BL616DK" ] sources = [ diff --git a/examples/lighting-app/bouffalolab/bl616/args.gni b/examples/lighting-app/bouffalolab/bl616/args.gni index d031a4b769ec88..aa60a4234e0c07 100644 --- a/examples/lighting-app/bouffalolab/bl616/args.gni +++ b/examples/lighting-app/bouffalolab/bl616/args.gni @@ -19,16 +19,7 @@ import("${chip_root}/src/platform/bouffalolab/BL616/args.gni") bouffalo_sdk_target = get_label_info(":sdk", "label_no_toolchain") -pw_log_BACKEND = "${chip_root}/src/pw_backends/log" -pw_assert_BACKEND = "${chip_root}/src/pw_backends/assert" -pw_rpc_CONFIG = "$dir_pw_rpc:disable_global_mutex" - -chip_detail_logging = true +chip_detail_logging = false # use -Os instead of -Og is_debug = false - -pw_build_LINK_DEPS = [ - "$dir_pw_assert:impl", - "$dir_pw_log:impl", -] diff --git a/examples/lighting-app/bouffalolab/bl702/BUILD.gn b/examples/lighting-app/bouffalolab/bl702/BUILD.gn index 9cec7d240e0ff7..35b7041d7d89f2 100644 --- a/examples/lighting-app/bouffalolab/bl702/BUILD.gn +++ b/examples/lighting-app/bouffalolab/bl702/BUILD.gn @@ -96,9 +96,6 @@ bl_iot_sdk("sdk") { } defines += [ "CHIP_DEVICE_CONFIG_ENABLE_ETHERNET=${chip_enable_ethernet}" ] - if (chip_enable_ethernet) { - defines += [ "CHIP_SYSTEM_CRYPTO_HEADER_RESERVE_SIZE=48" ] - } if (enable_psram) { defines += [ "CFG_USE_PSRAM=1" ] @@ -129,7 +126,7 @@ bouffalolab_executable("lighting_app") { bl_plat_name = "bl702" defines = [ - "APP_TASK_STACK_SIZE=2048", + "APP_TASK_STACK_SIZE=4096", "CHIP_UART_BAUDRATE=${baudrate}", "START_ENTRY=bl702_main", ] diff --git a/examples/lighting-app/bouffalolab/bl702l/BUILD.gn b/examples/lighting-app/bouffalolab/bl702l/BUILD.gn index c004af4134dfc2..de9210b4b1b714 100644 --- a/examples/lighting-app/bouffalolab/bl702l/BUILD.gn +++ b/examples/lighting-app/bouffalolab/bl702l/BUILD.gn @@ -106,7 +106,7 @@ bouffalolab_executable("lighting_app") { bl_plat_name = "bl702l" defines = [ - "APP_TASK_STACK_SIZE=2048", + "APP_TASK_STACK_SIZE=4096", "CHIP_UART_BAUDRATE=${baudrate}", "START_ENTRY=bl702_main", ] 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 9c06818348b10b..cd5c6fc7810640 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.matter @@ -2127,6 +2127,18 @@ endpoint 0 { binding cluster OtaSoftwareUpdateProvider; + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + server cluster AccessControl { emits event AccessControlEntryChanged; emits event AccessControlExtensionChanged; @@ -2209,7 +2221,7 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; - ram attribute featureMap default = 1; + ram attribute featureMap default = 4; ram attribute clusterRevision default = 1; handle command ScanNetworks; diff --git a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.zap b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.zap index 5e2fb2a77cde22..9c31d31bdc4f5a 100644 --- a/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.zap +++ b/examples/lighting-app/bouffalolab/data_model/lighting-app-ethernet.zap @@ -63,6 +63,176 @@ "deviceTypeCode": 22, "deviceTypeProfileId": 259, "clusters": [ + { + "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": "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": "Access Control", "code": 31, @@ -1199,7 +1369,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "4", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -4151,4 +4321,4 @@ "parentEndpointIdentifier": null } ] -} \ No newline at end of file +} diff --git a/examples/lighting-app/cc13x4_26x4/README.md b/examples/lighting-app/cc13x4_26x4/README.md index ea68690b0aefae..60cb44516739d5 100644 --- a/examples/lighting-app/cc13x4_26x4/README.md +++ b/examples/lighting-app/cc13x4_26x4/README.md @@ -264,7 +264,7 @@ On ``` ./chip-tool onoff on 1 -./chip-tool onoff toggee 1 (assuming the light is off) +./chip-tool onoff toggle 1 (assuming the light is off) ``` diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index f83ffd158bb875..3b2dde41a7e2e2 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -974,6 +974,23 @@ cluster OtaSoftwareUpdateRequestor = 42 { command AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; } +/** Nodes should be expected to be deployed to any and all regions of the world. These global regions + may have differing common languages, units of measurements, and numerical formatting + standards. As such, Nodes that visually or audibly convey information need a mechanism by which + they can be configured to use a user’s preferred language, units, etc */ +cluster LocalizationConfiguration = 43 { + revision 1; // NOTE: Default/not specifically set + + attribute access(write: manage) char_string<35> activeLocale = 0; + readonly attribute char_string supportedLocales[] = 1; + 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 @@ -1746,62 +1763,6 @@ cluster EthernetNetworkDiagnostics = 55 { command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; } -/** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. -Two types of switch devices are supported: latching switch (e.g. rocker switch) and momentary switch (e.g. push button), distinguished with their feature flags. -Interactions with the switch device are exposed as attributes (for the latching switch) and as events (for both types of switches). An interested party MAY subscribe to these attributes/events and thus be informed of the interactions, and can perform actions based on this, for example by sending commands to perform an action such as controlling a light or a window shade. */ -cluster Switch = 59 { - revision 2; - - bitmap Feature : bitmap32 { - kLatchingSwitch = 0x1; - kMomentarySwitch = 0x2; - kMomentarySwitchRelease = 0x4; - kMomentarySwitchLongPress = 0x8; - kMomentarySwitchMultiPress = 0x10; - kActionSwitch = 0x20; - } - - info event SwitchLatched = 0 { - int8u newPosition = 0; - } - - info event InitialPress = 1 { - int8u newPosition = 0; - } - - info event LongPress = 2 { - int8u newPosition = 0; - } - - info event ShortRelease = 3 { - int8u previousPosition = 0; - } - - info event LongRelease = 4 { - int8u previousPosition = 0; - } - - info event MultiPressOngoing = 5 { - int8u newPosition = 0; - int8u currentNumberOfPressesCounted = 1; - } - - info event MultiPressComplete = 6 { - int8u previousPosition = 0; - int8u totalNumberOfPressesCounted = 1; - } - - readonly attribute int8u numberOfPositions = 0; - readonly attribute int8u currentPosition = 1; - readonly attribute optional int8u multiPressMax = 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; -} - /** Commands to trigger a Node to allow a new Administrator to commission it. */ cluster AdministratorCommissioning = 60 { revision 1; // NOTE: Default/not specifically set @@ -2093,162 +2054,6 @@ cluster UserLabel = 65 { readonly attribute int16u clusterRevision = 65533; } -/** Attributes and commands for scene configuration and manipulation. */ -provisional cluster ScenesManagement = 98 { - revision 1; - - bitmap CopyModeBitmap : bitmap8 { - kCopyAllScenes = 0x1; - } - - bitmap Feature : bitmap32 { - kSceneNames = 0x1; - } - - struct AttributeValuePairStruct { - attrib_id attributeID = 0; - optional int8u valueUnsigned8 = 1; - optional int8s valueSigned8 = 2; - optional int16u valueUnsigned16 = 3; - optional int16s valueSigned16 = 4; - optional int32u valueUnsigned32 = 5; - optional int32s valueSigned32 = 6; - optional int64u valueUnsigned64 = 7; - optional int64s valueSigned64 = 8; - } - - struct ExtensionFieldSet { - cluster_id clusterID = 0; - AttributeValuePairStruct attributeValueList[] = 1; - } - - fabric_scoped struct SceneInfoStruct { - int8u sceneCount = 0; - fabric_sensitive int8u currentScene = 1; - fabric_sensitive group_id currentGroup = 2; - fabric_sensitive boolean sceneValid = 3; - int8u remainingCapacity = 4; - fabric_idx fabricIndex = 254; - } - - readonly attribute optional nullable node_id lastConfiguredBy = 0; - readonly attribute int16u sceneTableSize = 1; - readonly attribute SceneInfoStruct fabricSceneInfo[] = 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; - - request struct AddSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - int32u transitionTime = 2; - char_string sceneName = 3; - ExtensionFieldSet extensionFieldSets[] = 4; - } - - response struct AddSceneResponse = 0 { - status status = 0; - group_id groupID = 1; - int8u sceneID = 2; - } - - request struct ViewSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - } - - response struct ViewSceneResponse = 1 { - status status = 0; - group_id groupID = 1; - int8u sceneID = 2; - optional int32u transitionTime = 3; - optional char_string sceneName = 4; - optional ExtensionFieldSet extensionFieldSets[] = 5; - } - - request struct RemoveSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - } - - response struct RemoveSceneResponse = 2 { - status status = 0; - group_id groupID = 1; - int8u sceneID = 2; - } - - request struct RemoveAllScenesRequest { - group_id groupID = 0; - } - - response struct RemoveAllScenesResponse = 3 { - status status = 0; - group_id groupID = 1; - } - - request struct StoreSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - } - - response struct StoreSceneResponse = 4 { - status status = 0; - group_id groupID = 1; - int8u sceneID = 2; - } - - request struct RecallSceneRequest { - group_id groupID = 0; - int8u sceneID = 1; - optional nullable int32u transitionTime = 2; - } - - request struct GetSceneMembershipRequest { - group_id groupID = 0; - } - - response struct GetSceneMembershipResponse = 6 { - status status = 0; - nullable int8u capacity = 1; - group_id groupID = 2; - optional int8u sceneList[] = 3; - } - - request struct CopySceneRequest { - CopyModeBitmap mode = 0; - group_id groupIdentifierFrom = 1; - int8u sceneIdentifierFrom = 2; - group_id groupIdentifierTo = 3; - int8u sceneIdentifierTo = 4; - } - - response struct CopySceneResponse = 64 { - status status = 0; - group_id groupIdentifierFrom = 1; - int8u sceneIdentifierFrom = 2; - } - - /** Add a scene to the scene table. Extension field sets are supported, and are inputed as '{"ClusterID": VALUE, "AttributeValueList":[{"AttributeID": VALUE, "Value*": VALUE}]}' */ - fabric command access(invoke: manage) AddScene(AddSceneRequest): AddSceneResponse = 0; - /** Retrieves the requested scene entry from its Scene table. */ - fabric command ViewScene(ViewSceneRequest): ViewSceneResponse = 1; - /** Removes the requested scene entry, corresponding to the value of the GroupID field, from its Scene Table */ - fabric command access(invoke: manage) RemoveScene(RemoveSceneRequest): RemoveSceneResponse = 2; - /** Remove all scenes, corresponding to the value of the GroupID field, from its Scene Table */ - fabric command access(invoke: manage) RemoveAllScenes(RemoveAllScenesRequest): RemoveAllScenesResponse = 3; - /** Adds the scene entry into its Scene Table along with all extension field sets corresponding to the current state of other clusters on the same endpoint */ - fabric command access(invoke: manage) StoreScene(StoreSceneRequest): StoreSceneResponse = 4; - /** Set the attributes and corresponding state for each other cluster implemented on the endpoint accordingly to the resquested scene entry in the Scene Table */ - fabric command RecallScene(RecallSceneRequest): DefaultSuccess = 5; - /** Get an unused scene identifier when no commissioning tool is in the network, or for a commissioning tool to get the used scene identifiers within a certain group */ - fabric command GetSceneMembership(GetSceneMembershipRequest): GetSceneMembershipResponse = 6; - /** Allows a client to efficiently copy scenes from one group/scene identifier pair to another group/scene identifier pair. */ - fabric command access(invoke: manage) CopyScene(CopySceneRequest): CopySceneResponse = 64; -} - /** Attributes and commands for controlling the color properties of a color-capable light. */ cluster ColorControl = 768 { revision 7; @@ -2578,7 +2383,8 @@ cluster ColorControl = 768 { } endpoint 0 { - device type ma_rootdevice = 22, version 1; + device type ma_rootdevice = 22, version 3; + device type ma_otarequestor = 18, version 1; binding cluster OtaSoftwareUpdateProvider; @@ -2587,6 +2393,9 @@ endpoint 0 { callback attribute serverList; callback attribute clientList; callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; } @@ -2595,10 +2404,11 @@ endpoint 0 { emits event AccessControlEntryChanged; emits event AccessControlExtensionChanged; callback attribute acl; - callback attribute extension; callback attribute subjectsPerAccessControlEntry; callback attribute targetsPerAccessControlEntry; callback attribute accessControlEntriesPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -2629,8 +2439,11 @@ endpoint 0 { callback attribute capabilityMinima; callback attribute specificationVersion; callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 3; + ram attribute clusterRevision default = 4; } server cluster OtaSoftwareUpdateRequestor { @@ -2641,20 +2454,36 @@ endpoint 0 { ram attribute updatePossible default = 1; ram attribute updateState default = 0; ram attribute updateStateProgress default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; handle command AnnounceOTAProvider; } + server cluster LocalizationConfiguration { + ram attribute activeLocale; + callback attribute supportedLocales; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + server cluster GeneralCommissioning { ram attribute breadcrumb default = 0x0000000000000000; callback attribute basicCommissioningInfo; callback attribute regulatoryConfig; callback attribute locationCapability; callback attribute supportsConcurrentConnection; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 1; + ram attribute clusterRevision default = 2; handle command ArmFailSafe; handle command ArmFailSafeResponse; @@ -2673,6 +2502,9 @@ endpoint 0 { ram attribute lastNetworkingStatus; ram attribute lastNetworkID; ram attribute lastConnectErrorValue; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2708,6 +2540,9 @@ endpoint 0 { callback attribute activeRadioFaults; callback attribute activeNetworkFaults; callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2792,7 +2627,7 @@ endpoint 0 { callback attribute operationalDatasetComponents; callback attribute activeNetworkFaultsList; ram attribute featureMap default = 0x000F; - ram attribute clusterRevision default = 2; + ram attribute clusterRevision default = 3; handle command ResetCounts; } @@ -2836,23 +2671,17 @@ endpoint 0 { handle command ResetCounts; } - server cluster Switch { - emits event SwitchLatched; - ram attribute numberOfPositions default = 2; - ram attribute currentPosition; - ram attribute featureMap default = 0; - ram attribute clusterRevision default = 2; - } - server cluster AdministratorCommissioning { callback attribute windowStatus; callback attribute adminFabricIndex; callback attribute adminVendorId; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; handle command OpenCommissioningWindow; - handle command OpenBasicCommissioningWindow; handle command RevokeCommissioning; } @@ -2863,6 +2692,9 @@ endpoint 0 { callback attribute commissionedFabrics; callback attribute trustedRootCertificates; callback attribute currentFabricIndex; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2885,6 +2717,9 @@ endpoint 0 { callback attribute groupTable; callback attribute maxGroupsPerFabric; callback attribute maxGroupKeysPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2909,14 +2744,17 @@ endpoint 0 { } } endpoint 1 { - device type ma_dimmablelight = 257, version 1; + device type ma_colortemperaturelight = 268, version 4; server cluster Identify { ram attribute identifyTime default = 0x0000; ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 0; - ram attribute clusterRevision default = 4; + ram attribute clusterRevision default = 5; handle command Identify; handle command TriggerEffect; @@ -2924,6 +2762,9 @@ endpoint 1 { 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; @@ -2945,8 +2786,11 @@ endpoint 1 { ram attribute onTime default = 0x0000; ram attribute offWaitTime default = 0x0000; persist attribute startUpOnOff default = 0xFF; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 1; - ram attribute clusterRevision default = 5; + ram attribute clusterRevision default = 6; handle command Off; handle command On; @@ -2961,9 +2805,6 @@ endpoint 1 { ram attribute remainingTime default = 0x0000; ram attribute minLevel default = 0x01; ram attribute maxLevel default = 0xFE; - ram attribute currentFrequency default = 0x0000; - ram attribute minFrequency default = 0x0000; - ram attribute maxFrequency default = 0x0000; ram attribute options default = 0x00; ram attribute onOffTransitionTime default = 0x0000; ram attribute onLevel default = 0xFF; @@ -2971,6 +2812,9 @@ endpoint 1 { ram attribute offTransitionTime; ram attribute defaultMoveRate default = 50; persist attribute startUpCurrentLevel default = 255; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 6; @@ -2989,34 +2833,11 @@ endpoint 1 { callback attribute serverList; callback attribute clientList; callback attribute partsList; - callback attribute featureMap; - callback attribute clusterRevision; - } - - server cluster ScenesManagement { - ram attribute lastConfiguredBy; - ram attribute sceneTableSize default = 16; - callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; - ram attribute featureMap default = 1; - ram attribute clusterRevision default = 1; - - handle command AddScene; - handle command AddSceneResponse; - handle command ViewScene; - handle command ViewSceneResponse; - handle command RemoveScene; - handle command RemoveSceneResponse; - handle command RemoveAllScenes; - handle command RemoveAllScenesResponse; - handle command StoreScene; - handle command StoreSceneResponse; - handle command RecallScene; - handle command GetSceneMembership; - handle command GetSceneMembershipResponse; - handle command CopyScene; + callback attribute featureMap; + callback attribute clusterRevision; } server cluster ColorControl { @@ -3041,6 +2862,9 @@ endpoint 1 { ram attribute colorTempPhysicalMaxMireds default = 0x01C6; ram attribute coupleColorTempToLevelMinMireds; persist attribute startUpColorTemperatureMireds default = 0x00FA; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; ram attribute featureMap default = 0x1F; ram attribute clusterRevision default = 7; diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index 1195ca24f4963b..8264f7b2dad723 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -51,13 +51,22 @@ "label": "MA-rootdevice", "name": "MA-rootdevice", "deviceTypeOrder": 0 + }, + { + "code": 18, + "profileId": 259, + "label": "MA-otarequestor", + "name": "MA-otarequestor", + "deviceTypeOrder": 1 } ], "deviceVersions": [ + 3, 1 ], "deviceIdentifiers": [ - 22 + 22, + 18 ], "deviceTypeName": "MA-rootdevice", "deviceTypeCode": 22, @@ -135,6 +144,54 @@ "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, @@ -194,11 +251,11 @@ "reportableChange": 0 }, { - "name": "Extension", - "code": 1, + "name": "SubjectsPerAccessControlEntry", + "code": 2, "mfgCode": null, "side": "server", - "type": "array", + "type": "int16u", "included": 1, "storageOption": "External", "singleton": 0, @@ -210,8 +267,8 @@ "reportableChange": 0 }, { - "name": "SubjectsPerAccessControlEntry", - "code": 2, + "name": "TargetsPerAccessControlEntry", + "code": 3, "mfgCode": null, "side": "server", "type": "int16u", @@ -226,8 +283,8 @@ "reportableChange": 0 }, { - "name": "TargetsPerAccessControlEntry", - "code": 3, + "name": "AccessControlEntriesPerFabric", + "code": 4, "mfgCode": null, "side": "server", "type": "int16u", @@ -242,11 +299,27 @@ "reportableChange": 0 }, { - "name": "AccessControlEntriesPerFabric", - "code": 4, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "int16u", + "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, @@ -667,6 +740,54 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "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": 1, + "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": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -693,7 +814,7 @@ "storageOption": "RAM", "singleton": 1, "bounded": 0, - "defaultValue": "3", + "defaultValue": "4", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -856,6 +977,54 @@ "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, @@ -914,99 +1083,221 @@ ] }, { - "name": "General Commissioning", - "code": 48, + "name": "Localization Configuration", + "code": 43, "mfgCode": null, - "define": "GENERAL_COMMISSIONING_CLUSTER", + "define": "LOCALIZATION_CONFIGURATION_CLUSTER", "side": "server", "enabled": 1, - "commands": [ - { - "name": "ArmFailSafe", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "ArmFailSafeResponse", - "code": 1, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "SetRegulatoryConfig", - "code": 2, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "SetRegulatoryConfigResponse", - "code": 3, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "CommissioningComplete", - "code": 4, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "CommissioningCompleteResponse", - "code": 5, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - } - ], "attributes": [ { - "name": "Breadcrumb", + "name": "ActiveLocale", "code": 0, "mfgCode": null, "side": "server", - "type": "int64u", + "type": "char_string", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x0000000000000000", + "defaultValue": "", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "BasicCommissioningInfo", + "name": "SupportedLocales", "code": 1, "mfgCode": null, "side": "server", - "type": "BasicCommissioningInfo", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "RegulatoryConfig", - "code": 2, - "mfgCode": null, + "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": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, "side": "server", "type": "RegulatoryLocationTypeEnum", "included": 1, @@ -1051,6 +1342,54 @@ "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, @@ -1077,7 +1416,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": "2", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -1295,6 +1634,54 @@ "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, @@ -1468,7 +1855,55 @@ "code": 3, "mfgCode": null, "side": "server", - "type": "int32u", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveHardwareFaults", + "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": "ActiveRadioFaults", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -1480,11 +1915,11 @@ "reportableChange": 0 }, { - "name": "BootReason", - "code": 4, + "name": "ActiveNetworkFaults", + "code": 7, "mfgCode": null, "side": "server", - "type": "BootReasonEnum", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -1496,24 +1931,24 @@ "reportableChange": 0 }, { - "name": "ActiveHardwareFaults", - "code": 5, + "name": "TestEventTriggersEnabled", + "code": 8, "mfgCode": null, "side": "server", - "type": "array", + "type": "boolean", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "false", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ActiveRadioFaults", - "code": 6, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", "type": "array", @@ -1528,8 +1963,8 @@ "reportableChange": 0 }, { - "name": "ActiveNetworkFaults", - "code": 7, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -1544,16 +1979,16 @@ "reportableChange": 0 }, { - "name": "TestEventTriggersEnabled", - "code": 8, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "boolean", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "false", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -2791,7 +3226,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "3", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -3279,128 +3714,85 @@ ] }, { - "name": "Switch", - "code": 59, + "name": "Administrator Commissioning", + "code": 60, "mfgCode": null, - "define": "SWITCH_CLUSTER", + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", "side": "server", "enabled": 1, - "attributes": [ + "commands": [ { - "name": "NumberOfPositions", + "name": "OpenCommissioningWindow", "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 + "source": "client", + "isIncoming": 1, + "isEnabled": 1 }, { - "name": "CurrentPosition", - "code": 1, + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, "mfgCode": null, "side": "server", - "type": "int8u", + "type": "CommissioningWindowStatusEnum", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { - "name": "FeatureMap", - "code": 65532, + "name": "AdminFabricIndex", + "code": 1, "mfgCode": null, "side": "server", - "type": "bitmap32", + "type": "fabric_idx", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClusterRevision", - "code": 65533, + "name": "AdminVendorId", + "code": 2, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "vendor_id", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 - } - ], - "events": [ - { - "name": "SwitchLatched", - "code": 0, - "mfgCode": null, - "side": "server", - "included": 1 - } - ] - }, - { - "name": "Administrator Commissioning", - "code": 60, - "mfgCode": null, - "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", - "side": "server", - "enabled": 1, - "commands": [ - { - "name": "OpenCommissioningWindow", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "OpenBasicCommissioningWindow", - "code": 1, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 }, { - "name": "RevokeCommissioning", - "code": 2, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "WindowStatus", - "code": 0, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "CommissioningWindowStatusEnum", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -3412,11 +3804,11 @@ "reportableChange": 0 }, { - "name": "AdminFabricIndex", - "code": 1, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", - "type": "fabric_idx", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -3428,11 +3820,11 @@ "reportableChange": 0 }, { - "name": "AdminVendorId", - "code": 2, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "vendor_id", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -3679,6 +4071,54 @@ "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, @@ -3804,11 +4244,59 @@ "reportableChange": 0 }, { - "name": "MaxGroupsPerFabric", - "code": 2, + "name": "MaxGroupsPerFabric", + "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": "MaxGroupKeysPerFabric", + "code": 3, + "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": "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": "int16u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -3820,11 +4308,11 @@ "reportableChange": 0 }, { - "name": "MaxGroupKeysPerFabric", - "code": 3, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, "storageOption": "External", "singleton": 0, @@ -3991,29 +4479,29 @@ "id": 2, "name": "MA-dimmablelight", "deviceTypeRef": { - "code": 257, + "code": 268, "profileId": 259, - "label": "MA-dimmablelight", - "name": "MA-dimmablelight", + "label": "MA-colortemperaturelight", + "name": "MA-colortemperaturelight", "deviceTypeOrder": 0 }, "deviceTypes": [ { - "code": 257, + "code": 268, "profileId": 259, - "label": "MA-dimmablelight", - "name": "MA-dimmablelight", + "label": "MA-colortemperaturelight", + "name": "MA-colortemperaturelight", "deviceTypeOrder": 0 } ], "deviceVersions": [ - 1 + 4 ], "deviceIdentifiers": [ - 257 + 268 ], - "deviceTypeName": "MA-dimmablelight", - "deviceTypeCode": 257, + "deviceTypeName": "MA-colortemperaturelight", + "deviceTypeCode": 268, "deviceTypeProfileId": 259, "clusters": [ { @@ -4074,6 +4562,54 @@ "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, @@ -4100,7 +4636,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "4", + "defaultValue": "5", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -4214,6 +4750,54 @@ "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, @@ -4317,7 +4901,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x00", - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -4386,6 +4970,54 @@ "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, @@ -4412,7 +5044,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "5", + "defaultValue": "6", "reportable": 1, "minInterval": 0, "maxInterval": 65344, @@ -4558,54 +5190,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "CurrentFrequency", - "code": 4, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x0000", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "MinFrequency", - "code": 5, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x0000", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "MaxFrequency", - "code": 6, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "0x0000", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "Options", "code": 15, @@ -4675,110 +5259,52 @@ "code": 19, "mfgCode": null, "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "DefaultMoveRate", - "code": 20, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "50", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "StartUpCurrentLevel", - "code": 16384, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "NVM", - "singleton": 0, - "bounded": 0, - "defaultValue": "255", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "type": "bitmap32", + "type": "int16u", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "3", + "defaultValue": "", "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClusterRevision", - "code": 65533, + "name": "DefaultMoveRate", + "code": 20, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "int8u", "included": 1, "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "6", + "defaultValue": "50", "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 - } - ] - }, - { - "name": "Descriptor", - "code": 29, - "mfgCode": null, - "define": "DESCRIPTOR_CLUSTER", - "side": "server", - "enabled": 1, - "attributes": [ + }, { - "name": "DeviceTypeList", - "code": 0, + "name": "StartUpCurrentLevel", + "code": 16384, "mfgCode": null, "side": "server", - "type": "array", + "type": "int8u", "included": 1, - "storageOption": "External", + "storageOption": "NVM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "255", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 }, { - "name": "ServerList", - "code": 1, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", "type": "array", @@ -4793,8 +5319,8 @@ "reportableChange": 0 }, { - "name": "ClientList", - "code": 2, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -4809,8 +5335,8 @@ "reportableChange": 0 }, { - "name": "PartsList", - "code": 3, + "name": "AttributeList", + "code": 65531, "mfgCode": null, "side": "server", "type": "array", @@ -4831,10 +5357,10 @@ "side": "server", "type": "bitmap32", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -4847,175 +5373,76 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "External", + "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": null, + "defaultValue": "6", "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, + "minInterval": 0, + "maxInterval": 65344, "reportableChange": 0 } ] }, { - "name": "Scenes Management", - "code": 98, + "name": "Descriptor", + "code": 29, "mfgCode": null, - "define": "SCENES_CLUSTER", + "define": "DESCRIPTOR_CLUSTER", "side": "server", "enabled": 1, - "apiMaturity": "provisional", - "commands": [ - { - "name": "AddScene", - "code": 0, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, + "attributes": [ { - "name": "AddSceneResponse", + "name": "DeviceTypeList", "code": 0, "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "ViewScene", - "code": 1, - "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": "ViewSceneResponse", + "name": "ServerList", "code": 1, "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RemoveScene", - "code": 2, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "RemoveSceneResponse", - "code": 2, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RemoveAllScenes", - "code": 3, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "RemoveAllScenesResponse", - "code": 3, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "StoreScene", - "code": 4, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "StoreSceneResponse", - "code": 4, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "RecallScene", - "code": 5, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "GetSceneMembership", - "code": 6, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - }, - { - "name": "GetSceneMembershipResponse", - "code": 6, - "mfgCode": null, - "source": "server", - "isIncoming": 0, - "isEnabled": 1 - }, - { - "name": "CopyScene", - "code": 64, - "mfgCode": null, - "source": "client", - "isIncoming": 1, - "isEnabled": 1 - } - ], - "attributes": [ - { - "name": "LastConfiguredBy", - "code": 0, - "mfgCode": null, "side": "server", - "type": "node_id", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "SceneTableSize", - "code": 1, + "name": "ClientList", + "code": 2, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "16", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "FabricSceneInfo", - "code": 2, + "name": "PartsList", + "code": 3, "mfgCode": null, "side": "server", "type": "array", @@ -5084,10 +5511,10 @@ "side": "server", "type": "bitmap32", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -5100,13 +5527,13 @@ "side": "server", "type": "int16u", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 } ] @@ -5364,7 +5791,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "0x00FA", - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -5609,6 +6036,54 @@ "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, diff --git a/examples/lighting-app/linux/LightingAppCommandDelegate.cpp b/examples/lighting-app/linux/LightingAppCommandDelegate.cpp index cc5af976eb8b1a..d4fb35b423ec9e 100644 --- a/examples/lighting-app/linux/LightingAppCommandDelegate.cpp +++ b/examples/lighting-app/linux/LightingAppCommandDelegate.cpp @@ -84,43 +84,6 @@ void LightingAppCommandHandler::HandleCommand(intptr_t context) { self->OnGeneralFaultEventHandler(Clusters::GeneralDiagnostics::Events::NetworkFaultChange::Id); } - else if (name == "SwitchLatched") - { - uint8_t newPosition = static_cast(self->mJsonValue["NewPosition"].asUInt()); - self->OnSwitchLatchedHandler(newPosition); - } - else if (name == "InitialPress") - { - uint8_t newPosition = static_cast(self->mJsonValue["NewPosition"].asUInt()); - self->OnSwitchInitialPressedHandler(newPosition); - } - else if (name == "LongPress") - { - uint8_t newPosition = static_cast(self->mJsonValue["NewPosition"].asUInt()); - self->OnSwitchLongPressedHandler(newPosition); - } - else if (name == "ShortRelease") - { - uint8_t previousPosition = static_cast(self->mJsonValue["PreviousPosition"].asUInt()); - self->OnSwitchShortReleasedHandler(previousPosition); - } - else if (name == "LongRelease") - { - uint8_t previousPosition = static_cast(self->mJsonValue["PreviousPosition"].asUInt()); - self->OnSwitchLongReleasedHandler(previousPosition); - } - else if (name == "MultiPressOngoing") - { - uint8_t newPosition = static_cast(self->mJsonValue["NewPosition"].asUInt()); - uint8_t count = static_cast(self->mJsonValue["CurrentNumberOfPressesCounted"].asUInt()); - self->OnSwitchMultiPressOngoingHandler(newPosition, count); - } - else if (name == "MultiPressComplete") - { - uint8_t previousPosition = static_cast(self->mJsonValue["PreviousPosition"].asUInt()); - uint8_t count = static_cast(self->mJsonValue["TotalNumberOfPressesCounted"].asUInt()); - self->OnSwitchMultiPressCompleteHandler(previousPosition, count); - } else if (name == "PowerOnReboot") { self->OnRebootSignalHandler(BootReasonType::kPowerOnReboot); @@ -258,98 +221,6 @@ void LightingAppCommandHandler::OnSoftwareFaultEventHandler(uint32_t eventId) Clusters::SoftwareDiagnosticsServer::Instance().OnSoftwareFaultDetect(softwareFault); } -void LightingAppCommandHandler::OnSwitchLatchedHandler(uint8_t newPosition) -{ - EndpointId endpoint = 0; - - Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, newPosition); - VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, - ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute")); - ChipLogDetail(NotSpecified, "The latching switch is moved to a new position:%d", newPosition); - - Clusters::SwitchServer::Instance().OnSwitchLatch(endpoint, newPosition); -} - -void LightingAppCommandHandler::OnSwitchInitialPressedHandler(uint8_t newPosition) -{ - EndpointId endpoint = 0; - - Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, newPosition); - VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, - ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute")); - ChipLogDetail(NotSpecified, "The new position when the momentary switch starts to be pressed:%d", newPosition); - - Clusters::SwitchServer::Instance().OnInitialPress(endpoint, newPosition); -} - -void LightingAppCommandHandler::OnSwitchLongPressedHandler(uint8_t newPosition) -{ - EndpointId endpoint = 0; - - Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, newPosition); - VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, - ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute")); - ChipLogDetail(NotSpecified, "The new position when the momentary switch has been pressed for a long time:%d", newPosition); - - Clusters::SwitchServer::Instance().OnLongPress(endpoint, newPosition); -} - -void LightingAppCommandHandler::OnSwitchShortReleasedHandler(uint8_t previousPosition) -{ - EndpointId endpoint = 0; - - Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, 0); - VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, - ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute")); - ChipLogDetail(NotSpecified, "The the previous value of the CurrentPosition when the momentary switch has been released:%d", - previousPosition); - - Clusters::SwitchServer::Instance().OnShortRelease(endpoint, previousPosition); -} - -void LightingAppCommandHandler::OnSwitchLongReleasedHandler(uint8_t previousPosition) -{ - EndpointId endpoint = 0; - - Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, 0); - VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, - ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute")); - ChipLogDetail(NotSpecified, - "The the previous value of the CurrentPosition when the momentary switch has been released after having been " - "pressed for a long time:%d", - previousPosition); - - Clusters::SwitchServer::Instance().OnLongRelease(endpoint, previousPosition); -} - -void LightingAppCommandHandler::OnSwitchMultiPressOngoingHandler(uint8_t newPosition, uint8_t count) -{ - EndpointId endpoint = 0; - - Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, newPosition); - VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, - ChipLogError(NotSpecified, "Failed to set CurrentPosition attribute")); - ChipLogDetail(NotSpecified, "The new position when the momentary switch has been pressed in a multi-press sequence:%d", - newPosition); - ChipLogDetail(NotSpecified, "%d times the momentary switch has been pressed", count); - - Clusters::SwitchServer::Instance().OnMultiPressOngoing(endpoint, newPosition, count); -} - -void LightingAppCommandHandler::OnSwitchMultiPressCompleteHandler(uint8_t previousPosition, uint8_t count) -{ - EndpointId endpoint = 0; - - Protocols::InteractionModel::Status status = Switch::Attributes::CurrentPosition::Set(endpoint, 0); - VerifyOrReturn(Protocols::InteractionModel::Status::Success == status, - ChipLogError(NotSpecified, "Failed to reset CurrentPosition attribute")); - ChipLogDetail(NotSpecified, "The previous position when the momentary switch has been pressed in a multi-press sequence:%d", - previousPosition); - ChipLogDetail(NotSpecified, "%d times the momentary switch has been pressed", count); - - Clusters::SwitchServer::Instance().OnMultiPressComplete(endpoint, previousPosition, count); -} - void LightingAppCommandDelegate::OnEventCommandReceived(const char * json) { auto handler = LightingAppCommandHandler::FromJSON(json); diff --git a/examples/lighting-app/linux/LightingAppCommandDelegate.h b/examples/lighting-app/linux/LightingAppCommandDelegate.h index 6cbf83d7cdaa1f..91c7450c53bac7 100644 --- a/examples/lighting-app/linux/LightingAppCommandDelegate.h +++ b/examples/lighting-app/linux/LightingAppCommandDelegate.h @@ -51,43 +51,6 @@ class LightingAppCommandHandler * Should be called when a software fault takes place on the Node. */ void OnSoftwareFaultEventHandler(uint32_t eventId); - - /** - * Should be called when the latching switch is moved to a new position. - */ - void OnSwitchLatchedHandler(uint8_t newPosition); - - /** - * Should be called when the momentary switch starts to be pressed. - */ - void OnSwitchInitialPressedHandler(uint8_t newPosition); - - /** - * Should be called when the momentary switch has been pressed for a "long" time. - */ - void OnSwitchLongPressedHandler(uint8_t newPosition); - - /** - * Should be called when the momentary switch has been released. - */ - void OnSwitchShortReleasedHandler(uint8_t previousPosition); - - /** - * Should be called when the momentary switch has been released after having been pressed for a long time. - */ - void OnSwitchLongReleasedHandler(uint8_t previousPosition); - - /** - * Should be called to indicate how many times the momentary switch has been pressed in a multi-press - * sequence, during that sequence. - */ - void OnSwitchMultiPressOngoingHandler(uint8_t newPosition, uint8_t count); - - /** - * Should be called to indicate how many times the momentary switch has been pressed in a multi-press - * sequence, after it has been detected that the sequence has ended. - */ - void OnSwitchMultiPressCompleteHandler(uint8_t previousPosition, uint8_t count); }; class LightingAppCommandDelegate : public NamedPipeCommandDelegate diff --git a/examples/ota-requestor-app/ameba/README.md b/examples/ota-requestor-app/ameba/README.md index f7c2fef69b37e3..25adb797a37b67 100644 --- a/examples/ota-requestor-app/ameba/README.md +++ b/examples/ota-requestor-app/ameba/README.md @@ -6,11 +6,11 @@ A prototype application that demonstrates OTA Requestor capabilities. - Pull docker image: - $ docker pull ghcr.io/project-chip/chip-build-ameba:104 + $ docker pull ghcr.io/project-chip/chip-build-ameba:112 - Run docker container: - $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:104 + $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:112 - Setup build environment: diff --git a/examples/pigweed-app/ameba/README.md b/examples/pigweed-app/ameba/README.md index 286090e10dce01..b8895d747b52e0 100644 --- a/examples/pigweed-app/ameba/README.md +++ b/examples/pigweed-app/ameba/README.md @@ -31,11 +31,11 @@ following features are available: - Pull docker image: - $ docker pull ghcr.io/project-chip/chip-build-ameba:104 + $ docker pull ghcr.io/project-chip/chip-build-ameba:112 - Run docker container: - $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:104 + $ docker run -it -v ${CHIP_DIR}:/root/chip ghcr.io/project-chip/chip-build-ameba:112 - Setup build environment: diff --git a/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld b/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld index 206f89bd077fd3..6393c9d2d75663 100644 --- a/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld +++ b/examples/platform/bouffalolab/bl602/ldscripts/flash_rom.ld @@ -11,7 +11,9 @@ __RFTLV_HEAD1_L = (0x41524150); /* PAPA */ __RAM_START = 0x4200C000; __RAM_END = 0x4200C000 + 256K - __EM_SIZE; /* leave 8K left for BLE */ -__RAM_TCM_LEN = (16K + 16K + 48K + 64K + 64K - 16K - 16K); +__RAM_PBUF_POOL = DEFINED(__RAM_PBUF_POOL) ? __RAM_PBUF_POOL : 30K; + +__RAM_TCM_LEN = (16K + 16K + 48K + 64K + 64K - 16K - 16K + 30K - 12K - __RAM_PBUF_POOL); __RAM_WIFI_LEN = (__RAM_END - __RAM_START - __RAM_TCM_LEN); MEMORY @@ -173,6 +175,9 @@ SECTIONS *libwifi_drv.a:bl_utils.o(.bss*) *(.wifi_ram*) . = ALIGN(16); + + KEEP(*libCHIP.a:*(.bss.*PlatformManagerImp*)) + . = ALIGN(16); } > ram_wifi PROVIDE( _heap_wifi_start = . ); diff --git a/examples/platform/bouffalolab/bl602/lwipopts/lwipopts.h b/examples/platform/bouffalolab/bl602/lwipopts/lwipopts.h index 93c14da58cfbbb..ebcb05a4866f67 100644 --- a/examples/platform/bouffalolab/bl602/lwipopts/lwipopts.h +++ b/examples/platform/bouffalolab/bl602/lwipopts/lwipopts.h @@ -78,10 +78,6 @@ a lot of data that needs to be copied, this should be set high. */ #define MEMP_NUM_NETCONN (MEMP_NUM_TCP_PCB + MEMP_NUM_UDP_PCB + MEMP_NUM_TCP_PCB_LISTEN) -/* ---------- Pbuf options ---------- */ -/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */ -#define PBUF_POOL_SIZE 20 - /* ---------- TCP options ---------- */ #define LWIP_TCP 1 #define IP_DEFAULT_TTL 64 @@ -269,17 +265,37 @@ a lot of data that needs to be copied, this should be set high. */ #define LWIP_NETIF_EXT_STATUS_CALLBACK 1 -/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */ #define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS + 40 + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN) -#define LWIP_PBUF_FROM_CUSTOM_POOLS (0) - /* --------------------------------- ---------- MISC. options ---------- --------------------------------- */ +#if defined(CHIP_SYSTEM_CONFIG_PACKETBUFFER_LWIP_PBUF_RAM) && CHIP_SYSTEM_CONFIG_PACKETBUFFER_LWIP_PBUF_RAM +#define PBUF_POOL_SIZE 0 +#define MEM_LIBC_MALLOC 0 +#define MEM_USE_POOLS 0 +#define MEMP_USE_CUSTOM_POOLS 0 + +#include +#include +#define LWIP_PBUF_CUSTOM_DATA mem_size_t pool; + +#if defined(__cplusplus) +extern "C" const mem_size_t * memp_sizes; +extern "C" struct pbuf * pbuf_rightsize(struct pbuf * p, s16_t offset); +#else +extern const mem_size_t * memp_sizes; +extern struct pbuf * pbuf_rightsize(struct pbuf * p, s16_t offset); +#endif +#else + +#define PBUF_POOL_SIZE 20 +#define LWIP_PBUF_FROM_CUSTOM_POOLS (0) +#endif + #if defined(__cplusplus) extern "C" int bl_rand(void); extern "C" int * __errno(void); diff --git a/examples/platform/bouffalolab/bl616/lwipopts.h b/examples/platform/bouffalolab/bl616/lwipopts.h index 91d779fb9356e5..04671c945c227d 100644 --- a/examples/platform/bouffalolab/bl616/lwipopts.h +++ b/examples/platform/bouffalolab/bl616/lwipopts.h @@ -120,10 +120,9 @@ extern const int fhost_tcpip_priority; #define MEMP_NUM_UDP_PCB 16 #define MEMP_NUM_REASSDATA LWIP_MIN((IP_REASS_MAX_PBUFS), 5) -#define PBUF_POOL_SIZE 0 #define MEM_ALIGNMENT 4 #define MEM_SIZE 30720 -#define PBUF_POOL_BUFSIZE (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + 1280) +#define PBUF_POOL_BUFSIZE (1280 + 462 + 26) #define MEMP_MEM_MALLOC 1 // #define LWIP_HOOK_FILENAME "lwiphooks.h" @@ -177,4 +176,22 @@ extern const int fhost_tcpip_priority; #define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) \ u8_t variable_name[size] __attribute__((aligned(4))) __attribute__((section("SHAREDRAM"))) +#if defined(CHIP_SYSTEM_CONFIG_PACKETBUFFER_LWIP_PBUF_RAM) && CHIP_SYSTEM_CONFIG_PACKETBUFFER_LWIP_PBUF_RAM +#define PBUF_POOL_SIZE 0 + +#include +#include +#define LWIP_PBUF_CUSTOM_DATA mem_size_t pool; + +#if defined(__cplusplus) +extern "C" const mem_size_t * memp_sizes; +extern "C" struct pbuf * pbuf_rightsize(struct pbuf * p, s16_t offset); +#else +extern const mem_size_t * memp_sizes; +extern struct pbuf * pbuf_rightsize(struct pbuf * p, s16_t offset); +#endif +#else +#define PBUF_POOL_SIZE 20 +#endif + #endif /* LWIP_HDR_LWIPOPTS_H__ */ diff --git a/examples/platform/bouffalolab/bl702/ldscripts/psram_flash.ld b/examples/platform/bouffalolab/bl702/ldscripts/psram_flash.ld index a9ed71746418e8..593af0d2defb7d 100644 --- a/examples/platform/bouffalolab/bl702/ldscripts/psram_flash.ld +++ b/examples/platform/bouffalolab/bl702/ldscripts/psram_flash.ld @@ -208,6 +208,9 @@ SECTIONS _bt_l2cap_fixed_chan_list_start = .; KEEP(*(SORT_BY_NAME("._bt_l2cap_fixed_chan.static.*"))) _bt_l2cap_fixed_chan_list_end = .; + + . = ALIGN(8); + KEEP(*libCHIP.a:*(.bss.*PlatformManagerImp*)) } >tcm_ocram AT >flash .boot2 (NOLOAD) : diff --git a/examples/platform/bouffalolab/bl702l/ldscripts/psram_flash.ld b/examples/platform/bouffalolab/bl702l/ldscripts/psram_flash.ld index 597d98a4b11658..076f3d6659d084 100644 --- a/examples/platform/bouffalolab/bl702l/ldscripts/psram_flash.ld +++ b/examples/platform/bouffalolab/bl702l/ldscripts/psram_flash.ld @@ -170,6 +170,9 @@ SECTIONS _bt_l2cap_fixed_chan_list_start = .; KEEP(*(SORT_BY_NAME("._bt_l2cap_fixed_chan.static.*"))) _bt_l2cap_fixed_chan_list_end = .; + + . = ALIGN(8); + KEEP(*libCHIP.a:*(.bss.*PlatformManagerImp*)) } >tcm_ocram AT >flash .boot2 (NOLOAD) : diff --git a/examples/platform/bouffalolab/common/bouffalo_sdk/platform_port.cpp b/examples/platform/bouffalolab/common/bouffalo_sdk/platform_port.cpp index f92b527b410d3a..e1be14c2a2806f 100644 --- a/examples/platform/bouffalolab/common/bouffalo_sdk/platform_port.cpp +++ b/examples/platform/bouffalolab/common/bouffalo_sdk/platform_port.cpp @@ -56,6 +56,8 @@ extern "C" void vAssertCalled(void) printf("vAssertCalled, ra = %p in task %s\r\n", (void *) ra, pcTaskGetName(NULL)); } + abort(); + while (true) ; } diff --git a/examples/platform/bouffalolab/common/plat/plat.h b/examples/platform/bouffalolab/common/plat/plat.h index f0360ff19a70c5..6a9535a088cf3f 100644 --- a/examples/platform/bouffalolab/common/plat/plat.h +++ b/examples/platform/bouffalolab/common/plat/plat.h @@ -23,6 +23,10 @@ #define EXT_DISCOVERY_TIMEOUT_SECS 20 +#ifndef CONFIG_APP_ADVERTISE_COMMISSIONABLE_ON_LAST_FABRIC_REMOVAL +#define CONFIG_APP_ADVERTISE_COMMISSIONABLE_ON_LAST_FABRIC_REMOVAL 0 +#endif + typedef void (*app_pds_gpio_irq_handler_t)(void * arg); #ifdef __cplusplus diff --git a/examples/platform/bouffalolab/common/plat/platform.cpp b/examples/platform/bouffalolab/common/plat/platform.cpp index 13b07ec0a3e992..ef0424fdf650b4 100644 --- a/examples/platform/bouffalolab/common/plat/platform.cpp +++ b/examples/platform/bouffalolab/common/plat/platform.cpp @@ -178,6 +178,37 @@ void UnlockOpenThreadTask(void) } #endif +#if CONFIG_APP_ADVERTISE_COMMISSIONABLE_ON_LAST_FABRIC_REMOVAL +class AppFabricTableDelegate : public FabricTable::Delegate +{ + void OnFabricRemoved(const FabricTable & fabricTable, FabricIndex fabricIndex) + { + if (chip::Server::GetInstance().GetFabricTable().FabricCount() == 0) + { + ChipLogProgress(DeviceLayer, "Performing erasing of settings partition"); + PlatformMgr().ScheduleWork([](intptr_t) { +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + ConfigurationManagerImpl::GetDefaultInstance().ClearThreadStack(); + ThreadStackMgrImpl().FactoryResetThreadStack(); + ThreadStackMgr().InitThreadStack(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + ChipLogProgress(DeviceLayer, "Clearing WiFi provision"); + chip::DeviceLayer::ConnectivityMgr().ClearWiFiStationProvision(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + + CHIP_ERROR err = Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(AppServer, "Failed to open the Basic Commissioning Window"); + } + }); + } + } +}; +#endif + CHIP_ERROR PlatformManagerImpl::PlatformInit(void) { chip::RendezvousInformationFlags rendezvousMode(chip::RendezvousInformationFlag::kOnNetwork); @@ -235,7 +266,8 @@ CHIP_ERROR PlatformManagerImpl::PlatformInit(void) } else { - ChipLogError(NotSpecified, "sFactoryDataProvider.Init() failed"); + ChipLogError(NotSpecified, "factory data provider is failed to initialize, use example DAC provider."); + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); } #else SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); @@ -265,6 +297,11 @@ CHIP_ERROR PlatformManagerImpl::PlatformInit(void) gExampleDeviceInfoProvider.SetStorageDelegate(&chip::Server::GetInstance().GetPersistentStorage()); +#if CONFIG_APP_ADVERTISE_COMMISSIONABLE_ON_LAST_FABRIC_REMOVAL + static AppFabricTableDelegate sAppFabricDelegate; + chip::Server::GetInstance().GetFabricTable().AddFabricDelegate(&sAppFabricDelegate); +#endif + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); #if CHIP_DEVICE_CONFIG_ENABLE_THREAD diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index 600a6653c9275e..b6b21012b5263d 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -67,6 +67,10 @@ #include #include #include + +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#include +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER #endif // SL_WIFI #ifdef DIC_ENABLE @@ -175,25 +179,32 @@ BaseApplicationDelegate BaseApplication::sAppDelegate = BaseApplicationDelegate( void BaseApplicationDelegate::OnCommissioningSessionStarted() { isComissioningStarted = true; + +#if SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER + WifiSleepManager::GetInstance().HandleCommissioningSessionStarted(); +#endif // SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER } void BaseApplicationDelegate::OnCommissioningSessionStopped() { isComissioningStarted = false; + +#if SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER + WifiSleepManager::GetInstance().HandleCommissioningSessionStopped(); +#endif // SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER +} + +void BaseApplicationDelegate::OnCommissioningSessionEstablishmentError(CHIP_ERROR err) +{ + isComissioningStarted = false; + +#if SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER + WifiSleepManager::GetInstance().HandleCommissioningSessionStopped(); +#endif // SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER } void BaseApplicationDelegate::OnCommissioningWindowClosed() { -#if CHIP_CONFIG_ENABLE_ICD_SERVER && (defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1) - if (!BaseApplication::GetProvisionStatus() && !isComissioningStarted) - { - int32_t status = wfx_power_save(RSI_SLEEP_MODE_8, DEEP_SLEEP_WITH_RAM_RETENTION); - if (status != SL_STATUS_OK) - { - ChipLogError(AppServer, "Failed to enable the TA Deep Sleep"); - } - } -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917 if (BaseApplication::GetProvisionStatus()) { // After the device is provisioned and the commissioning passed @@ -888,6 +899,10 @@ void BaseApplication::OnPlatformEvent(const ChipDeviceEvent * event, intptr_t) { #if SL_WIFI chip::app::DnssdServer::Instance().StartServer(); + +#if CHIP_CONFIG_ENABLE_ICD_SERVER + WifiSleepManager::GetInstance().VerifyAndTransitionToLowPowerMode(WifiSleepManager::PowerEvent::kConnectivityChange); +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER #endif // SL_WIFI #if SILABS_OTA_ENABLED @@ -895,37 +910,14 @@ void BaseApplication::OnPlatformEvent(const ChipDeviceEvent * event, intptr_t) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(OTAConfig::kInitOTARequestorDelaySec), InitOTARequestorHandler, nullptr); #endif // SILABS_OTA_ENABLED -#if (CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI) - // on power cycle, let the device go to sleep after connection is established - if (BaseApplication::sAppDelegate.isCommissioningInProgress() == false) - { -#if SLI_SI917 - sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE); -#else - sl_status_t err = wfx_power_save(); -#endif /* SLI_SI917 */ - if (err != SL_STATUS_OK) - { - ChipLogError(AppServer, "wfx_power_save failed: 0x%lx", err); - } - } -#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI */ } } break; case DeviceEventType::kCommissioningComplete: { -#if (CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI) -#if SLI_SI917 - sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE); -#else - sl_status_t err = wfx_power_save(); -#endif /* SLI_SI917 */ - if (err != SL_STATUS_OK) - { - ChipLogError(AppServer, "wfx_power_save failed: 0x%lx", err); - } -#endif /* CHIP_CONFIG_ENABLE_ICD_SERVER && RS911X_WIFI */ +#if SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER + WifiSleepManager::GetInstance().VerifyAndTransitionToLowPowerMode(WifiSleepManager::PowerEvent::kCommissioningComplete); +#endif // SL_WIFI && CHIP_CONFIG_ENABLE_ICD_SERVER } break; default: diff --git a/examples/platform/silabs/BaseApplication.h b/examples/platform/silabs/BaseApplication.h index d355447d1b7981..93c6c7d95fa8c9 100644 --- a/examples/platform/silabs/BaseApplication.h +++ b/examples/platform/silabs/BaseApplication.h @@ -73,6 +73,7 @@ class BaseApplicationDelegate : public AppDelegate, public chip::FabricTable::De bool isComissioningStarted = false; void OnCommissioningSessionStarted() override; void OnCommissioningSessionStopped() override; + void OnCommissioningSessionEstablishmentError(CHIP_ERROR err) override; void OnCommissioningWindowClosed() override; // FabricTable::Delegate diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index bac4016e6c1094..87279c2c379b06 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -27,6 +27,10 @@ #ifdef SL_WIFI #include +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#include +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + // TODO: We shouldn't need any platform specific includes in this file #if (defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1) #include @@ -228,6 +232,10 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) // See comment above about OpenThread memory allocation as to why this is WIFI only here. ReturnErrorOnFailure(chip::Platform::MemoryInit()); ReturnErrorOnFailure(InitWiFi()); + +#if CHIP_CONFIG_ENABLE_ICD_SERVER + ReturnErrorOnFailure(DeviceLayer::Silabs::WifiSleepManager::GetInstance().Init()); +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER #endif ReturnErrorOnFailure(PlatformMgr().InitChipStack()); @@ -264,6 +272,8 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName) #ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED static SilabsTestEventTriggerDelegate sTestEventTriggerDelegate; + sTestEventTriggerDelegate.Init(&provision.GetStorage()); + initParams.testEventTriggerDelegate = &sTestEventTriggerDelegate; #endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 527f83b6a86b5b..41ab6b62573fd3 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -32,10 +32,6 @@ declare_args() { # OTA timeout in seconds ota_periodic_query_timeout_sec = 86400 - - # The EnableKey in hex string format used by TestEventTrigger command in - # GeneralDiagnostics cluster. The length of the string should be 16 bytes. - sl_test_event_trigger_enable_key = "00112233445566778899AABBCCDDEEFF" } # Sanity check @@ -58,29 +54,6 @@ config("chip_examples_project_config") { ] } -config("test-event-trigger-config") { - defines = [ "SL_MATTER_TEST_EVENT_TRIGGER_ENABLED" ] - - if (is_debug) { - defines += [ "SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY=\"${sl_test_event_trigger_enable_key}\"" ] - } -} - -source_set("test-event-trigger") { - sources = [ - "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.cpp", - "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.h", - ] - - deps = [ "${sl_provision_root}:headers" ] - public_configs = [ ":test-event-trigger-config" ] - public_deps = [ - "${chip_root}/src/app:test-event-trigger", - "${chip_root}/src/lib/core", - "${chip_root}/src/lib/support", - ] -} - source_set("matter-shell") { defines = [ "ENABLE_CHIP_SHELL" ] @@ -200,7 +173,7 @@ source_set("siwx917-common") { ] if (sl_enable_test_event_trigger) { - public_deps += [ ":test-event-trigger" ] + public_deps += [ "${silabs_common_plat_dir}/test-event-trigger:sources" ] } if (sl_enable_si70xx_sensor) { diff --git a/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp b/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp deleted file mode 100644 index 4d99346b4e5831..00000000000000 --- a/examples/platform/silabs/SilabsTestEventTriggerDelegate.cpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * - * 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 "SilabsTestEventTriggerDelegate.h" -#include - -using namespace ::chip::DeviceLayer; - -namespace chip { - -bool SilabsTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const -{ - uint8_t storedEnableKey[TestEventTriggerDelegate::kEnableKeyLength]; - MutableByteSpan enableKeySpan(storedEnableKey); - - // Return false if we were not able to get the enableKey - VerifyOrReturnValue( - Silabs::Provision::Manager::GetInstance().GetStorage().GetTestEventTriggerKey(enableKeySpan) == CHIP_NO_ERROR, false); - - return (!enableKeySpan.empty() && enableKeySpan.data_equal(enableKey)); -} - -} // namespace chip diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 25d0156d271a91..1f7c7288e849a4 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -30,10 +30,6 @@ declare_args() { # OTA timeout in seconds ota_periodic_query_timeout_sec = 86400 - - # The EnableKey in hex string format used by TestEventTrigger command in - # GeneralDiagnostics cluster. The length of the string should be 16 bytes. - sl_test_event_trigger_enable_key = "00112233445566778899AABBCCDDEEFF" } import("${silabs_common_plat_dir}/args.gni") @@ -61,29 +57,6 @@ config("chip_examples_project_config") { ] } -config("test-event-trigger-config") { - defines = [ "SL_MATTER_TEST_EVENT_TRIGGER_ENABLED" ] - - if (is_debug) { - defines += [ "SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY=\"${sl_test_event_trigger_enable_key}\"" ] - } -} - -source_set("test-event-trigger") { - sources = [ - "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.cpp", - "${silabs_common_plat_dir}/SilabsTestEventTriggerDelegate.h", - ] - - deps = [ "${sl_provision_root}:headers" ] - public_configs = [ ":test-event-trigger-config" ] - public_deps = [ - "${chip_root}/src/app:test-event-trigger", - "${chip_root}/src/lib/core", - "${chip_root}/src/lib/support", - ] -} - source_set("openthread_core_config_efr32_chip_examples") { if (chip_enable_openthread) { sources = [ "project_include/OpenThreadConfig.h" ] @@ -229,7 +202,7 @@ source_set("efr32-common") { ] if (sl_enable_test_event_trigger) { - public_deps += [ ":test-event-trigger" ] + public_deps += [ "${silabs_common_plat_dir}/test-event-trigger:sources" ] } if (sl_enable_si70xx_sensor) { diff --git a/examples/platform/silabs/provision/BUILD.gn b/examples/platform/silabs/provision/BUILD.gn index 79931e3c609568..bdfe33abaa6032 100644 --- a/examples/platform/silabs/provision/BUILD.gn +++ b/examples/platform/silabs/provision/BUILD.gn @@ -53,13 +53,6 @@ source_set("storage") { public_deps = [ "${sl_provision_root}:headers" ] if (sl_enable_test_event_trigger) { - # Temporary workaround since we have duplicated configurations - if (wifi_soc) { - public_configs = [ "${chip_root}/examples/platform/silabs/SiWx917:test-event-trigger-config" ] - } else { - public_configs = [ - "${chip_root}/examples/platform/silabs/efr32:test-event-trigger-config", - ] - } + public_configs = [ "${chip_root}/examples/platform/silabs/test-event-trigger:test-event-trigger-config" ] } } diff --git a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp index c395e2858effea..527ed130981a32 100644 --- a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -34,9 +33,9 @@ #include #endif // defined(SL_MATTER_TEST_EVENT_TRIGGER_ENABLED) && (SL_MATTER_GN_BUILD == 0) #endif // NDEBUG -#ifdef OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION #include -#endif // OTA_ENCRYPTION_ENABLE +#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION #ifndef SLI_SI91X_MCU_INTERFACE #include #endif @@ -474,7 +473,7 @@ CHIP_ERROR Storage::GetCertificationDeclaration(MutableByteSpan & value) err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_CD_OFFSET, SL_CREDENTIALS_CD_SIZE, value); } #endif -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS if (CHIP_ERROR_NOT_FOUND == err) { // Example CD @@ -502,7 +501,7 @@ CHIP_ERROR Storage::GetProductAttestationIntermediateCert(MutableByteSpan & valu err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_PAI_OFFSET, SL_CREDENTIALS_PAI_SIZE, value); } #endif -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS if (CHIP_ERROR_NOT_FOUND == err) { // Example PAI @@ -530,7 +529,7 @@ CHIP_ERROR Storage::GetDeviceAttestationCert(MutableByteSpan & value) err = ReadFileByOffset(*this, "GetDeviceAttestationCert", SL_CREDENTIALS_DAC_OFFSET, SL_CREDENTIALS_DAC_SIZE, value); } #endif -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS if (CHIP_ERROR_NOT_FOUND == err) { // Example DAC @@ -569,7 +568,7 @@ CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, Mutab } else { -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS // Example DAC key return Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message, signature); #else @@ -605,7 +604,7 @@ CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, Mutab AttestationKey key(kid); err = key.SignMessage(message, signature); } -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS else { // Example DAC key @@ -663,23 +662,18 @@ CHIP_ERROR Storage::GetProvisionRequest(bool & value) return SilabsConfig::ReadConfigValue(SilabsConfig::kConfigKey_Provision_Request, value); } -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) { chip::DeviceLayer::Silabs::OtaTlvEncryptionKey::OtaTlvEncryptionKey key; ReturnErrorOnFailure(key.Import(value.data(), value.size())); return SilabsConfig::WriteConfigValue(SilabsConfig::kOtaTlvEncryption_KeyId, key.GetId()); } -#endif // OTA_ENCRYPTION_ENABLE +#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION -/** - * @brief Reads the test event trigger key from NVM. If the key isn't present, returns default value if defined. - * - * @param[out] keySpan output buffer. Must be at least large enough for 16 bytes (ken length) - * @return CHIP_ERROR - */ CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) { +#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED constexpr size_t kEnableKeyLength = 16; // Expected byte size of the EnableKey CHIP_ERROR err = CHIP_NO_ERROR; size_t keyLength = 0; @@ -689,7 +683,7 @@ CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) err = SilabsConfig::ReadConfigValueBin(SilabsConfig::kConfigKey_Test_Event_Trigger_Key, keySpan.data(), kEnableKeyLength, keyLength); #ifndef NDEBUG -#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED +#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { @@ -702,36 +696,17 @@ CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) } err = CHIP_NO_ERROR; } -#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED +#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY #endif // NDEBUG keySpan.reduce_size(kEnableKeyLength); return err; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; +#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED } } // namespace Provision - -void MigrateDacProvider(void) -{ - constexpr uint32_t kOldKey_Creds_KeyId = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x21); - constexpr uint32_t kOldKey_Creds_Base_Addr = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x22); - constexpr uint32_t kOldKey_Creds_DAC_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x23); - constexpr uint32_t kOldKey_Creds_DAC_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x24); - constexpr uint32_t kOldKey_Creds_PAI_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x26); - constexpr uint32_t kOldKey_Creds_PAI_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x25); - constexpr uint32_t kOldKey_Creds_CD_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x27); - constexpr uint32_t kOldKey_Creds_CD_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x28); - - MigrationManager::MigrateUint32(kOldKey_Creds_KeyId, SilabsConfig::kConfigKey_Creds_KeyId); - MigrationManager::MigrateUint32(kOldKey_Creds_Base_Addr, SilabsConfig::kConfigKey_Creds_Base_Addr); - MigrationManager::MigrateUint32(kOldKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_DAC_Size, SilabsConfig::kConfigKey_Creds_DAC_Size); - MigrationManager::MigrateUint32(kOldKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_PAI_Size, SilabsConfig::kConfigKey_Creds_PAI_Size); - MigrationManager::MigrateUint32(kOldKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Offset); - MigrationManager::MigrateUint32(kOldKey_Creds_CD_Size, SilabsConfig::kConfigKey_Creds_CD_Size); -} - } // namespace Silabs } // namespace DeviceLayer } // namespace chip diff --git a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp index ebfd3ec53124cf..d5d53eb183c98c 100644 --- a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp @@ -25,9 +25,9 @@ #include #include #include -#ifdef OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION #include -#endif // OTA_ENCRYPTION_ENABLE +#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION using namespace chip::Credentials; @@ -578,13 +578,13 @@ CHIP_ERROR Storage::GetCertificationDeclaration(MutableByteSpan & value) { size_t size = 0; CHIP_ERROR err = (Flash::Get(Parameters::ID::kCertification, value.data(), value.size(), size)); -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) { // Example CD return Examples::GetExampleDACProvider()->GetCertificationDeclaration(value); } -#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#endif // SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS ReturnErrorOnFailure(err); value.reduce_size(size); return CHIP_NO_ERROR; @@ -599,13 +599,13 @@ CHIP_ERROR Storage::GetProductAttestationIntermediateCert(MutableByteSpan & valu { size_t size = 0; CHIP_ERROR err = (Flash::Get(Parameters::ID::kPaiCert, value.data(), value.size(), size)); -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) { // Example PAI return Examples::GetExampleDACProvider()->GetProductAttestationIntermediateCert(value); } -#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#endif // SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS ReturnErrorOnFailure(err); value.reduce_size(size); return CHIP_NO_ERROR; @@ -620,13 +620,13 @@ CHIP_ERROR Storage::GetDeviceAttestationCert(MutableByteSpan & value) { size_t size = 0; CHIP_ERROR err = (Flash::Get(Parameters::ID::kDacCert, value.data(), value.size(), size)); -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) { // Example DAC return Examples::GetExampleDACProvider()->GetDeviceAttestationCert(value); } -#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#endif // SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS ReturnErrorOnFailure(err); value.reduce_size(size); return CHIP_NO_ERROR; @@ -652,13 +652,13 @@ CHIP_ERROR Storage::SignWithDeviceAttestationKey(const ByteSpan & message, Mutab uint8_t temp[kDeviceAttestationKeySizeMax] = { 0 }; size_t size = 0; CHIP_ERROR err = Flash::Get(Parameters::ID::kDacKey, temp, sizeof(temp), size); -#ifdef CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#ifdef SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS if (CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND == err) { // Example DAC key return Examples::GetExampleDACProvider()->SignWithDeviceAttestationKey(message, signature); } -#endif // CHIP_DEVICE_CONFIG_ENABLE_EXAMPLE_CREDENTIALS +#endif // SL_MATTER_ENABLE_EXAMPLE_CREDENTIALS ReturnErrorOnFailure(err); #if (defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE) uint8_t key_buffer[kDeviceAttestationKeySizeMax] = { 0 }; @@ -719,22 +719,25 @@ CHIP_ERROR Storage::GetProvisionRequest(bool & value) // return Flash::Set(Parameters::ID::kProvisionRequest, value); return CHIP_ERROR_NOT_IMPLEMENTED; } -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION CHIP_ERROR Storage::SetOtaTlvEncryptionKey(const ByteSpan & value) { return CHIP_ERROR_NOT_IMPLEMENTED; } -#endif // OTA_ENCRYPTION_ENABLE +#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION CHIP_ERROR Storage::GetTestEventTriggerKey(MutableByteSpan & keySpan) { +#ifdef SL_MATTER_TEST_EVENT_TRIGGER_ENABLED + // TODO: Implement Getter + // Adding the same return twice to have the function structure return CHIP_ERROR_NOT_IMPLEMENTED; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; +#endif // SL_MATTER_TEST_EVENT_TRIGGER_ENABLED } } // namespace Provision - -void MigrateDacProvider(void) {} - } // namespace Silabs } // namespace DeviceLayer } // namespace chip diff --git a/examples/platform/silabs/shell/BUILD.gn b/examples/platform/silabs/shell/BUILD.gn index 8d4cab328e71dc..2d4cb29326ea45 100644 --- a/examples/platform/silabs/shell/BUILD.gn +++ b/examples/platform/silabs/shell/BUILD.gn @@ -35,5 +35,8 @@ source_set("icd") { public_configs = [ ":icd-shell-config" ] - deps = [ "${shell_dependency_path}:matter-shell" ] + deps = [ + "${chip_root}/src/app/icd/server:notifier", + "${shell_dependency_path}:matter-shell", + ] } diff --git a/examples/platform/silabs/test-event-trigger/BUILD.gn b/examples/platform/silabs/test-event-trigger/BUILD.gn new file mode 100644 index 00000000000000..73b2be753377ea --- /dev/null +++ b/examples/platform/silabs/test-event-trigger/BUILD.gn @@ -0,0 +1,48 @@ +# Copyright (c) 2025 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("${chip_root}/third_party/silabs/matter_support/provision/args.gni") + +declare_args() { + # The EnableKey in hex string format used by TestEventTrigger command in + # GeneralDiagnostics cluster. The length of the string should be 16 bytes. + sl_test_event_trigger_enable_key = "00112233445566778899AABBCCDDEEFF" +} + +config("test-event-trigger-config") { + defines = [ "SL_MATTER_TEST_EVENT_TRIGGER_ENABLED" ] + + if (is_debug) { + defines += [ "SL_MATTER_TEST_EVENT_TRIGGER_ENABLE_KEY=\"${sl_test_event_trigger_enable_key}\"" ] + } + + include_dirs = [ "." ] +} + +source_set("sources") { + sources = [ + "SilabsTestEventTriggerDelegate.cpp", + "SilabsTestEventTriggerDelegate.h", + ] + + public_configs = [ ":test-event-trigger-config" ] + + public_deps = [ + "${chip_root}/src/app:test-event-trigger", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/support", + "${sl_provision_root}:headers", + ] +} diff --git a/examples/platform/silabs/test-event-trigger/SilabsTestEventTriggerDelegate.cpp b/examples/platform/silabs/test-event-trigger/SilabsTestEventTriggerDelegate.cpp new file mode 100644 index 00000000000000..b86bf0f193fdd4 --- /dev/null +++ b/examples/platform/silabs/test-event-trigger/SilabsTestEventTriggerDelegate.cpp @@ -0,0 +1,59 @@ +/* + * + * 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::DeviceLayer; + +namespace chip { + +CHIP_ERROR SilabsTestEventTriggerDelegate::Init(DeviceLayer::Silabs::Provision::ProvisionedDataProvider * provider) +{ + VerifyOrReturnError(provider != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + mProvider = provider; + + return CHIP_NO_ERROR; +} + +bool SilabsTestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + uint8_t storedEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0 }; + MutableByteSpan storedEnableKeySpan(storedEnableKey); + + // If mProvider is equal to nullptr, we still continue in the function to check if the requested enableKey matches the zero + // key. + if (mProvider != nullptr) + { + error = mProvider->GetTestEventTriggerKey(storedEnableKeySpan); + } + + if (error != CHIP_NO_ERROR) + { + // If we fail to read the enableKey from storage, the MutableByteSpan is not modified by the getter which leaves the span + // equal to a zero bytepsan (size = 0). This guarantees that we will be able to inform the stack that the test event trigger + // is not enabled when the stack tries to match the zero bytespan to our enableKey. + ChipLogError(DeviceLayer, "Failed to get test event trigger key: %s", ErrorStr(error)); + } + + return storedEnableKeySpan.data_equal(enableKey); +} + +} // namespace chip diff --git a/examples/platform/silabs/SilabsTestEventTriggerDelegate.h b/examples/platform/silabs/test-event-trigger/SilabsTestEventTriggerDelegate.h similarity index 69% rename from examples/platform/silabs/SilabsTestEventTriggerDelegate.h rename to examples/platform/silabs/test-event-trigger/SilabsTestEventTriggerDelegate.h index c691c0eff9759b..9b4a7ebd414e13 100644 --- a/examples/platform/silabs/SilabsTestEventTriggerDelegate.h +++ b/examples/platform/silabs/test-event-trigger/SilabsTestEventTriggerDelegate.h @@ -18,9 +18,8 @@ #pragma once -#include - #include +#include #include #include #include @@ -32,12 +31,25 @@ class SilabsTestEventTriggerDelegate : public TestEventTriggerDelegate public: explicit SilabsTestEventTriggerDelegate() = default; + /** + * @brief Configures the Silabs Test Event trigger + * + * @param provider pointer to the silabs provisionned data provider + * + * @return CHIP_ERROR CHIP_NO_ERROR, if the init was succesful + * CHIP_ERROR_INVALID_ARGUMENT, if the manager input is equal to nullptr + */ + CHIP_ERROR Init(DeviceLayer::Silabs::Provision::ProvisionedDataProvider * provider); + /** * @brief Checks to see if `enableKey` provided matches value chosen by the manufacturer. * @param enableKey Buffer of the key to verify. * @return True or False. */ bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override; + +private: + DeviceLayer::Silabs::Provision::ProvisionedDataProvider * mProvider = nullptr; }; } // namespace chip diff --git a/examples/platform/silabs/tests/BUILD.gn b/examples/platform/silabs/tests/BUILD.gn new file mode 100644 index 00000000000000..2b6e19b99f461d --- /dev/null +++ b/examples/platform/silabs/tests/BUILD.gn @@ -0,0 +1,36 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") +import("${chip_root}/build/chip/chip_test_group.gni") +import("${chip_root}/build/chip/chip_test_suite.gni") +import("${chip_root}/src/platform/silabs/tests/args.gni") + +chip_test_suite("examples_tests") { + output_name = "libSilabsExamplesPlatformTests" + + test_sources = [ "TestSilabsTestEventTrigger.cpp" ] + + public_deps = [ + "${chip_root}/examples/platform/silabs/test-event-trigger:sources", + "${chip_root}/src/lib/core", + "${chip_root}/src/lib/core:string-builder-adapters", + "${chip_root}/src/lib/support", + "${chip_root}/src/lib/support:testing", + ] + + cflags = [ "-Wconversion" ] +} diff --git a/examples/platform/silabs/tests/TestSilabsTestEventTrigger.cpp b/examples/platform/silabs/tests/TestSilabsTestEventTrigger.cpp new file mode 100644 index 00000000000000..45248220219938 --- /dev/null +++ b/examples/platform/silabs/tests/TestSilabsTestEventTrigger.cpp @@ -0,0 +1,217 @@ +/* + * + * 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 + +using namespace chip; +using namespace chip::DeviceLayer::Silabs::Provision; + +namespace { +const uint8_t kTestEnableKey1[TestEventTriggerDelegate::kEnableKeyLength] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF }; +const uint8_t kTestEnableKey2[TestEventTriggerDelegate::kEnableKeyLength] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }; +const uint8_t kInvalidEnableKey[TestEventTriggerDelegate::kEnableKeyLength - 1] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F }; +const uint8_t kZeroEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0 }; + +class ProviderStub : public ProvisionedDataProvider +{ +public: + CHIP_ERROR GetTestEventTriggerKey(MutableByteSpan & keySpan) override + { + VerifyOrReturnError(!forceError, CHIP_ERROR_INTERNAL); + + ByteSpan enableKeySpan = ByteSpan(mEnableKey, TestEventTriggerDelegate::kEnableKeyLength); + CopySpanToMutableSpan(enableKeySpan, keySpan); + return CHIP_NO_ERROR; + } + + void SetEnableKey(const uint8_t * key, size_t length) + { + if (length == sizeof(mEnableKey)) + { + memcpy(mEnableKey, key, length); + } + } + + void SetForceError(bool value) { forceError = value; } + +private: + uint8_t mEnableKey[TestEventTriggerDelegate::kEnableKeyLength] = { 0 }; + bool forceError = false; +}; + +} // namespace + +// Test that a valid key matches +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_ValidKey) +{ + ProviderStub provider; + provider.SetEnableKey(kTestEnableKey1, TestEventTriggerDelegate::kEnableKeyLength); + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + ByteSpan validKeySpan(kTestEnableKey1); + EXPECT_TRUE(delegate.DoesEnableKeyMatch(validKeySpan)); +} + +// Test that an invalid key does not match +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_InvalidKey) +{ + ProviderStub provider; + provider.SetEnableKey(kTestEnableKey1, TestEventTriggerDelegate::kEnableKeyLength); + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + ByteSpan invalidKeySpan(kInvalidEnableKey, TestEventTriggerDelegate::kEnableKeyLength - 1); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(invalidKeySpan)); +} + +// Test that an empty key does not match +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_EmptyKey) +{ + ProviderStub provider; + provider.SetEnableKey(kTestEnableKey1, TestEventTriggerDelegate::kEnableKeyLength); + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + EXPECT_FALSE(delegate.DoesEnableKeyMatch(ByteSpan(kZeroEnableKey))); +} + +// Test that a different valid key does not match +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_DifferentValidKey) +{ + ProviderStub provider; + provider.SetEnableKey(kTestEnableKey1, TestEventTriggerDelegate::kEnableKeyLength); + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + ByteSpan differentValidKeySpan(kTestEnableKey2); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(differentValidKeySpan)); +} + +// Test that an empty key matchs when no enable key is set +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_NoKeySet_EmptyKey) +{ + ProviderStub provider; + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + EXPECT_TRUE(delegate.DoesEnableKeyMatch(ByteSpan(kZeroEnableKey))); +} + +// Test that a valid key does not match when no enable key is set +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_NoKeySet_ValidKey) +{ + ProviderStub provider; + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + ByteSpan validKeySpan(kTestEnableKey1); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(validKeySpan)); +} + +// Test that a valid key does not match when provider is not set +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_NoStorage_ValidKey) +{ + SilabsTestEventTriggerDelegate delegate; + + ByteSpan validKeySpan(kTestEnableKey1); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(validKeySpan)); +} + +// Test that an invalid key does not match when provider is not set +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_NoStorage_InvalidKey) +{ + SilabsTestEventTriggerDelegate delegate; + + ByteSpan invalidKeySpan(kInvalidEnableKey); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(invalidKeySpan)); +} + +// Test that an empty key matchs when provider is not set +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_NoStorage_EmptyKey) +{ + SilabsTestEventTriggerDelegate delegate; + + EXPECT_TRUE(delegate.DoesEnableKeyMatch(ByteSpan(kZeroEnableKey))); +} + +// Test that a valid key does not match when GetTestEventTriggerKey returns an error +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_GetKeyError_ValidKey) +{ + ProviderStub provider; + provider.SetForceError(true); + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + ByteSpan validKeySpan(kTestEnableKey1); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(validKeySpan)); +} + +// Test that an invalid key does not match when GetTestEventTriggerKey returns an error +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_GetKeyError_InvalidKey) +{ + ProviderStub provider; + provider.SetForceError(true); + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + ByteSpan invalidKeySpan(kInvalidEnableKey); + EXPECT_FALSE(delegate.DoesEnableKeyMatch(invalidKeySpan)); +} + +// Test that an empty key matchs when GetTestEventTriggerKey returns an error +TEST(TestSilabsTestEventTriggerDelegate, TestDoesEnableKeyMatch_GetKeyError_EmptyKey) +{ + ProviderStub provider; + provider.SetForceError(true); + + SilabsTestEventTriggerDelegate delegate; + delegate.Init(&provider); + + EXPECT_TRUE(delegate.DoesEnableKeyMatch(ByteSpan(kZeroEnableKey))); +} + +// Test that Init function initializes the delegate with a valid provider +TEST(TestSilabsTestEventTriggerDelegate, TestInit_ValidProvider) +{ + ProviderStub provider; + SilabsTestEventTriggerDelegate delegate; + EXPECT_EQ(delegate.Init(&provider), CHIP_NO_ERROR); +} + +// Test that Init function returns an error when initialized with a null provider +TEST(TestSilabsTestEventTriggerDelegate, TestInit_NullProvider) +{ + SilabsTestEventTriggerDelegate delegate; + EXPECT_EQ(delegate.Init(nullptr), CHIP_ERROR_INVALID_ARGUMENT); +} diff --git a/examples/platform/telink/common/include/AppTaskCommon.h b/examples/platform/telink/common/include/AppTaskCommon.h index ac10ef587d2be9..25e0e4c8da481c 100644 --- a/examples/platform/telink/common/include/AppTaskCommon.h +++ b/examples/platform/telink/common/include/AppTaskCommon.h @@ -76,8 +76,11 @@ class AppTaskCommon { kButtonId_ExampleAction = 1, kButtonId_FactoryReset, - kButtonId_StartWiFi, +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD kButtonId_StartThread, +#elif CHIP_DEVICE_CONFIG_ENABLE_WIFI + kButtonId_StartWiFi, +#endif kButtonId_StartBleAdv } ButtonId; #endif diff --git a/examples/platform/telink/common/include/SensorManagerCommon.h b/examples/platform/telink/common/include/SensorManagerCommon.h index 25e800b078e021..6cce353f25439d 100644 --- a/examples/platform/telink/common/include/SensorManagerCommon.h +++ b/examples/platform/telink/common/include/SensorManagerCommon.h @@ -26,7 +26,7 @@ #include #include -#if defined(CONFIG_CHIP_USE_MARS_SENSOR) && defined(CONFIG_WS2812_STRIP) && !defined(CONFIG_PM) +#if defined(CONFIG_CHIP_USE_MARS_SENSOR) && defined(CONFIG_WS2812_STRIP_GPIO_TELINK) && !defined(CONFIG_PM) #define USE_COLOR_TEMPERATURE_LIGHT #endif diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index c5807b035b191a..d898297670967c 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -424,7 +424,7 @@ void AppTaskCommon::InitPwms() LinkPwms(pwmManager); -#if CONFIG_WS2812_STRIP +#if CONFIG_WS2812_STRIP_GPIO_TELINK pwmManager.linkBackend(Ws2812Strip::getInstance()); #elif CONFIG_PWM pwmManager.linkBackend(PwmPool::getInstance()); @@ -437,7 +437,7 @@ void AppTaskCommon::LinkPwms(PwmManager & pwmManager) { #if CONFIG_BOARD_TLSR9118BDK40D_V1 && CONFIG_PWM // TLSR9118BDK40D_V1 EVK supports single LED PWM channel pwmManager.linkPwm(PwmManager::EAppPwm_Red, 0); -#elif CONFIG_WS2812_STRIP +#elif CONFIG_WS2812_STRIP_GPIO_TELINK pwmManager.linkPwm(PwmManager::EAppPwm_Red, 0); pwmManager.linkPwm(PwmManager::EAppPwm_Green, 1); pwmManager.linkPwm(PwmManager::EAppPwm_Blue, 2); @@ -446,7 +446,7 @@ void AppTaskCommon::LinkPwms(PwmManager & pwmManager) pwmManager.linkPwm(PwmManager::EAppPwm_Red, 1); pwmManager.linkPwm(PwmManager::EAppPwm_Green, 2); pwmManager.linkPwm(PwmManager::EAppPwm_Blue, 3); -#endif // CONFIG_WS2812_STRIP +#endif } void AppTaskCommon::InitButtons(void) diff --git a/examples/platform/telink/common/src/mainCommon.cpp b/examples/platform/telink/common/src/mainCommon.cpp index 583d61c0082c57..099ffec0debc41 100644 --- a/examples/platform/telink/common/src/mainCommon.cpp +++ b/examples/platform/telink/common/src/mainCommon.cpp @@ -174,6 +174,6 @@ int main(void) err = GetAppTask().StartApp(); exit: - LOG_ERR("Exit err %" CHIP_ERROR_FORMAT, err.Format()); + LOG_ERR("Exit err %d", err.Format()); return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/examples/platform/telink/util/include/PWMManager.h b/examples/platform/telink/util/include/PWMManager.h index 717180a9fa4f01..eced61e7614286 100644 --- a/examples/platform/telink/util/include/PWMManager.h +++ b/examples/platform/telink/util/include/PWMManager.h @@ -110,7 +110,7 @@ class PwmManager PwmBackend * m_backend; }; -#if CONFIG_WS2812_STRIP +#if CONFIG_WS2812_STRIP_GPIO_TELINK class Ws2812Strip : public PwmBackend { @@ -170,4 +170,4 @@ class PwmDummy : public PwmBackend PwmDummy(){}; }; -#endif // CONFIG_WS2812_STRIP +#endif // CONFIG_WS2812_STRIP_GPIO_TELINK diff --git a/examples/platform/telink/util/src/ColorFormat.cpp b/examples/platform/telink/util/src/ColorFormat.cpp index 0c92c9bc0a02e6..ac648e0ddc1d9b 100644 --- a/examples/platform/telink/util/src/ColorFormat.cpp +++ b/examples/platform/telink/util/src/ColorFormat.cpp @@ -116,9 +116,9 @@ RgbColor_t XYToRgb(uint8_t Level, uint16_t currentX, uint16_t currentY) b = (X * 0.0557f) - (Y * 0.2040f) + (Z * 1.0570f); // apply gamma 2.2 correction - r = (r <= 0.0031308f ? 12.92f * r : (1.055f) * pow(r, (1.0f / 2.4f)) - 0.055f); - g = (g <= 0.0031308f ? 12.92f * g : (1.055f) * pow(g, (1.0f / 2.4f)) - 0.055f); - b = (b <= 0.0031308f ? 12.92f * b : (1.055f) * pow(b, (1.0f / 2.4f)) - 0.055f); + r = (r <= 0.0031308f ? 12.92f * r : (1.055f) * powf(r, (1.0f / 2.4f)) - 0.055f); + g = (g <= 0.0031308f ? 12.92f * g : (1.055f) * powf(g, (1.0f / 2.4f)) - 0.055f); + b = (b <= 0.0031308f ? 12.92f * b : (1.055f) * powf(b, (1.0f / 2.4f)) - 0.055f); // Round off r = clamp(r, 0, 1); @@ -150,17 +150,17 @@ RgbColor_t CTToRgb(CtColor_t ct) } else { - r = 329.698727446f * pow(ctCentiKelvin - 60, -0.1332047592f); + r = 329.698727446f * powf(ctCentiKelvin - 60, -0.1332047592f); } // Green if (ctCentiKelvin <= 66) { - g = 99.4708025861f * log(ctCentiKelvin) - 161.1195681661f; + g = 99.4708025861f * logf(ctCentiKelvin) - 161.1195681661f; } else { - g = 288.1221695283f * pow(ctCentiKelvin - 60, -0.0755148492f); + g = 288.1221695283f * powf(ctCentiKelvin - 60, -0.0755148492f); } // Blue diff --git a/examples/platform/telink/util/src/PWMManager.cpp b/examples/platform/telink/util/src/PWMManager.cpp index aa747974c93b31..b3502723dbf4d4 100644 --- a/examples/platform/telink/util/src/PWMManager.cpp +++ b/examples/platform/telink/util/src/PWMManager.cpp @@ -142,7 +142,7 @@ void PwmManager::linkBackend(PwmBackend & backend) } } -#if CONFIG_WS2812_STRIP +#if CONFIG_WS2812_STRIP_GPIO_TELINK #include @@ -297,4 +297,4 @@ void PwmDummy::setPwmHWBreath(size_t pwm, size_t breathMs) LOG_WRN("PWM Dummy setPwmHWBreath not supported"); } -#endif // CONFIG_WS2812_STRIP +#endif // CONFIG_WS2812_STRIP_GPIO_TELINK diff --git a/examples/platform/telink/zephyr_ext/zephyr_key_matrix.c b/examples/platform/telink/zephyr_ext/zephyr_key_matrix.c index 00ea46c82d0e2f..e81fe8d3eff908 100644 --- a/examples/platform/telink/zephyr_ext/zephyr_key_matrix.c +++ b/examples/platform/telink/zephyr_ext/zephyr_key_matrix.c @@ -47,7 +47,7 @@ static void key_matrix_poll(struct key_matrix_data * key_matrix, bool init) /* Key matrix scan worker */ static void key_matrix_scan_work(struct k_work * item) { - struct key_matrix_data * key_matrix = CONTAINER_OF(item, struct key_matrix_data, work); + struct key_matrix_data * key_matrix = CONTAINER_OF(k_work_delayable_from_work(item), struct key_matrix_data, work); (void) k_work_schedule(&key_matrix->work, K_MSEC(KEY_MATRIX_SCAN_PERIOD_MS)); key_matrix_poll(key_matrix, false); diff --git a/examples/platform/telink/zephyr_ext/zephyr_key_pool.c b/examples/platform/telink/zephyr_ext/zephyr_key_pool.c index 5a88d15303fde9..c3fa044dc1f924 100644 --- a/examples/platform/telink/zephyr_ext/zephyr_key_pool.c +++ b/examples/platform/telink/zephyr_ext/zephyr_key_pool.c @@ -75,7 +75,7 @@ static void key_pool_poll(struct key_pool_data * key_pool, bool init) /* Key pool scan worker */ static void key_pool_event_work(struct k_work * item) { - struct key_pool_data * key_pool = CONTAINER_OF(item, struct key_pool_data, work); + struct key_pool_data * key_pool = CONTAINER_OF(k_work_delayable_from_work(item), struct key_pool_data, work); key_pool_poll(key_pool, false); } diff --git a/examples/platform/telink/zephyr_ext/zephyr_led_pool.c b/examples/platform/telink/zephyr_ext/zephyr_led_pool.c index f8ced2d413fd63..a00544c403861f 100644 --- a/examples/platform/telink/zephyr_ext/zephyr_led_pool.c +++ b/examples/platform/telink/zephyr_ext/zephyr_led_pool.c @@ -80,7 +80,7 @@ static void led_pool_aux_update(const struct led_pool_data * led_pool) /* Led pool worker */ static void led_pool_event_work(struct k_work * item) { - struct led_pool_data * led_pool = CONTAINER_OF(item, struct led_pool_data, work); + struct led_pool_data * led_pool = CONTAINER_OF(k_work_delayable_from_work(item), struct led_pool_data, work); led_pool_aux_update(led_pool); (void) k_work_reschedule(&led_pool->work, led_pool_aux_timeout(led_pool)); diff --git a/examples/platform/telink/zephyr_ext/zephyr_pwm_pool.c b/examples/platform/telink/zephyr_ext/zephyr_pwm_pool.c index 3f1651844f1cec..0322e812b62a92 100644 --- a/examples/platform/telink/zephyr_ext/zephyr_pwm_pool.c +++ b/examples/platform/telink/zephyr_ext/zephyr_pwm_pool.c @@ -140,7 +140,7 @@ static void pwm_pool_aux_update(const struct pwm_pool_data * pwm_pool) /* Pwm pool worker */ static void pwm_pool_event_work(struct k_work * item) { - struct pwm_pool_data * pwm_pool = CONTAINER_OF(item, struct pwm_pool_data, work); + struct pwm_pool_data * pwm_pool = CONTAINER_OF(k_work_delayable_from_work(item), struct pwm_pool_data, work); pwm_pool_aux_update(pwm_pool); (void) k_work_reschedule(&pwm_pool->work, pwm_pool_aux_timeout(pwm_pool)); diff --git a/examples/tv-app/android/BUILD.gn b/examples/tv-app/android/BUILD.gn index f08f16f363e516..4978c5c2173778 100644 --- a/examples/tv-app/android/BUILD.gn +++ b/examples/tv-app/android/BUILD.gn @@ -167,11 +167,11 @@ android_library("java") { javac_flags = [ "-Xlint:deprecation" ] # TODO: add classpath support (we likely need to add something like - # ..../platforms/android-26/android.jar to access BLE items) + # ..../platforms/android-30/android.jar to access BLE items) } java_prebuilt("android") { - jar_path = "${android_sdk_root}/platforms/android-26/android.jar" + jar_path = "${android_sdk_root}/platforms/android-30/android.jar" } group("default") { diff --git a/examples/tv-casting-app/android/BUILD.gn b/examples/tv-casting-app/android/BUILD.gn index 18937b34d97e52..82f68ad0af1dfe 100644 --- a/examples/tv-casting-app/android/BUILD.gn +++ b/examples/tv-casting-app/android/BUILD.gn @@ -120,11 +120,11 @@ android_library("java") { javac_flags = [ "-Xlint:deprecation" ] # TODO: add classpath support (we likely need to add something like - # ..../platforms/android-26/android.jar to access BLE items) + # ..../platforms/android-30/android.jar to access BLE items) } java_prebuilt("android") { - jar_path = "${android_sdk_root}/platforms/android-26/android.jar" + jar_path = "${android_sdk_root}/platforms/android-30/android.jar" } group("default") { diff --git a/examples/virtual-device-app/android/BUILD.gn b/examples/virtual-device-app/android/BUILD.gn index 7f071107544719..79b77f5e76810f 100644 --- a/examples/virtual-device-app/android/BUILD.gn +++ b/examples/virtual-device-app/android/BUILD.gn @@ -85,11 +85,11 @@ android_library("java") { javac_flags = [ "-Xlint:deprecation" ] # TODO: add classpath support (we likely need to add something like - # ..../platforms/android-26/android.jar to access BLE items) + # ..../platforms/android-30/android.jar to access BLE items) } java_prebuilt("android") { - jar_path = "${android_sdk_root}/platforms/android-26/android.jar" + jar_path = "${android_sdk_root}/platforms/android-30/android.jar" } group("default") { diff --git a/integrations/cloudbuild/chef.yaml b/integrations/cloudbuild/chef.yaml index 45c4df62387847..17a45e36233187 100644 --- a/integrations/cloudbuild/chef.yaml +++ b/integrations/cloudbuild/chef.yaml @@ -1,5 +1,5 @@ steps: - - name: "ghcr.io/project-chip/chip-build-vscode:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" 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:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" # 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:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" env: - PW_ENVIRONMENT_ROOT=/pwenv args: @@ -38,7 +38,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" env: - PW_ENVIRONMENT_ROOT=/pwenv args: diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index 715019984f2b50..174ef4b8bfe32b 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:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" 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:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" # 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:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" id: ESP32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -44,7 +44,7 @@ steps: volumes: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -65,7 +65,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" id: EFR32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -87,7 +87,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:104" + - name: "ghcr.io/project-chip/chip-build-vscode:112" id: Linux env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -140,7 +140,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:108" + - name: "ghcr.io/project-chip/chip-build-vscode:113" 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 8339f7089f0d0b..84d3e578126e6b 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -112 : [Telink] Update Docker image (Zephyr SDK update) +113 : [Android] set java 8 for java docker diff --git a/integrations/docker/images/stage-2/chip-build-java/Dockerfile b/integrations/docker/images/stage-2/chip-build-java/Dockerfile index c5b54e4c439f8e..3cf226efa86205 100644 --- a/integrations/docker/images/stage-2/chip-build-java/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-java/Dockerfile @@ -6,7 +6,7 @@ LABEL org.opencontainers.image.source https://github.com/project-chip/connectedh RUN set -x \ && apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install -fy \ - openjdk-11-jdk \ + openjdk-8-jdk \ && rm -rf /var/lib/apt/lists/ \ && : # last line @@ -20,4 +20,4 @@ RUN set -x \ && : # last line ENV PATH $PATH:/usr/lib/kotlinc/bin -ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 +ENV JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 diff --git a/integrations/docker/images/stage-3/chip-build-android/Dockerfile b/integrations/docker/images/stage-3/chip-build-android/Dockerfile index eb2360ccb937e0..ee2a2d55fb2fd1 100644 --- a/integrations/docker/images/stage-3/chip-build-android/Dockerfile +++ b/integrations/docker/images/stage-3/chip-build-android/Dockerfile @@ -2,9 +2,6 @@ ARG VERSION=1 FROM ghcr.io/project-chip/chip-build-java:${VERSION} LABEL org.opencontainers.image.source https://github.com/project-chip/connectedhomeip -# JDK 8 access -# JDK 8 is required because Android `sdkmanager` -# doesn't work with JDK 11. RUN set -x \ && apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install -fy \ @@ -72,3 +69,4 @@ RUN set -x \ ENV ANDROID_HOME=/opt/android/sdk ENV ANDROID_NDK_HOME=/opt/android/android-ndk-r23c +ENV JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 2817afb6bd853d..b5655819c00265 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -80,8 +80,7 @@ def BuildHostFakeTarget(): "-clang").ExceptIfRe('-libfuzzer') target.AppendModifier("pw-fuzztest", fuzzing_type=HostFuzzingType.PW_FUZZTEST).OnlyIfRe( "-clang").ExceptIfRe('-(libfuzzer|ossfuzz|asan)') - target.AppendModifier('coverage', use_coverage=True).OnlyIfRe( - '-(chip-tool|all-clusters)').ExceptIfRe('-clang') + target.AppendModifier('coverage', use_coverage=True) target.AppendModifier('dmalloc', use_dmalloc=True) target.AppendModifier('clang', use_clang=True) diff --git a/scripts/build/builders/android.py b/scripts/build/builders/android.py index 3f640177f190ad..fa112e9aaf7911 100644 --- a/scripts/build/builders/android.py +++ b/scripts/build/builders/android.py @@ -164,9 +164,9 @@ def validate_build_environment(self): os.environ["ANDROID_HOME"], "tools", "bin", "sdkmanager" ) - # New SDK manager at cmdline-tools/latest/bin/ + # New SDK manager at cmdline-tools/10.0/bin/ new_sdk_manager = os.path.join( - os.environ["ANDROID_HOME"], "cmdline-tools", "latest", "bin", "sdkmanager" + os.environ["ANDROID_HOME"], "cmdline-tools", "10.0", "bin", "sdkmanager" ) if not ( os.path.isfile(sdk_manager) and os.access(sdk_manager, os.X_OK) @@ -413,7 +413,7 @@ def generate(self): new_sdk_manager = os.path.join( os.environ["ANDROID_HOME"], "cmdline-tools", - "latest", + "10.0", "bin", "sdkmanager", ) diff --git a/scripts/build/builders/bouffalolab.py b/scripts/build/builders/bouffalolab.py index d575259aafab7a..5cee2d873bb8b7 100644 --- a/scripts/build/builders/bouffalolab.py +++ b/scripts/build/builders/bouffalolab.py @@ -285,16 +285,14 @@ def PreBuildCommand(self): def PostBuildCommand(self): - bouffalo_sdk_chips = ["bl616"] - abs_path_fw = os.path.join(self.output_dir, self.app.AppNamePrefix(self.chip_name) + ".bin") - - if self.chip_name not in bouffalo_sdk_chips: - abs_path_fw_raw = os.path.join(self.output_dir, self.app.AppNamePrefix(self.chip_name) + ".raw") + if self.chip_name in ["bl616"]: + abs_path_fw = os.path.join(self.output_dir, self.app.AppNamePrefix(self.chip_name) + ".raw") + else: + abs_path_fw = os.path.join(self.output_dir, self.app.AppNamePrefix(self.chip_name) + ".bin") if os.path.isfile(abs_path_fw): target_dir = self.output_dir.replace(self.chip_dir, "").strip("/") - abs_path_fw_bin = os.path.join(self.output_dir, self.app.AppNamePrefix(self.chip_name) + ".bin") path_fw = os.path.join(target_dir, self.app.AppNamePrefix(self.chip_name) + ".bin") path_flash_script = os.path.join(target_dir, self.app.AppNamePrefix(self.chip_name) + ".flash.py") diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 8dd1cf3e93dd98..8611ddad629303 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -13,6 +13,7 @@ # limitations under the License. import os +import shlex from enum import Enum, auto from platform import uname from typing import Optional @@ -547,6 +548,13 @@ def GnBuildEnv(self): if self.board == HostBoard.ARM64: self.build_env['PKG_CONFIG_PATH'] = os.path.join( self.SysRootPath('SYSROOT_AARCH64'), 'lib/aarch64-linux-gnu/pkgconfig') + if self.app == HostApp.TESTS and self.use_coverage and self.use_clang: + # Every test is expected to have a distinct build ID, so `%m` will be + # distinct. + # + # Output is relative to "oputput_dir" since that is where GN executs + self.build_env['LLVM_PROFILE_FILE'] = os.path.join("coverage", "profiles", "run_%b.profraw") + return self.build_env def SysRootPath(self, name): @@ -556,7 +564,7 @@ def SysRootPath(self, name): def generate(self): super(HostBuilder, self).generate() - if 'JAVA_PATH' in os.environ: + if 'JAVA_HOME' in os.environ: self._Execute( ["third_party/java_deps/set_up_java_deps.sh"], title="Setting up Java deps", @@ -621,6 +629,60 @@ def PostBuildCommand(self): self._Execute(['genhtml', os.path.join(self.coverage_dir, 'lcov_final.info'), '--output-directory', os.path.join(self.coverage_dir, 'html')], title="HTML coverage") + # coverage for clang works by having perfdata for every test run, which are in "*.profraw" files + if self.app == HostApp.TESTS and self.use_coverage and self.use_clang: + # Clang coverage config generates "coverage/{name}.profraw" for each test indivdually + # Here we are merging ALL raw profiles into a single indexed file + + _indexed_instrumentation = shlex.quote(os.path.join(self.coverage_dir, "merged.profdata")) + + self._Execute([ + "bash", + "-c", + f'find {shlex.quote(self.coverage_dir)} -name "*.profraw"' + + f' | xargs -n 10240 llvm-profdata merge -sparse -o {_indexed_instrumentation}' + ], + title="Generating merged coverage data") + + _lcov_data = os.path.join(self.coverage_dir, "merged.lcov") + + self._Execute([ + "bash", + "-c", + f'find {shlex.quote(self.coverage_dir)} -name "*.profraw"' + + ' | xargs -n1 basename | sed "s/\\.profraw//" ' + + f' | xargs -I @ echo -object {shlex.quote(os.path.join(self.output_dir, "tests", "@"))}' + + f' | xargs -n 10240 llvm-cov export -format=lcov --instr-profile {_indexed_instrumentation} ' + # only care about SDK code. third_party is not considered sdk + + ' --ignore-filename-regex "/third_party/"' + # about 75K lines with almost 0% coverage + + ' --ignore-filename-regex "/zzz_generated/"' + # generated interface files. about 8K lines with little coverage + + ' --ignore-filename-regex "/out/.*/Linux/dbus/"' + # 100% coverage for 1K lines, but not relevant (test code) + + ' --ignore-filename-regex "/out/.*/clang_static_coverage_config/"' + # Tests are likely 100% or close to, want to see only "functionality tested" + + ' --ignore-filename-regex "/tests/"' + # Ignore system includes + + ' --ignore-filename-regex "/usr/include/"' + + ' --ignore-filename-regex "/usr/lib/"' + + f' | cat >{shlex.quote(_lcov_data)}' + ], + title="Generating lcov data") + + self._Execute([ + "genhtml", + "--ignore-errors", + "inconsistent", + "--ignore-errors", + "range", + # "--hierarchical" <- this may be interesting + "--output", + os.path.join(self.output_dir, "html"), + os.path.join(self.coverage_dir, "merged.lcov"), + ], + title="Generating HTML coverage report") + if self.app == HostApp.JAVA_MATTER_CONTROLLER: self.createJavaExecutable("java-matter-controller") diff --git a/scripts/build/clang_coverage_wrapper.py b/scripts/build/clang_coverage_wrapper.py new file mode 100644 index 00000000000000..a8b2cc98abbfd5 --- /dev/null +++ b/scripts/build/clang_coverage_wrapper.py @@ -0,0 +1,91 @@ +#!/usr/bin/env -S python3 -B + +# Copyright (c) 2025 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 click +import coloredlogs +import jinja2 + +# Supported log levels, mapping string values required for argument +# parsing into logging constants +__LOG_LEVELS__ = { + "debug": logging.DEBUG, + "info": logging.INFO, + "warn": logging.WARN, + "fatal": logging.FATAL, +} + +# This repesents the code that is generated according to +# https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#using-the-profiling-runtime-without-static-initializers +# +# So that the output of coverage is customized and does not go to `default.profraw` +_CPP_TEMPLATE = """\ +extern "C" { + +int __llvm_profile_runtime = 0; +void __llvm_profile_initialize_file(); +void __llvm_profile_write_file(); +void __llvm_profile_set_filename(const char *); + +} // extern "C" + +struct StaticInitLLVMProfile { + StaticInitLLVMProfile() { + __llvm_profile_set_filename("{{raw_profile_filename}}"); + } + ~StaticInitLLVMProfile() { + __llvm_profile_write_file(); + } +} gInitLLVMProfilingPaths; +""" + + +@click.command() +@click.option( + "--log-level", + default="INFO", + type=click.Choice([k for k in __LOG_LEVELS__.keys()], case_sensitive=False), + help="Determines the verbosity of script output.", +) +@click.option( + "--no-log-timestamps", + default=False, + is_flag=True, + help="Skip timestaps in log output", +) +@click.option( + "--output", + help="What file to output when runnning under clang profiling", +) +@click.option( + "--raw-profile-filename", + help="Filename to use for output", +) +def main(log_level, no_log_timestamps, output, raw_profile_filename): + log_fmt = "%(asctime)s %(levelname)-7s %(message)s" + if no_log_timestamps: + log_fmt = "%(levelname)-7s %(message)s" + coloredlogs.install(level=__LOG_LEVELS__[log_level], fmt=log_fmt) + + logging.info("Writing output to %s (profile name: %s)", output, raw_profile_filename) + with open(output, "wt") as f: + f.write(jinja2.Template(_CPP_TEMPLATE).render(raw_profile_filename=raw_profile_filename)) + + logging.debug("Writing completed") + + +if __name__ == "__main__": + main(auto_envvar_prefix="CHIP") diff --git a/scripts/build/test.py b/scripts/build/test.py index f1488ba17b870a..6fa25fec257443 100644 --- a/scripts/build/test.py +++ b/scripts/build/test.py @@ -47,7 +47,7 @@ def build_actual_output(root: str, out: str, args: List[str]) -> List[str]: 'NXP_K32W0_SDK_ROOT': 'TEST_NXP_K32W0_SDK_ROOT', 'IMX_SDK_ROOT': 'IMX_SDK_ROOT', 'TI_SYSCONFIG_ROOT': 'TEST_TI_SYSCONFIG_ROOT', - 'JAVA_PATH': 'TEST_JAVA_PATH', + 'JAVA_HOME': 'TEST_JAVA_HOME', 'GSDK_ROOT': 'TEST_GSDK_ROOT', 'WISECONNECT_SDK_ROOT': 'TEST_WISECONNECT_SDK_ROOT', 'WIFI_SDK_ROOT': 'TEST_WIFI_SDK_ROOT', diff --git a/scripts/build_coverage.sh b/scripts/build_coverage.sh index 2cf3f13ee131ad..d21aef5a77eb7e 100755 --- a/scripts/build_coverage.sh +++ b/scripts/build_coverage.sh @@ -218,12 +218,14 @@ fi mkdir -p "$COVERAGE_ROOT" lcov --initial --capture --directory "$OUTPUT_ROOT/obj/src" \ + --ignore-errors inconsistent \ --exclude="$PWD"/zzz_generated/* \ --exclude="$PWD"/third_party/* \ --exclude=/usr/include/* \ --output-file "$COVERAGE_ROOT/lcov_base.info" lcov --capture --directory "$OUTPUT_ROOT/obj/src" \ + --ignore-errors inconsistent \ --exclude="$PWD"/zzz_generated/* \ --exclude="$PWD"/third_party/* \ --exclude=/usr/include/* \ @@ -231,9 +233,11 @@ lcov --capture --directory "$OUTPUT_ROOT/obj/src" \ lcov --add-tracefile "$COVERAGE_ROOT/lcov_base.info" \ --add-tracefile "$COVERAGE_ROOT/lcov_test.info" \ + --ignore-errors inconsistent \ --output-file "$COVERAGE_ROOT/lcov_final.info" genhtml "$COVERAGE_ROOT/lcov_final.info" \ + --ignore-errors inconsistent \ --output-directory "$COVERAGE_ROOT/html" \ --title "SHA:$(git rev-parse HEAD)" \ --header-title "Matter SDK Coverage Report" diff --git a/scripts/flashing/bouffalolab_firmware_utils.py b/scripts/flashing/bouffalolab_firmware_utils.py index e6ca898609102f..a65ec869ed7b39 100755 --- a/scripts/flashing/bouffalolab_firmware_utils.py +++ b/scripts/flashing/bouffalolab_firmware_utils.py @@ -446,7 +446,67 @@ def exe_gen_ota_image_cmd(flashtool_exe): new_name = os.path.join(self.work_dir, "ota_images", fw_name + ota_img_name[len("FW_OTA"):]) os.system("mv {} {}".format(img, new_name)) - def exe_prog_cmd(flashtool_exe, mfd_addr): + def construct_prog_confg(): + + iot_cfg = { + "param": { + "interface_type": "uart", + "comport_uart": self.args["port"], + "speed_uart": self.args["baudrate"], + "speed_jlink": "1000", + "chip_xtal": self.args["xtal"], + "ota": "", + "version": "", + "aes_key": "", + "aes_iv": "", + "addr": "0x0", + "publickey": "", + "privatekey": "" + }, + "check_box": { + "fw_download": True, + "mfg_download": False, + "media_download": False, + "romfs_download": False, + "psm_download": False, + "key_download": False, + "data_download": False, + "factory_download": True if self.args["dts"] else False, + "mfd_download": True if self.args["mfd"] else False, + "boot2_download": True if self.args["boot2"] else False, + "ckb_erase_all": "True" if self.args["erase"] else "False", + "partition_download": True if self.args["pt"] else False, + "encrypt": False, + "sign": False, + "single_download": False, + "auto_efuse_verify": False + }, + "input_path": { + "fw_bin_input": self.args['firmware'], + "mfg_bin_input": "", + "media_bin_input": "", + "romfs_dir_input": "", + "psm_bin_input": "", + "key_bin_input": "", + "data_bin_input": "", + "factory_bin_input": self.args["dts"], + "mfd_bin_input": self.args["mfd"], + "boot2_bin_input": self.args["boot2"], + "img_bin_input": "", + "pt_table_bin_input": self.args["pt"], + "publickey": "", + "privatekey": "" + } + } + + conf_toml = os.path.splitext(self.args['firmware'])[0] + "_config.toml" + + with open(conf_toml, "w", encoding="utf-8") as f: + toml.dump(iot_cfg, f) + + return conf_toml + + def exe_prog_cmd(flashtool_exe, mfd_addr, flashtool_path): if not self.args["port"]: return @@ -454,33 +514,43 @@ def exe_prog_cmd(flashtool_exe, mfd_addr): if self.args["mfd"] and not mfd_addr: raise Exception("No MFD partition found in partition table.") - prog_cmd = [ - flashtool_exe, - "--port", self.args["port"], - "--baudrate", self.args["baudrate"], - "--chipname", self.args["chipname"], - "--firmware", self.args["firmware"], - "--dts", self.args["dts"], - "--pt", self.args["pt"], - ] + if self.args["mfd"] and not self.args["key"]: + conf_toml = construct_prog_confg() - if self.args["boot2"]: - prog_cmd += ["--boot2", self.args["boot2"]] + prog_cmd = [ + flashtool_exe, + "--chipname", self.args["chipname"], + "--config", conf_toml, + ] - if self.args["sk"]: - prog_cmd += ["--sk", self.args["sk"]] + else: + prog_cmd = [ + flashtool_exe, + "--port", self.args["port"], + "--baudrate", self.args["baudrate"], + "--chipname", self.args["chipname"], + "--firmware", self.args["firmware"], + "--dts", self.args["dts"], + "--pt", self.args["pt"], + ] - if mfd_addr and self.args["mfd_str"]: - if self.args["key"] and not self.args["iv"]: - logging.warning("mfd file has no iv, do NOT program mfd key.") - else: - prog_cmd += ["--dac_key", self.args["key"]] - prog_cmd += ["--dac_iv", self.args["iv"]] - prog_cmd += ["--dac_addr", hex(mfd_addr)] - prog_cmd += ["--dac_value", self.args["mfd_str"]] + if self.args["boot2"]: + prog_cmd += ["--boot2", self.args["boot2"]] + + if self.args["sk"]: + prog_cmd += ["--sk", self.args["sk"]] + + if mfd_addr and self.args["mfd_str"]: + if self.args["key"] and not self.args["iv"]: + logging.warning("mfd file has no iv, do NOT program mfd key.") + else: + prog_cmd += ["--dac_key", self.args["key"]] + prog_cmd += ["--dac_iv", self.args["iv"]] + prog_cmd += ["--dac_addr", hex(mfd_addr)] + prog_cmd += ["--dac_value", self.args["mfd_str"]] - if self.option.erase: - prog_cmd += ["--erase"] + if self.option.erase: + prog_cmd += ["--erase"] logging.info("firmware programming: {}".format(" ".join(prog_cmd))) process = subprocess.Popen(prog_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -500,7 +570,7 @@ def exe_prog_cmd(flashtool_exe, mfd_addr): os.chdir(self.work_dir) exe_gen_ota_image_cmd(flashtool_exe) - exe_prog_cmd(flashtool_exe, mfd_addr) + exe_prog_cmd(flashtool_exe, mfd_addr, flashtool_path) def bouffalo_sdk_prog(self): diff --git a/scripts/setup/requirements.bouffalolab.txt b/scripts/setup/requirements.bouffalolab.txt index 933330c0a4ad82..9dc4cc2c226ac0 100644 --- a/scripts/setup/requirements.bouffalolab.txt +++ b/scripts/setup/requirements.bouffalolab.txt @@ -4,4 +4,6 @@ ecdsa>=0.18.0 qrcode==7.4.2 bitarray==2.6.0 python_stdnum==1.18 -pycryptodome>=3.20.0 \ No newline at end of file +pycryptodome>=3.20.0 +toml>=0.10.2 +construct>=2.10.70 diff --git a/scripts/spec_xml/generate_spec_xml.py b/scripts/spec_xml/generate_spec_xml.py index e72da49cf34c09..48f75b87985107 100755 --- a/scripts/spec_xml/generate_spec_xml.py +++ b/scripts/spec_xml/generate_spec_xml.py @@ -154,6 +154,9 @@ def scrape_all(scraper, spec_root, output_dir, dry_run, include_in_progress): os.remove(os.path.join(clusters_output_dir, filename)) for filename in os.listdir(device_types_output_dir): + # Closures also has multiple device types in one file, should fix this, but for now a workaround: + if filename.startswith('ClosureBaseDeviceTypes'): + continue adoc = os.path.basename(filename).replace('.xml', '.adoc') if adoc not in device_type_files: print(f'Removing {adoc} as it was not in the generated spec document') diff --git a/scripts/tools/ELF_SIZE_TOOLING.md b/scripts/tools/ELF_SIZE_TOOLING.md index 7e7e9883afabfa..400fa118d78645 100644 --- a/scripts/tools/ELF_SIZE_TOOLING.md +++ b/scripts/tools/ELF_SIZE_TOOLING.md @@ -26,7 +26,7 @@ you can build the master branch of a binary and save it somewhere like Example runs: ``` -> ~/devel/chip-scripts/bindiff.py \ +> ./scripts/tools/binary_elf_size_diff.py \ ./out/qpg-qpg6105-light/chip-qpg6105-lighting-example.out \ ./out/qpg-master.out @@ -46,7 +46,7 @@ TOTAL -34 ``` ``` -> ~/devel/chip-scripts/bindiff.py \ +> ./scripts/tools/binary_elf_size_diff.py \ --output csv --skip-total \ ./out/qpg-qpg6105-light/chip-qpg6105-lighting-example.out ./out/qpg-master.out diff --git a/scripts/tools/bouffalolab/generate_factory_data.py b/scripts/tools/bouffalolab/generate_factory_data.py index f6475ed07650d2..18a1159f994001 100755 --- a/scripts/tools/bouffalolab/generate_factory_data.py +++ b/scripts/tools/bouffalolab/generate_factory_data.py @@ -133,7 +133,9 @@ def gen_test_certs(chip_cert: str, pai_cert: str = None, pai_key: str = None, dac_cert: str = None, - dac_key: str = None): + dac_key: str = None, + dac_product_id: int = None, + discriminator: int = None): def parse_cert_file(cert): @@ -189,7 +191,7 @@ def verify_certificates(chip_cert, paa_cert, pai_cert, dac_cert): log.info("Verify Certificate Chain: {}".format(shlex.join(cmd))) subprocess.run(cmd) - def gen_dac_certificate(chip_cert, device_name, vendor_id, product_id, pai_cert, pai_key, dac_cert, dac_key, pai_issue_date, pai_expire_date): + def gen_dac_certificate(chip_cert, device_name, dac_vid, dac_pid, pai_cert, pai_key, dac_cert, dac_key, pai_issue_date, pai_expire_date, discriminator): def gen_valid_times(issue_date, expire_date): now = datetime.now() - timedelta(days=1) @@ -206,8 +208,8 @@ def gen_valid_times(issue_date, expire_date): cmd = [chip_cert, "gen-att-cert", "--type", "d", # device attestation certificate "--subject-cn", device_name + " Test DAC 0", - "--subject-vid", hex(vendor_id), - "--subject-pid", hex(product_id), + "--subject-vid", hex(dac_vid), + "--subject-pid", hex(dac_pid), "--ca-cert", pai_cert, "--ca-key", pai_key, "--out", dac_cert, @@ -230,7 +232,7 @@ def convert_pem_to_der(chip_cert, action, pem): return der - def gen_cd(chip_cert, dac_vendor_id, dac_product_id, vendor_id, product_id, cd_cert, cd_key, cd): + def gen_cd(chip_cert, paa_cert, dac_vendor_id, dac_product_id, vendor_id, product_id, cd_cert, cd_key, cd): if os.path.isfile(cd): return @@ -255,15 +257,29 @@ def gen_cd(chip_cert, dac_vendor_id, dac_product_id, vendor_id, product_id, cd_c "--dac-origin-product-id", hex(dac_product_id), ] + if paa_cert: + cmd += ["--authorized-paa-cert", paa_cert] + log.info("Generate CD: {}".format(shlex.join(cmd))) subprocess.run(cmd) pai_vendor_id, pai_product_id, pai_issue_date, pai_expire_date = parse_cert_file(pai_cert) - dac_vendor_id = pai_vendor_id if pai_vendor_id else vendor_id - dac_product_id = pai_product_id if pai_product_id else product_id + dac_vendor_id = pai_vendor_id + + if dac_product_id is not None and pai_product_id is not None and dac_product_id != pai_product_id: + raise Exception("Specified product id for DAC certificate is not same as product id in PAI certificate.") + + if pai_product_id is not None: + dac_product_id = pai_product_id + + if dac_cert is None: + dac_disc_vp = "{}_{}_{}".format(hex(dac_vendor_id).split("x")[-1], hex(dac_product_id).split("x")[-1], discriminator) + dac_cert = os.path.join(output, "out_{}_dac_cert.pem".format(dac_disc_vp)) + dac_key = os.path.join(output, "out_{}_dac_key.pem".format(dac_disc_vp)) + gen_dac_certificate(chip_cert, device_name, dac_vendor_id, dac_product_id, pai_cert, - pai_key, dac_cert, dac_key, pai_issue_date, pai_expire_date) + pai_key, dac_cert, dac_key, pai_issue_date, pai_expire_date, discriminator) dac_cert_der = convert_pem_to_der(chip_cert, "convert-cert", dac_cert) dac_key_der = convert_pem_to_der(chip_cert, "convert-key", dac_key) @@ -274,7 +290,7 @@ def gen_cd(chip_cert, dac_vendor_id, dac_product_id, vendor_id, product_id, cd_c verify_certificates(chip_cert, paa_cert, pai_cert, dac_cert) - gen_cd(chip_cert, dac_vendor_id, dac_product_id, vendor_id, product_id, cd_cert, cd_key, cd) + gen_cd(chip_cert, paa_cert, dac_vendor_id, dac_product_id, vendor_id, product_id, cd_cert, cd_key, cd) return cd, pai_cert_der, dac_cert_der, dac_key_der @@ -447,10 +463,14 @@ def to_bytes(input): else: return None + def hex_to_int(hex_string): + return int(hex_string, 16) + parser = argparse.ArgumentParser(description="Bouffalo Lab Factory Data generator tool") parser.add_argument("--dac_cert", type=str, help="DAC certificate file.") parser.add_argument("--dac_key", type=str, help="DAC certificate privat key.") + parser.add_argument("--dac_pid", type=hex_to_int, help="Product Identification, hex string, used in DAC certificate. ") parser.add_argument("--passcode", type=int, help="Setup pincode, optional.") parser.add_argument("--pai_cert", type=str, default=TEST_PAI_CERT, help="PAI certificate file.") parser.add_argument("--cd", type=str, help="Certificate Declaration file.") @@ -460,9 +480,9 @@ def to_bytes(input): parser.add_argument("--spake2p_it", type=int, default=None, help="Spake2+ iteration count, optional.") parser.add_argument("--spake2p_salt", type=base64.b64decode, help="Spake2+ salt in hex string, optional.") - parser.add_argument("--vendor_id", type=int, default=0x130D, help="Vendor Identification, mandatory.") + parser.add_argument("--vendor_id", type=hex_to_int, default=0x130D, help="Vendor Identification, hex string, mandatory.") parser.add_argument("--vendor_name", type=str, default="Bouffalo Lab", help="Vendor Name string, optional.") - parser.add_argument("--product_id", type=int, default=0x1001, help="Product Identification, mandatory.") + parser.add_argument("--product_id", type=hex_to_int, default=0x1001, help="Product Identification, hex string, mandatory.") parser.add_argument("--product_name", type=str, default="Test Product", help="Product Name string, optional.") parser.add_argument("--product_part_no", type=str, help="Product Part number, optional.") @@ -494,11 +514,8 @@ def to_bytes(input): unique_id = gen_test_unique_id(args.unique_id) spake2p_it, spake2p_salt, spake2p_verifier = gen_test_spake2(passcode, args.spake2p_it, args.spake2p_salt) - vp_info = "{}_{}".format(hex(args.vendor_id), hex(args.product_id)) - vp_disc_info = "{}_{}_{}".format(hex(args.vendor_id), hex(args.product_id), discriminator) - if args.dac_cert is None: - args.dac_cert = os.path.join(args.output, "out_{}_dac_cert.pem".format(vp_disc_info)) - args.dac_key = os.path.join(args.output, "out_{}_dac_key.pem".format(vp_disc_info)) + vp_info = "{}_{}".format(hex(args.vendor_id).split('x')[-1], hex(args.product_id).split('x')[-1]) + vp_disc_info = "{}_{}".format(vp_info, discriminator) if args.cd is None: args.cd = os.path.join(args.output, "out_{}_cd.der".format(vp_info)) @@ -516,7 +533,9 @@ def to_bytes(input): args.pai_cert, args.pai_key, args.dac_cert, - args.dac_key) + args.dac_key, + args.dac_pid, + discriminator) mfd_output = os.path.join(args.output, "out_{}_mfd.bin".format(vp_disc_info)) args.dac_cert = dac_cert_der diff --git a/scripts/tools/telink/process_binaries.py b/scripts/tools/telink/process_binaries.py index 5144920dd86823..27443ba072e5d6 100755 --- a/scripts/tools/telink/process_binaries.py +++ b/scripts/tools/telink/process_binaries.py @@ -103,7 +103,7 @@ def compress_lzma_firmware(input_file, output_file): os.remove('merged.bin') # Telink W91 dual-core SoC binary operations -if build_conf.getboolean('CONFIG_SOC_SERIES_RISCV_TELINK_W91'): +if build_conf.getboolean('CONFIG_SOC_RISCV_TELINK_W91'): n22_partition_offset = build_conf['CONFIG_TELINK_W91_N22_PARTITION_ADDR'] if build_conf.getboolean('CONFIG_BOOTLOADER_MCUBOOT'): n22_partition_offset -= build_conf['CONFIG_FLASH_LOAD_OFFSET'] diff --git a/scripts/tools/telink/requirements.txt b/scripts/tools/telink/requirements.txt index e76b1423e4ded9..891532c9448a1a 100644 --- a/scripts/tools/telink/requirements.txt +++ b/scripts/tools/telink/requirements.txt @@ -1,4 +1,4 @@ -cryptography==43.0.1 +cryptography==44.0.1 cffi==1.15.0; python_version < "3.13" cffi==1.17.1; python_version >= "3.13" future==0.18.3 diff --git a/src/app/GlobalAttributes.cpp b/src/app/GlobalAttributes.cpp index a65f79b22bd870..ac6c00ab447d58 100644 --- a/src/app/GlobalAttributes.cpp +++ b/src/app/GlobalAttributes.cpp @@ -97,14 +97,6 @@ DataModel::ActionReturnStatus ReadGlobalAttributeFromMetadata(DataModel::Provide // and this reduces template variants for Encode, saving flash. ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast(entry.attributeId))); } - - for (auto id : GlobalAttributesNotInMetadata) - { - // NOTE: cast to u64 because TLV encodes all numbers the same (no TLV sideffects) - // and this reduces template variants for Encode, saving flash. - ReturnErrorOnFailure(listEncodeHelper.Encode(static_cast(id))); - } - return CHIP_NO_ERROR; }); } diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index da2190629ec4c1..6a96afcf29429d 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -1801,28 +1801,8 @@ Protocols::InteractionModel::Status InteractionModelEngine::CheckCommandExistenc } } - { - DataModel::ServerClusterFinder finder(provider); - if (finder.Find(aCommandPath).has_value()) - { - // cluster exists, so command is invalid - return Protocols::InteractionModel::Status::UnsupportedCommand; - } - } - - // At this point either cluster or endpoint does not exist. If we find the endpoint, then the cluster - // is invalid - { - DataModel::EndpointFinder finder(provider); - if (finder.Find(aCommandPath.mEndpointId)) - { - // endpoint exists, so cluster is invalid - return Protocols::InteractionModel::Status::UnsupportedCluster; - } - } - - // endpoint not found - return Protocols::InteractionModel::Status::UnsupportedEndpoint; + // invalid command, return the right failure status + return DataModel::ValidateClusterPath(provider, aCommandPath, Protocols::InteractionModel::Status::UnsupportedCommand); } DataModel::Provider * InteractionModelEngine::SetDataModelProvider(DataModel::Provider * model) diff --git a/src/app/InteractionModelEngine.h b/src/app/InteractionModelEngine.h index 12c3262d34f60a..eb66f3eb5a4ed1 100644 --- a/src/app/InteractionModelEngine.h +++ b/src/app/InteractionModelEngine.h @@ -25,9 +25,6 @@ #pragma once -// TODO(#32628): Remove the CHIPCore.h header when the esp32 build is correctly fixed -#include - #include #include #include diff --git a/src/app/WriteHandler.cpp b/src/app/WriteHandler.cpp index 9847641b61d7f3..09a9ec0079e901 100644 --- a/src/app/WriteHandler.cpp +++ b/src/app/WriteHandler.cpp @@ -19,11 +19,15 @@ #include #include #include +#include +#include #include #include #include +#include #include #include +#include #include #include #include @@ -44,6 +48,8 @@ namespace app { namespace { +using Protocols::InteractionModel::Status; + /// Wraps a EndpointIterator and ensures that `::Release()` is called /// for the iterator (assuming it is non-null) class AutoReleaseGroupEndpointIterator @@ -754,6 +760,75 @@ void WriteHandler::MoveToState(const State aTargetState) ChipLogDetail(DataManagement, "IM WH moving to [%s]", GetStateStr()); } +DataModel::ActionReturnStatus WriteHandler::CheckWriteAllowed(const Access::SubjectDescriptor & aSubject, + const ConcreteAttributePath & aPath) +{ + // TODO: ordering is to check writability/existence BEFORE ACL and this seems wrong, however + // existing unit tests (TC_AcessChecker.py) validate that we get UnsupportedWrite instead of UnsupportedAccess + // + // This should likely be fixed in spec (probably already fixed by + // https://github.com/CHIP-Specifications/connectedhomeip-spec/pull/9024) + // and tests and implementation + // + // Open issue that needs fixing: https://github.com/project-chip/connectedhomeip/issues/33735 + + std::optional attributeEntry; + DataModel::AttributeFinder finder(mDataModelProvider); + + attributeEntry = finder.Find(aPath); + + // if path is not valid, return a spec-compliant return code. + if (!attributeEntry.has_value()) + { + // Global lists are not in metadata and not writable. Return the correct error code according to the spec + Status attributeErrorStatus = + IsSupportedGlobalAttributeNotInMetadata(aPath.mAttributeId) ? Status::UnsupportedWrite : Status::UnsupportedAttribute; + + return DataModel::ValidateClusterPath(mDataModelProvider, aPath, attributeErrorStatus); + } + + // Allow writes on writable attributes only + VerifyOrReturnValue(attributeEntry->writePrivilege.has_value(), Status::UnsupportedWrite); + + bool checkAcl = true; + if (mLastSuccessfullyWrittenPath.has_value()) + { + // only validate ACL if path has changed + // + // Note that this is NOT operator==: we could do `checkAcl == (aPath != *mLastSuccessfullyWrittenPath)` + // however that seems to use more flash. + if ((aPath.mEndpointId == mLastSuccessfullyWrittenPath->mEndpointId) && + (aPath.mClusterId == mLastSuccessfullyWrittenPath->mClusterId) && + (aPath.mAttributeId == mLastSuccessfullyWrittenPath->mAttributeId)) + { + checkAcl = false; + } + } + + if (checkAcl) + { + Access::RequestPath requestPath{ .cluster = aPath.mClusterId, + .endpoint = aPath.mEndpointId, + .requestType = Access::RequestType::kAttributeWriteRequest, + .entityId = aPath.mAttributeId }; + CHIP_ERROR err = Access::GetAccessControl().Check(aSubject, requestPath, RequiredPrivilege::ForWriteAttribute(aPath)); + + if (err != CHIP_NO_ERROR) + { + VerifyOrReturnValue(err != CHIP_ERROR_ACCESS_DENIED, Status::UnsupportedAccess); + VerifyOrReturnValue(err != CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL, Status::AccessRestricted); + + return err; + } + } + + // validate that timed write is enforced + VerifyOrReturnValue(IsTimedWrite() || !attributeEntry->flags.Has(DataModel::AttributeQualityFlags::kTimed), + Status::NeedsTimedInteraction); + + return Status::Success; +} + CHIP_ERROR WriteHandler::WriteClusterData(const Access::SubjectDescriptor & aSubject, const ConcreteDataAttributePath & aPath, TLV::TLVReader & aData) { @@ -761,16 +836,21 @@ CHIP_ERROR WriteHandler::WriteClusterData(const Access::SubjectDescriptor & aSub // the write is done via the DataModel interface VerifyOrReturnError(mDataModelProvider != nullptr, CHIP_ERROR_INCORRECT_STATE); - DataModel::WriteAttributeRequest request; + ChipLogDetail(DataManagement, "Writing attribute: Cluster=" ChipLogFormatMEI " Endpoint=0x%x AttributeId=" ChipLogFormatMEI, + ChipLogValueMEI(aPath.mClusterId), aPath.mEndpointId, ChipLogValueMEI(aPath.mAttributeId)); - request.path = aPath; - request.subjectDescriptor = &aSubject; - request.previousSuccessPath = mLastSuccessfullyWrittenPath; - request.writeFlags.Set(DataModel::WriteFlags::kTimed, IsTimedWrite()); + DataModel::ActionReturnStatus status = CheckWriteAllowed(aSubject, aPath); + if (status.IsSuccess()) + { + DataModel::WriteAttributeRequest request; - AttributeValueDecoder decoder(aData, aSubject); + request.path = aPath; + request.subjectDescriptor = &aSubject; + request.writeFlags.Set(DataModel::WriteFlags::kTimed, IsTimedWrite()); - DataModel::ActionReturnStatus status = mDataModelProvider->WriteAttribute(request, decoder); + AttributeValueDecoder decoder(aData, aSubject); + status = mDataModelProvider->WriteAttribute(request, decoder); + } mLastSuccessfullyWrittenPath = status.IsSuccess() ? std::make_optional(aPath) : std::nullopt; diff --git a/src/app/WriteHandler.h b/src/app/WriteHandler.h index fa1d324a5bd854..afb29b0a8fbb71 100644 --- a/src/app/WriteHandler.h +++ b/src/app/WriteHandler.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -185,6 +186,14 @@ class WriteHandler : public Messaging::ExchangeDelegate System::PacketBufferHandle && aPayload) override; void OnResponseTimeout(Messaging::ExchangeContext * apExchangeContext) override; + /// Validate that a write is acceptable on the given path. + /// + /// Validates that ACL, writability and Timed interaction settings are ok. + /// + /// Returns a success status if all is ok, failure otherwise. + DataModel::ActionReturnStatus CheckWriteAllowed(const Access::SubjectDescriptor & aSubject, + const ConcreteAttributePath & aPath); + // Write the given data to the given path CHIP_ERROR WriteClusterData(const Access::SubjectDescriptor & aSubject, const ConcreteDataAttributePath & aPath, TLV::TLVReader & aData); diff --git a/src/app/clusters/thermostat-server/thermostat-delegate.h b/src/app/clusters/thermostat-server/thermostat-delegate.h index 5f11ab59889430..b6158c2f9fca9b 100644 --- a/src/app/clusters/thermostat-server/thermostat-delegate.h +++ b/src/app/clusters/thermostat-server/thermostat-delegate.h @@ -120,7 +120,7 @@ class Delegate * 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. + * called when the Thermostat receives a AtomicRequest command of type CommitWrite 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. diff --git a/src/app/clusters/thermostat-server/thermostat-server-presets.cpp b/src/app/clusters/thermostat-server/thermostat-server-presets.cpp index 1dede071619962..96d2a7b716bf16 100644 --- a/src/app/clusters/thermostat-server/thermostat-server-presets.cpp +++ b/src/app/clusters/thermostat-server/thermostat-server-presets.cpp @@ -464,7 +464,7 @@ Status ThermostatAttrAccess::PrecommitPresets(EndpointId endpoint) if (err != CHIP_NO_ERROR) { ChipLogError(Zcl, - "emberAfThermostatClusterCommitPresetsSchedulesRequestCallback: GetPresetAtIndex failed with error " + "PrecommitPresets: GetPresetAtIndex failed with error " "%" CHIP_ERROR_FORMAT, err.Format()); return Status::InvalidInState; @@ -516,7 +516,7 @@ Status ThermostatAttrAccess::PrecommitPresets(EndpointId endpoint) if (err != CHIP_NO_ERROR) { ChipLogError(Zcl, - "emberAfThermostatClusterCommitPresetsSchedulesRequestCallback: GetPendingPresetAtIndex failed with error " + "PrecommitPresets: GetPendingPresetAtIndex failed with error " "%" CHIP_ERROR_FORMAT, err.Format()); return Status::InvalidInState; diff --git a/src/app/data-model-provider/MetadataLookup.cpp b/src/app/data-model-provider/MetadataLookup.cpp index a249b7e33caeed..cfbdb91e278edc 100644 --- a/src/app/data-model-provider/MetadataLookup.cpp +++ b/src/app/data-model-provider/MetadataLookup.cpp @@ -21,6 +21,8 @@ namespace chip { namespace app { namespace DataModel { +using Protocols::InteractionModel::Status; + std::optional ServerClusterFinder::Find(const ConcreteClusterPath & path) { VerifyOrReturnValue(mProvider != nullptr, std::nullopt); @@ -63,25 +65,6 @@ std::optional AttributeFinder::Find(const ConcreteAttributePath return std::nullopt; } -EndpointFinder::EndpointFinder(ProviderMetadataTree * provider) : mProvider(provider) -{ - VerifyOrReturn(mProvider != nullptr); - mEndpoints = mProvider->EndpointsIgnoreError(); -} - -std::optional EndpointFinder::Find(EndpointId endpointId) -{ - for (auto & endpointEntry : mEndpoints) - { - if (endpointEntry.id == endpointId) - { - return endpointEntry; - } - } - - return std::nullopt; -} - Protocols::InteractionModel::Status ValidateClusterPath(ProviderMetadataTree * provider, const ConcreteClusterPath & path, Protocols::InteractionModel::Status successStatus) { @@ -90,6 +73,7 @@ Protocols::InteractionModel::Status ValidateClusterPath(ProviderMetadataTree * p return successStatus; } + // If we get here, the cluster identified by the path does not exist. auto endpoints = provider->EndpointsIgnoreError(); for (auto & endpointEntry : endpoints) { diff --git a/src/app/data-model-provider/MetadataLookup.h b/src/app/data-model-provider/MetadataLookup.h index 7526bd32acc375..29ded483667c1d 100644 --- a/src/app/data-model-provider/MetadataLookup.h +++ b/src/app/data-model-provider/MetadataLookup.h @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -65,20 +66,14 @@ class AttributeFinder ReadOnlyBuffer mAttributes; }; -/// Helps search for a specific server endpoint in the given -/// metadata provider. +/// Validates that the cluster identified by `path` exists within the given provider. /// -/// Facilitates the operation of "find an endpoint with a given ID". -class EndpointFinder -{ -public: - EndpointFinder(ProviderMetadataTree * provider); - std::optional Find(EndpointId endpointId); - -private: - ProviderMetadataTree * mProvider; - ReadOnlyBuffer mEndpoints; -}; +/// If the endpoint identified by the path does not exist, will return Status::UnsupportedEndpoint. +/// If the endpoint exists but does not have the cluster identified by the path, will return Status::UnsupportedCluster. +/// +/// otherwise, it will return successStatus. +Protocols::InteractionModel::Status ValidateClusterPath(ProviderMetadataTree * provider, const ConcreteClusterPath & path, + Protocols::InteractionModel::Status successStatus); /// Validates that the cluster identified by `path` exists within the given provider. /// If the endpoint does not exist, will return Status::UnsupportedEndpoint. diff --git a/src/app/data-model-provider/OperationTypes.h b/src/app/data-model-provider/OperationTypes.h index 294bf2616435b4..35d1654ac12568 100644 --- a/src/app/data-model-provider/OperationTypes.h +++ b/src/app/data-model-provider/OperationTypes.h @@ -88,17 +88,6 @@ struct WriteAttributeRequest : OperationRequest { ConcreteDataAttributePath path; // NOTE: this also contains LIST operation options (i.e. "data" path type) BitFlags writeFlags; - - // The path of the previous successful write in the same write transaction, if any. - // - // In particular this means that a write to this path has succeeded before (i.e. it passed required ACL checks). - // The intent for this is to allow short-cutting ACL checks when ACL is in progress of being updated: - // - During write chunking, list writes can be of the form "reset list" followed by "append item by item" - // - When ACL is updating, a reset to empty would result in the entire ACL being deny and the "append" - // would fail. - // callers are expected to keep track of a `previousSuccessPath` whenever a write succeeds (otherwise ACL - // checks may fail) - std::optional previousSuccessPath; }; enum class InvokeFlags : uint32_t diff --git a/src/app/data-model-provider/Provider.h b/src/app/data-model-provider/Provider.h index 36a13d0eb810a3..fc5a204c869785 100644 --- a/src/app/data-model-provider/Provider.h +++ b/src/app/data-model-provider/Provider.h @@ -76,12 +76,7 @@ class Provider : public ProviderMetadataTree /// /// When this is invoked, caller is expected to have already done some validations: /// - cluster `data version` has been checked for the incoming request if applicable - /// - /// TEMPORARY/TRANSITIONAL requirement for transitioning from ember-specific code - /// WriteAttribute is REQUIRED to perform: - /// - 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) + /// - validation of ACL/timed interaction flags/writability, if those checks are desired. virtual ActionReturnStatus WriteAttribute(const WriteAttributeRequest & request, AttributeValueDecoder & decoder) = 0; /// `handler` is used to send back the reply. diff --git a/src/app/data-model-provider/ProviderMetadataTree.h b/src/app/data-model-provider/ProviderMetadataTree.h index 3b0820e6efb73e..8e7763dc489020 100644 --- a/src/app/data-model-provider/ProviderMetadataTree.h +++ b/src/app/data-model-provider/ProviderMetadataTree.h @@ -60,14 +60,14 @@ class ProviderMetadataTree virtual CHIP_ERROR ClientClusters(EndpointId endpointId, ListBuilder & builder) = 0; virtual CHIP_ERROR ServerClusters(EndpointId endpointId, ListBuilder & builder) = 0; - /// Attribute lists contain all attributes EXCEPT the list attributes that - /// are part of metadata. The output from this method MUST NOT contain: - /// - AttributeList::Id + /// Attribute lists contain all attributes. This MUST include all global + /// attributes (See SPEC 7.13 Global Elements / Global Attributes Table). + /// In particular this MUST contain: /// - AcceptedCommandList::Id - /// - GeneratedCommandList::Id - /// However it MUST ALWAYS contain: + /// - AttributeList::Id /// - ClusterRevision::Id /// - FeatureMap::Id + /// - GeneratedCommandList::Id virtual CHIP_ERROR Attributes(const ConcreteClusterPath & path, ListBuilder & builder) = 0; virtual CHIP_ERROR GeneratedCommands(const ConcreteClusterPath & path, ListBuilder & builder) = 0; virtual CHIP_ERROR AcceptedCommands(const ConcreteClusterPath & path, ListBuilder & builder) = 0; diff --git a/src/app/data-model-provider/tests/WriteTesting.h b/src/app/data-model-provider/tests/WriteTesting.h index 7651ffe37940f3..2ab3988ef8f739 100644 --- a/src/app/data-model-provider/tests/WriteTesting.h +++ b/src/app/data-model-provider/tests/WriteTesting.h @@ -60,12 +60,6 @@ class WriteOperation return *this; } - WriteOperation & SetPreviousSuccessPath(std::optional path) - { - mRequest.previousSuccessPath = path; - return *this; - } - WriteOperation & SetDataVersion(Optional version) { mRequest.path.mDataVersion = version; diff --git a/src/app/icd/server/BUILD.gn b/src/app/icd/server/BUILD.gn index e0d51689105d49..faa0cbe3f6945e 100644 --- a/src/app/icd/server/BUILD.gn +++ b/src/app/icd/server/BUILD.gn @@ -154,6 +154,8 @@ source_set("configuration-data") { "ICDConfigurationData.h", ] + public_deps = [ "${chip_root}/src/app/common:enums" ] + deps = [ ":icd-server-config", "${chip_root}/src/lib/core", diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp index fbcd9d302cf1ec..7b8654d2b2fb5b 100644 --- a/src/app/reporting/Engine.cpp +++ b/src/app/reporting/Engine.cpp @@ -52,20 +52,6 @@ namespace { using Protocols::InteractionModel::Status; -Status EventPathValid(DataModel::Provider * model, const ConcreteEventPath & eventPath) -{ - { - DataModel::ServerClusterFinder serverClusterFinder(model); - if (serverClusterFinder.Find(eventPath).has_value()) - { - return Status::Success; - } - } - - DataModel::EndpointFinder endpointFinder(model); - return endpointFinder.Find(eventPath.mEndpointId).has_value() ? Status::UnsupportedCluster : Status::UnsupportedEndpoint; -} - /// Returns the status of ACL validation. /// If the return value has a status set, that means the ACL check failed, /// the read must not be performed, and the returned status (which may @@ -530,7 +516,9 @@ CHIP_ERROR Engine::CheckAccessDeniedEventPaths(TLV::TLVWriter & aWriter, bool & } ConcreteEventPath path(current->mValue.mEndpointId, current->mValue.mClusterId, current->mValue.mEventId); - Status status = EventPathValid(mpImEngine->GetDataModelProvider(), path); + + // A event path is valid only if the cluster is valid + Status status = DataModel::ValidateClusterPath(mpImEngine->GetDataModelProvider(), path, Status::Success); if (status != Status::Success) { diff --git a/src/app/reporting/ReportScheduler.h b/src/app/reporting/ReportScheduler.h index d6425e34818c9a..05fc89f5b63c29 100644 --- a/src/app/reporting/ReportScheduler.h +++ b/src/app/reporting/ReportScheduler.h @@ -18,9 +18,6 @@ #pragma once -// TODO(#32628): Remove the CHIPCore.h header when the esp32 build is correctly fixed -#include - #include #include #include diff --git a/src/app/server/java/BUILD.gn b/src/app/server/java/BUILD.gn index deb85f7da22adc..f70157f65ce9c1 100644 --- a/src/app/server/java/BUILD.gn +++ b/src/app/server/java/BUILD.gn @@ -74,9 +74,9 @@ android_library("java") { javac_flags = [ "-Xlint:deprecation" ] # TODO: add classpath support (we likely need to add something like - # ..../platforms/android-26/android.jar to access BLE items) + # ..../platforms/android-30/android.jar to access BLE items) } java_prebuilt("android") { - jar_path = "${android_sdk_root}/platforms/android-26/android.jar" + jar_path = "${android_sdk_root}/platforms/android-30/android.jar" } diff --git a/src/app/tests/TestWriteInteraction.cpp b/src/app/tests/TestWriteInteraction.cpp index e0560ddecbc173..dfe01ee80ed7f1 100644 --- a/src/app/tests/TestWriteInteraction.cpp +++ b/src/app/tests/TestWriteInteraction.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,74 @@ chip::Credentials::GroupDataProviderImpl gGroupsProvider(kMaxGroupsPerFabric, kM namespace chip { namespace app { + +using namespace chip::Test; + +const MockNodeConfig & TestMockNodeConfig() +{ + using namespace Clusters::Globals::Attributes; + + // clang-format off + static const MockNodeConfig config({ + MockEndpointConfig(kRootEndpointId, { + MockClusterConfig(Clusters::IcdManagement::Id, { + ClusterRevision::Id, FeatureMap::Id, + Clusters::IcdManagement::Attributes::OperatingMode::Id, + }), + }), + MockEndpointConfig(kTestEndpointId, { + MockClusterConfig(Clusters::UnitTesting::Id, { + ClusterRevision::Id, FeatureMap::Id, + Clusters::UnitTesting::Attributes::Boolean::Id, + Clusters::UnitTesting::Attributes::Int16u::Id, + Clusters::UnitTesting::Attributes::ListFabricScoped::Id, + Clusters::UnitTesting::Attributes::ListStructOctetString::Id, + }), + }), + MockEndpointConfig(kMockEndpoint1, { + MockClusterConfig(MockClusterId(1), { + ClusterRevision::Id, FeatureMap::Id, + }, { + MockEventId(1), MockEventId(2), + }), + MockClusterConfig(MockClusterId(2), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), + }), + }), + MockEndpointConfig(kMockEndpoint2, { + MockClusterConfig(MockClusterId(1), { + ClusterRevision::Id, FeatureMap::Id, + }), + MockClusterConfig(MockClusterId(2), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), MockAttributeId(2), + }), + MockClusterConfig(MockClusterId(3), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), MockAttributeId(2), MockAttributeId(3), + }), + }), + MockEndpointConfig(kMockEndpoint3, { + MockClusterConfig(MockClusterId(1), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), + }), + MockClusterConfig(MockClusterId(2), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), MockAttributeId(2), MockAttributeId(3), MockAttributeId(4), + }), + MockClusterConfig(MockClusterId(3), { + ClusterRevision::Id, FeatureMap::Id, + }), + MockClusterConfig(MockClusterId(4), { + ClusterRevision::Id, FeatureMap::Id, + }), + }), + /// For `TestWriteRoundtripWithClusterObjects` where path 2/3/4 is used + MockEndpointConfig(2, { + MockClusterConfig(3, {4}), + }) + }); + // clang-format on + return config; +} + class TestWriteInteraction : public chip::Test::AppContext { public: @@ -72,9 +141,11 @@ class TestWriteInteraction : public chip::Test::AppContext ASSERT_EQ(chip::GroupTesting::InitData(&gGroupsProvider, GetBobFabricIndex(), span), CHIP_NO_ERROR); mOldProvider = InteractionModelEngine::GetInstance()->SetDataModelProvider(&TestImCustomDataModel::Instance()); + chip::Test::SetMockNodeConfig(TestMockNodeConfig()); } void TearDown() override { + chip::Test::ResetMockNodeConfig(); InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider); chip::Credentials::GroupDataProvider * provider = chip::Credentials::GetGroupDataProvider(); if (provider != nullptr) diff --git a/src/app/tests/suites/certification/Test_TC_DLOG_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DLOG_2_1.yaml index cedff5b8987fdd..a7d2588e9da193 100644 --- a/src/app/tests/suites/certification/Test_TC_DLOG_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DLOG_2_1.yaml @@ -120,6 +120,7 @@ tests: The current SDK implementation stores log files transferred via the BDX protocol in the /tmp folder. if {PICS_MCORE_DLOG_S_UTCTIMESTAMP} then verify that UTCTimeStamp is included in the RetrieveLogsResponse command if {PICS_MCORE_DLOG_S_TIMESINCEBOOT} then verify that TimeSinceBoot is included in the RetrieveLogsResponse command + disabled: true - label: "Step 4: if (SendInitMsgfromDUT = false) TH does not send BDX @@ -318,7 +319,7 @@ tests: If SendInitMsgfromDUT = false proceed with the following validation: 1. Verification: - On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with Exhausted(1) status code to TH and LogContent field of RetrieveLogsResponse contains at most 1024 bytes + On TH(chip-tool), verify that the DUT responds by sending RetrieveLogsResponse Command with Exhausted(1) status code to TH and LogContent field of RetrieveLogsResponse contains at most 1024 bytes [1725363236.448] [56032:56034] [DMG] Received Command Response Data, Endpoint=0 Cluster=0x0000_0032 Command=0x0000_0001 [1725363236.449] [56032:56034] [TOO] Endpoint: 0 Cluster: 0x0000_0032 Command 0x0000_0001 @@ -466,7 +467,6 @@ tests: [1707967219.637242][10723:10726] CHIP:TOO: status: 2 [1707967219.637248][10723:10726] CHIP:TOO: logContent: [1707967219.637253][10723:10726] CHIP:TOO: } - disabled: true - label: diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_2_2.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_2_2.yaml deleted file mode 100644 index 11be3889e4d9f7..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_2_2.yaml +++ /dev/null @@ -1,2005 +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. - -name: 42.2.2. [TC-TSTAT-2.2] Setpoint Test Cases 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 2a read MinCoolSetpointLimit" - PICS: TSTAT.S.A0017 - command: "readAttribute" - attribute: "MinCoolSetpointLimit" - response: - saveAs: MinCoolSetpointLimitValue - - - label: "Saving value for comparision in step 2a read MaxCoolSetpointLimit" - PICS: TSTAT.S.A0018 - command: "readAttribute" - attribute: "MaxCoolSetpointLimit" - response: - saveAs: MaxCoolSetpointLimitValue - - - label: - "Saving value for comparision in step 2c read attribute - MinSetpointDeadBand" - PICS: TSTAT.S.A0019 - command: "readAttribute" - attribute: "MinSetpointDeadBand" - response: - saveAs: MinSetpointDeadBandValue - - - label: "Saving value for comparision in step 3a read MinHeatSetpointLimit" - PICS: TSTAT.S.A0015 - command: "readAttribute" - attribute: "MinHeatSetpointLimit" - response: - saveAs: MinHeatSetpointLimitValue - - - label: - "Saving value for comparision in step 3 reads - UnoccupiedCoolingSetpoint attribute" - command: "readAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.A0013 - response: - saveAs: UnoccupiedCoolingSetpointValue - - - label: "Saving value for comparision in step 3a read MaxHeatSetpointLimit" - PICS: TSTAT.S.A0016 - command: "readAttribute" - attribute: "MaxHeatSetpointLimit" - response: - saveAs: MaxHeatSetpointLimitValue - - - label: - "Saving value for comparision in step3c read attribute - OccupiedHeatingSetpoint" - PICS: TSTAT.S.A0012 - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - response: - saveAs: OccupiedHeatingSetpointValue - - - label: - "Saving value for comparision in step3c read attribute - OccupiedCoolingSetpoint" - PICS: TSTAT.S.A0011 - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - response: - saveAs: OccupiedCoolingSetpointValue - - - label: - "Saving value for comparision in step 6a read attribute - AbsMinHeatSetpointLimit" - command: "readAttribute" - attribute: "AbsMinHeatSetpointLimit" - PICS: TSTAT.S.A0003 - response: - saveAs: AbsMinHeatSetpointLimitValue - - - label: - "Saving value for comparision in step 7a read attribute - AbsMaxHeatSetpointLimit" - command: "readAttribute" - attribute: "AbsMaxHeatSetpointLimit" - PICS: TSTAT.S.A0004 - response: - saveAs: AbsMaxHeatSetpointLimitValue - - - label: - "Saving value for comparision in step 8a read attribute - AbsMinCoolSetpointLimit" - command: "readAttribute" - attribute: "AbsMinCoolSetpointLimit" - PICS: TSTAT.S.A0005 - response: - saveAs: AbsMinCoolSetpointLimitValue - - - label: - "Saving value for comparision in step9a read attribute - AbsMaxCoolSetpointLimit" - command: "readAttribute" - attribute: "AbsMaxCoolSetpointLimit" - PICS: TSTAT.S.A0006 - response: - saveAs: AbsMaxCoolSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 2a: Test Harness Client reads attribute OccupiedCoolingSetpoint - from the DUT" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - response: - constraints: - type: int16s - minValue: MinCoolSetpointLimitValue - maxValue: MaxCoolSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 2a: Test Harness Client reads OccupiedCoolingSetpoint attribute - from Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.A0017 && !TSTAT.S.A0018 - response: - constraints: - type: int16s - minValue: 1600 - maxValue: 3200 - - - label: - "Step 2a: Test Harness Client then attempts Writes a value back that - is different but valid for OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2500 - - - label: - "Step 2a: Test Harness Client reads it back again to confirm the - successful write of OccupiedCoolingSetpoint attribute" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2500 - - - label: - "Step 2b: Test Harness Client then attempts Writes - OccupiedCoolingSetpoint to value below the MinCoolSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.A0017 - arguments: - value: 30 - response: - error: CONSTRAINT_ERROR - - #MinCoolSetPointLimit might be negative if not checked before decrement - - label: - "Step 2b: Test Harness Writes OccupiedCoolingSetpoint to value below - the MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #2 Test Harness Client attempts to write OccupiedCoolingSetpoint below the MinCoolSetpointLimit and confirms that the device does not accept the value. - ./chip-tool thermostat write occupied-cooling-setpoint 1000 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) for the value which is below of the MinCoolSetpointLimitValue - - [1676028984.901635][19375:19377] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676028984.901706][19375:19377] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676028984.901895][19375:19377] CHIP:EM: <<< [E:18153i M:141749864 (Ack:137408936)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1676028984.901980][19375:19377] CHIP:IN: (S) Sending msg 141749864 on secure session with LSID: 58847 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 2b: Test Harness Writes OccupiedCoolingSetpoint to value above - the MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.A0017 - arguments: - value: 4000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 2b: Test Harness Writes OccupiedCoolingSetpoint to value above - the MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - arguments: - value: MaxCoolSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 2c: Test Harness Writes the limit of MaxCoolSetpointLimit to - OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.A0017 - arguments: - value: 3200 - - - label: - "Step 2c: Test Harness Writes the limit of MaxCoolSetpointLimit to - OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - arguments: - value: MaxCoolSetpointLimitValue - - - label: - "Step 2c: Test Harness Writes the limit of MinCoolSetpointLimit to - OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.F05 && !TSTAT.S.A0017 - arguments: - value: 1600 - - - label: - "Step 2c: Test Harness Writes the limit of MinCoolSetpointLimit to - OccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 && !TSTAT.S.F05 && TSTAT.S.A0017 - arguments: - value: MinCoolSetpointLimitValue - - #LowerLimit = Max(MinCoolSetpointLimit,(OccupiedHeatingSetpoint + MinSetpointDeadBand)) not possible in YAML - - label: - "Step 2c: Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = - Max(MinCoolSetpointLimit, (OccupiedHeatingSetpoint + - MinSetpointDeadBand)) to OccupiedCoolingSetpoint attribute when Auto - is enabled" - PICS: TSTAT.S.F05 && TSTAT.S.A0011 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - Test Harness Client then attempts to write OccupiedCoolingSetpoint to both of the limits of LowerLimit(1600) & MaxCoolSetpointLimit(3200) and confirms that the device does accept the value. See also Note 5. - - ./chip-tool thermostat write occupied-cooling-setpoint 1600 1 1 - On TH(chip-tool) verify that DUT sends a success response - [1676029009.026653][19381:19383] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029009.026688][19381:19383] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029009.026776][19381:19383] CHIP:EM: <<< [E:29492i M:142792974 (Ack:241003612)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - #Using saved values when optional attributes are available - - label: - "Step 3a: Test Harness Reads OccupiedHeatingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: MinHeatSetpointLimitValue - maxValue: MaxHeatSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 3a: Test Harness Reads OccupiedHeatingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.A0015 && !TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: 700 - maxValue: 3000 - - - label: - "Step 3a: Test Harness Writes a value back that is different but - valid for OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2100 - - - label: - "Step 3a: Test Harness Reads it back again to confirm the successful - write of OccupiedHeatingSetpoint attribute" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 2100 - - - label: - "Step 3b: Test Harness Writes OccupiedHeatingSetpoint to value below - the MinHeatSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.A0015 - arguments: - value: 100 - response: - error: CONSTRAINT_ERROR - - #MinHeatSetpointLimit might be negative if not checked before decrement - - label: - "Step 3b: Test Harness Writes OccupiedHeatingSetpoint to value below - the MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write OccupiedHeatingSetpoint below the MinHeatSetpointLimit and confirms that the device does not accept the value - - ./chip-tool thermostat write occupied-heating-setpoint 500 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676029113.651245][19392:19394] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029113.651285][19392:19394] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029113.651397][19392:19394] CHIP:EM: <<< [E:43315i M:59735604 (Ack:107613834)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3b: Test Harness Writes OccupiedHeatingSetpoint to value above - the MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.A0016 - arguments: - value: 4010 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 3b: Test Harness Writes OccupiedHeatingSetpoint to value above - the MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 3c: Test Harness Writes the limit of MaxHeatSetpointLimit to - OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.F05 && !TSTAT.S.A0016 - arguments: - value: 3000 - - - label: - "Step 3c: Test Harness Writes the limit of MaxHeatSetpointLimit to - OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.F05 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue - - - label: - "Step 3c: Test Harness Writes the limit of MaxHeatSetpointLimit to - OccupiedHeatingSetpoint attribute If TSTAT.S.F05 is true" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F05 && !TSTAT.S.A0015 - arguments: - value: 3000 - response: - error: CONSTRAINT_ERROR - - #UpperLimit = Min(MaxHeatSetpointLimit,(OccupiedCoolingSetpoint - MinSetpointDeadBand)) not possible in YAML - - label: - "Step 3c: Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = - Min(MaxHeatSetpointLimit, (OccupiedCoolingSetpoint - - MinSetpointDeadBand)) to OccupiedHeatingSetpoint attribute when Auto - is enabled" - PICS: - TSTAT.S.F05 && TSTAT.S.A0011 && TSTAT.S.A0012 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - Test Harness Client then attempts to write OccupiedHeatingSetpoint to both of the limits of MinHeatSetpointLimit(700) & UpperLimit(3000) and confirms that the device does accept the value. - - ./chip-tool thermostat write occupied-heating-setpoint 3000 1 1 - - On TH(chip-tool) verify that DUT sends a success response - 1676029222.303920][19403:19405] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029222.303955][19403:19405] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029222.304055][19403:19405] CHIP:EM: <<< [E:236i M:251820549 (Ack:138263425)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 - - ./chip-tool thermostat write occupied-heating-setpoint 700 1 1 - On TH(chip-tool) verify that DUT sends a success response - - - [1678943387.942204][770598:770600] CHIP:DMG: StatusIB = - [1678943387.942212][770598:770600] CHIP:DMG: { - [1678943387.942220][770598:770600] CHIP:DMG: status = 0x00 (SUCCESS), - [1678943387.942228][770598:770600] CHIP:DMG: }, - [1678943387.942236][770598:770600] CHIP:DMG: - [1678943387.942243][770598:770600] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 3c: Test Harness Writes the limit of MinHeatSetpointLimit to - OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && !TSTAT.S.A0015 - arguments: - value: 700 - - - label: - "Step 3c: Test Harness Writes the limit of MinHeatSetpointLimit to - OccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - arguments: - value: MinHeatSetpointLimitValue - - - label: - "Step 4a: Test Harness Reads UnoccupiedCoolingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 - response: - constraints: - type: int16s - minValue: MinCoolSetpointLimitValue - maxValue: MaxCoolSetpointLimitValue - - - label: - "Step 4a: Test Harness Reads UnoccupiedCoolingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0017 && !TSTAT.S.A0018 - response: - constraints: - type: int16s - minValue: 1600 - maxValue: 3200 - - - label: - "Step 4a: Test Harness Writes a value back that is different but - valid for UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 - arguments: - value: 2500 - - - label: - "Step 4a: Test Harness Reads it back again to confirm the successful - write of UnoccupiedCoolingSetpoint attribute" - command: "readAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 - response: - value: 2500 - - - label: - "Step 4b: Test Harness Writes UnoccupiedCoolingSetpoint to value - below the MinCoolSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0017 - arguments: - value: 500 - response: - error: CONSTRAINT_ERROR - - #MinCoolSetpointLimit might be negative if not checked before decrement - - label: - "Step 4b: Test Harness Writes UnoccupiedCoolingSetpoint to value - below the MinCoolSetpointLimit" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0017 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write OccupiedHeatingSetpoint below the MinHeatSetpointLimit and confirms that the device does not accept the value - - ./chip-tool thermostat write unoccupied-cooling-setpoint 500 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676029263.842915][19409:19411] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029263.842943][19409:19411] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029263.843052][19409:19411] CHIP:EM: <<< [E:47350i M:72320003 (Ack:188090912)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 4b: Test Harness Writes UnoccupiedCoolingSetpoint to value - above the MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0018 - arguments: - value: 4010 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 4b: Test Harness Writes UnoccupiedCoolingSetpoint to value - above the MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0018 - arguments: - value: MaxCoolSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 4c: Test Harness Writes the limit of MaxCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0018 && !TSTAT.S.F05 - arguments: - value: 3200 - - - label: - "Step 4c: Test Harness Writes the limit of MaxCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.F05 - arguments: - value: MaxCoolSetpointLimitValue - - #LowerLimit = Max(MinCoolSetpointLimit,(UnoccupiedCoolingSetpoint + MinSetpointDeadBand)) not possible in YAML - - label: - "Step 4c: Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = - Max(MinCoolSetpointLimit, (UnoccupiedCoolingSetpoint + - MinSetpointDeadBand)) to UnoccupiedCoolingSetpoint attribute" - PICS: - TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0013 && TSTAT.S.F05 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - - below mentioned the example command to verify - - ./chip-tool thermostat write unoccupied-cooling-setpoint 2000 1 1 - On TH(chip-tool) verify that DUT sends a success response. As its an optional attribute, we are not getting expected result - [1676029365.250210][19420:19422] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029365.250263][19420:19422] CHIP:TOO: Response Failure: IM Error 0x00000586: General error: 0x86 (UNSUPPORTED_ATTRIBUTE) - [1676029365.250403][19420:19422] CHIP:EM: <<< [E:16230i M:267641165 (Ack:117850882)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1676029365.250467][19420:19422] CHIP:IN: (S) Sending msg 267641165 on secure session with LSID: 45606 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 4c: Test Harness Writes the limit of MinCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0017 && !TSTAT.S.F05 - arguments: - value: 1600 - - - label: - "Step 4c: Test Harness Writes the limit of MinCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && !TSTAT.S.A0017 && TSTAT.S.F05 - arguments: - value: 1600 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 4c: Test Harness Writes the limit of MinCoolSetpointLimit to - UnoccupiedCoolingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedCoolingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.F05 - arguments: - value: MinCoolSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 5a: Test Harness Reads UnoccupiedHeatingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: MinHeatSetpointLimitValue - maxValue: MaxHeatSetpointLimitValue - - #Using hardcoded values when optional attributes are not available - - label: - "Step 5a: Test Harness Reads UnoccupiedHeatingSetpoint attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0015 && !TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: 700 - maxValue: 3000 - - - label: - "Step 5a: Test Harness Writes a value back that is different but - valid for UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 - arguments: - value: 2500 - - - label: - "Step 5a: Test Harness Reads it back again to confirm the successful - write of UnoccupiedHeatingSetpoint attribute" - command: "readAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 - response: - value: 2500 - - - label: - "Step 5b: Test Harness Writes UnoccupiedHeatingSetpoint to value - below the MinHeatSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0015 - arguments: - value: 100 - response: - error: CONSTRAINT_ERROR - - #MinHeatSetpointLimit might be negative if not checked before decrement - - label: - "Step 5b: Test Harness Writes UnoccupiedHeatingSetpoint to value - below the MinHeatSetpointLimit" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0015 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write UnoccupiedHeatingSetpoint below the MinHeatSetpointLimit and confirms that the device does not accept the value - - ./chip-tool thermostat write unoccupied-heating-setpoint 500 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87). As its an optional attribute, we are not getting expected result - - [1676029557.268065][19431:19433] CHIP:DMG: } - [1676029557.268220][19431:19433] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029557.268290][19431:19433] CHIP:TOO: Response Failure: IM Error 0x00000586: General error: 0x86 (UNSUPPORTED_ATTRIBUTE) - [1676029557.268470][19431:19433] CHIP:EM: <<< [E:8458i M:31631638 (Ack:115187982)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 5b: Test Harness Writes UnoccupiedHeatingSetpoint to value - above the MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0016 - arguments: - value: 4010 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 5b: Test Harness Writes UnoccupiedHeatingSetpoint to value - above the MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 5c: Test Harness Writes the limit of MaxHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0016 && !TSTAT.S.F05 - arguments: - value: 3000 - - - label: - "Step 5c: Test Harness Writes the limit of MaxHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 - arguments: - value: MaxHeatSetpointLimitValue - - - label: - "Step 5c: Test Harness Writes the limit of MaxHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0016 && TSTAT.S.F05 - arguments: - value: 3000 - response: - error: CONSTRAINT_ERROR - - #UpperLimit = Min(MaxHeatSetpointLimit,(UnoccupiedCoolingSetpoint - MinSetpointDeadBand)) not possible in YAML - - label: - "Step 5c: Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = - Min(MaxHeatSetpointLimit, (UnoccupiedCoolingSetpoint - - MinSetpointDeadBand)) to UnoccupiedHeatingSetpoint attribute when Auto - is enabled." - PICS: - TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0013 && TSTAT.S.F05 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - - below mentioned the example command to verify - - ./chip-tool thermostat write unoccupied-heating-setpoint 2000 1 1 - On TH(chip-tool) verify that DUT sends a success response. As its an optional attribute, we are not getting expected result - - [1676029629.242182][19437:19439] CHIP:DMG: } - [1676029629.242250][19437:19439] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029629.242280][19437:19439] CHIP:TOO: Response Failure: IM Error 0x00000586: General error: 0x86 (UNSUPPORTED_ATTRIBUTE) - [1676029629.242366][19437:19439] CHIP:EM: <<< [E:51650i M:149591010 (Ack:214538556)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1676029629.242402][19437:19439] CHIP:IN: (S) Sending msg 149591010 on secure session with LSID: 6132 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 5c: Test Harness Writes the limit of MinHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && !TSTAT.S.A0015 - arguments: - value: 700 - - - label: - "Step 5c: Test Harness Writes the limit of MinHeatSetpointLimit to - UnoccupiedHeatingSetpoint attribute" - command: "writeAttribute" - attribute: "UnoccupiedHeatingSetpoint" - PICS: TSTAT.S.F02 && TSTAT.S.F00 && TSTAT.S.A0015 - arguments: - value: MinHeatSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 6a: Test Harness Reads MinHeatSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0016 && TSTAT.S.A0003 - response: - constraints: - type: int16s - minValue: AbsMinHeatSetpointLimitValue - maxValue: MaxHeatSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 6a: Test Harness Reads MinHeatSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0016 && !TSTAT.S.A0003 - response: - constraints: - type: int16s - minValue: 700 - maxValue: 3000 - - - label: - "Step 6a: Test Harness Writes a value back that is different but valid - for MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - arguments: - value: 800 - - - label: - "Step 6a: Test Harness Reads it back again to confirm the successful - write of MinHeatSetpointLimit attribute" - command: "readAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - response: - value: 800 - - - label: - "Step 6b: Test Harness Writes a value back that is different but - violates the deadband" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.A0015 && TSTAT.S.F05 - arguments: - value: 2000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 6b: Test Harness Writes MinHeatSetpointLimit to value below the - AbsMinHeatSetpointLimit " - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0003 - arguments: - value: 100 - response: - error: CONSTRAINT_ERROR - - #AbsMinHeatSetpointLimit might be negative if not checked before decrement - - label: - "Step 6b: Test Harness Writes MinHeatSetpointLimit to value below the - AbsMinHeatSetpointLimit " - PICS: - TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0003 && PICS_SKIP_SAMPLE_APP - verification: | - #1. Test Harness Client attempts to write MinHeatSetpointLimit below the AbsMinHeatSetpointLimit and confirms that the device does not accept the value. - ./chip-tool thermostat write min-heat-setpoint-limit 300 1 1 - On TH (chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676029705.839179][19450:19452] CHIP:DMG: } - [1676029705.839253][19450:19452] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029705.839287][19450:19452] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029705.839411][19450:19452] CHIP:EM: <<< [E:34538i M:185292291 (Ack:127655640)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1676029705.839456][19450:19452] CHIP:IN: (S) Sending msg 185292291 on secure session with LSID: 61694 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 6b: Test Harness Writes MinHeatSetpointLimit to value above the - AbsMaxHeatSetpointLimit " - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0016 - arguments: - value: 4050 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 6b: Test Harness Writes MinHeatSetpointLimit to value above the - AbsMaxHeatSetpointLimit " - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 6c: Test Harness Writes the limit of MaxHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.F05 && !TSTAT.S.A0016 - arguments: - value: 3000 - - - label: - "Step 6c: Test Harness Writes the limit of MaxHeatSetpointLimit to - MinHeatSetpointimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.F05 && TSTAT.S.A0016 - arguments: - value: MaxHeatSetpointLimitValue - - #UpperLimit = Min(MaxHeatSetpointLimit,(MinCoolSetpointLimit - MinSetpointDeadBand)) not possible in YAML - - label: - "Step 6c: Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = - Min(MaxHeatSetpointLimit, (MinCoolSetpointLimit - - MinSetpointDeadBand)) to MinHeatSetpointLimit attribute when Auto is - enabled" - PICS: - TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.F05 && TSTAT.S.A0005 && - PICS_SKIP_SAMPLE_APP - verification: | - Test Harness Client then attempts to write MinHeatSetpointLimit to both of the limits of AbsMinHeatSetpointLimit & UpperLimit and confirms that the device does accept the value. - below is an exaple command. - - ./chip-tool thermostat write min-heat-setpoint-limit 1200 1 1 - - On TH(chip-tool) verify that DUT sends a success response - - [1676029742.329801][19458:19460] CHIP:DMG: } - [1676029742.329846][19458:19460] CHIP:DMG: - [1676029742.329883][19458:19460] CHIP:DMG: StatusIB = - [1676029742.329922][19458:19460] CHIP:DMG: { - [1676029742.329962][19458:19460] CHIP:DMG: status = 0x00 (SUCCESS), - [1676029742.330001][19458:19460] CHIP:DMG: }, - [1676029742.330040][19458:19460] CHIP:DMG: - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 6c: Test Harness Writes the limit of AbsMinHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0003 - arguments: - value: 700 - - - label: - "Step 6c: Test Harness Writes the limit of AbsMinHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0003 - arguments: - value: AbsMinHeatSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 7a: Test Harness Reads MaxHeatSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: - TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && TSTAT.S.A0004 && - TSTAT.S.A0016 - response: - constraints: - type: int16s - minValue: MinHeatSetpointLimitValue - maxValue: AbsMaxHeatSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 7a: Test Harness Reads MaxHeatSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: - " TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && !TSTAT.S.A0004 && - !TSTAT.S.A0016 " - response: - constraints: - type: int16s - minValue: 700 - maxValue: 3000 - - - label: - "Step 7b: Test Harness Writes the limit of AbsMinHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - arguments: - value: 700 - - - label: - "Step 7b: Test Harness Writes the limit of AbsMaxHeatSetpointLimit to - MinHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.A0015 && TSTAT.S.F05 - arguments: - value: 3000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 7b: Test Harness Writes a value back that is different but valid - for MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 - arguments: - value: 2900 - - - label: - "Step 7b: Test Harness Reads it back again to confirm the successful - write of MaxHeatSetpointLimit attribute" - command: "readAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 - response: - value: 2900 - - - label: - "Step 7b: Test Harness Writes MaxHeatSetpointLimit to value below the - AbsMinHeatSetpointLimit " - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.A0015 - arguments: - value: 100 - response: - error: CONSTRAINT_ERROR - - #MinHeatSetpointLimit might be negative if not checked before decrement - - label: - "Step 7b: Test Harness Writes MaxHeatSetpointLimit to value below the - MinHeatSetpointLimit" - PICS: - TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.A0015 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write MaxHeatSetpointLimit below the MinHeatSetpointLimit and confirms that the device does not accept the value. - ./chip-tool thermostat write max-heat-setpoint-limit 100 1 1 - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676029976.380552][19475:19477] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676029976.380598][19475:19477] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676029976.380705][19475:19477] CHIP:EM: <<< [E:10254i M:97110781 (Ack:264765613)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 7b: Test Harness Writes MaxHeatSetpointLimit to value above the - AbsMaxHeatSetpointLimit " - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.A0004 - arguments: - value: 4000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 7b: Test Harness Writes MaxHeatSetpointLimit to value above the - AbsMaxHeatSetpointLimit " - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.A0004 - arguments: - value: AbsMaxHeatSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 7c: Test Harness Writes the limit of AbsMaxHeatSetpointLimit to - MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && !TSTAT.S.A0004 - arguments: - value: 3000 - - - label: - "Step 7c: Test Harness Writes the limit of AbsMaxHeatSetpointLimit to - MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && TSTAT.S.A0004 - arguments: - value: AbsMaxHeatSetpointLimitValue - - #UpperLimit = Min(AbsMaxHeatSetpointLimit,(MaxCoolSetpointLimit - MinSetpointDeadBand)) not possible in YAML - - label: - "Step 7c: Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = - Min(AbsMaxHeatSetpointLimit, (MaxCoolSetpointLimit - - MinSetpointDeadBand)) to MaxHeatSetpointLimit attribute" - PICS: - TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.F05 && TSTAT.S.A0018 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation - - Test Harness Client then attempts to write MaxHeatSetpointLimit to both of the limits of MinHeatSetpointLimit & UpperLimit and confirms that the device does accept the value. - - below is an examble command - - ./chip-tool thermostat write max-heat-setpoint-limit 2000( Consider the different value but valid4) 1 1 - On TH(chip-tool) verify that DUT sends a success response - - [1676030018.852009][19481:19483] CHIP:DMG: Cluster = 0x201, - [1676030018.852054][19481:19483] CHIP:DMG: Attribute = 0x0000_0016, - [1676030018.852094][19481:19483] CHIP:DMG: } - [1676030018.852138][19481:19483] CHIP:DMG: - [1676030018.852178][19481:19483] CHIP:DMG: StatusIB = - [1676030018.852218][19481:19483] CHIP:DMG: { - [1676030018.852258][19481:19483] CHIP:DMG: status = 0x00 (SUCCESS), - [1676030018.852297][19481:19483] CHIP:DMG: }, - [1676030018.852337][19481:19483] CHIP:DMG: - [1676030018.852370][19481:19483] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 7c: Test Harness Writes the limit of MinHeatSetpointLimit to - MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.A0015 - arguments: - value: 700 - - - label: - "Step 7c: Test Harness Writes the limit of MinHeatSetpointLimit to - MaxHeatSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.A0015 - arguments: - value: MinHeatSetpointLimitValue - - #Using saved values when optional attributes are available - - label: - "Step 8a: Test Harness Reads MinCoolSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 && TSTAT.S.A0005 - response: - constraints: - type: int16s - minValue: AbsMinCoolSetpointLimitValue - maxValue: MaxCoolSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 8a: Test Harness Reads MinCoolSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0018 && !TSTAT.S.A0005 - response: - constraints: - type: int16s - minValue: 1600 - maxValue: 3200 - - - label: - "Step 8a: Test Harness Writes a value back that is different but valid - for MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - arguments: - value: 2000 - - - label: - "Step 8a: Test Harness Reads it back again to confirm the successful - write of MinCoolSetpointLimit attribute" - command: "readAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - response: - value: 2000 - - - label: - "Step 8b: Test Harness Writes MinCoolSetpointLimit to value below the - AbsMinCoolSetpointLimit " - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0005 - arguments: - value: 500 - response: - error: CONSTRAINT_ERROR - - #AbsMinCoolSetpointLimit might be negative if not checked before decrement - - label: - "Step 8b: Test Harness Writes MinCoolSetpointLimit to value below the - AbsMinCoolSetpointLimit" - PICS: - TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0005 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client then attempts to write MinCoolSetpointLimit below the AbsMinCoolSetpointLimit and confirms that the device does not accept the value. - - ./chip-tool thermostat write min-cool-setpoint-limit 400 1 1 - - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676030095.274876][19495:19497] CHIP:DMG: } - [1676030095.274936][19495:19497] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676030095.274965][19495:19497] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676030095.275097][19495:19497] CHIP:EM: <<< [E:51146i M:60043723 (Ack:28649429)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - label: - "Step 8b: Test Harness Writes MinCoolSetpointLimit to value above the - MaxCoolSetpointLimit " - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0018 - arguments: - value: 4000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 8b: Test Harness Writes MinCoolSetpointLimit to value above the - MaxCoolSetpointLimit " - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 - arguments: - value: MaxCoolSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 8c: Test Harness Writes the limit of MaxCoolSetpointLimit to - MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0018 - arguments: - value: 3200 - - - label: - "Step 8c: Test Harness Writes the limit of MaxCoolSetpointLimit to - MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0018 - arguments: - value: MaxCoolSetpointLimitValue - - - label: - "Step 8c: Test Harness Writes the limit of AbsMinCoolSetpointLimit to - MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0005 && !TSTAT.S.F05 - arguments: - value: 1600 - - - label: - "Step 8c: Test Harness Writes the limit of AbsMinCoolSetpointLimit to - MinCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0005 && !TSTAT.S.F05 - arguments: - value: AbsMinCoolSetpointLimitValue - - #LowerLimit = Max(AbsMinCoolSetpointLimit,(MinHeatSetpointLimit + MinSetpointDeadBand)) not possible in YAML - - label: - "Step 8c: Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = - Max(AbsMinCoolSetpointLimit, (MinHeatSetpointLimit + - MinSetpointDeadBand)) to MinCoolSetpointLimit attribute" - PICS: - TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0015 && TSTAT.S.F05 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - Test Harness Client then attempts to write MinCoolSetpointLimit to both of the limits of LowerLimit & MaxCoolSetpointLimit and confirms that the device does accept the value. - - ./chip-tool thermostat write min-cool-setpoint-limit 1600 1 1 - - On TH(chip-tool) verify that DUT sends a success response - - [1678947233.814534][773656:773658] CHIP:DMG: - [1678947233.814541][773656:773658] CHIP:DMG: StatusIB = - [1678947233.814548][773656:773658] CHIP:DMG: { - [1678947233.814555][773656:773658] CHIP:DMG: status = 0x00 (SUCCESS), - [1678947233.814562][773656:773658] CHIP:DMG: }, - [1678947233.814570][773656:773658] CHIP:DMG: - [1678947233.814576][773656:773658] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - #Using saved values when optional attributes are available - - label: - "Step 9a: Test Harness Reads MaxCoolSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0017 && TSTAT.S.A0006 - response: - constraints: - type: int16s - minValue: MinCoolSetpointLimitValue - maxValue: AbsMaxCoolSetpointLimitValue - - #Using hard coded values when optional attributes are not available - - label: - "Step 9a: Test Harness Reads MaxCoolSetpointLimit attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0017 && !TSTAT.S.A0006 - response: - constraints: - type: int16s - minValue: 1600 - maxValue: 3200 - - - label: - "Step 9a: Test Harness Writes a value back that is different but valid - for MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.F05 - arguments: - value: 2000 - - - label: - "Step 9a: Test Harness Reads it back again to confirm the successful - write of MaxCoolSetpointLimit attribute" - command: "readAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.F05 - response: - value: 2000 - - - label: - "Step 9b: Test Harness Writes MaxCoolSetpointLimit to value below the - AbsMinCoolSetpointLimit " - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0017 - arguments: - value: 500 - response: - error: CONSTRAINT_ERROR - - #AbsMinCoolSetpointLimit might be negative if not checked before decrement - - label: - "Step 9b: Test Harness Writes MaxCoolSetpointLimit to value below the - AbsMinCoolSetpointLimit" - PICS: - TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0017 && PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - #1. Test Harness Client attempts to write MaxCoolSetpointLimit below the MinCoolSetpointLimit and confirms that the device does not accept the value. - - ./chip-tool thermostat write max-cool-setpoint-limit 100 1 1 - - On TH(chip-tool) verify that DUT sends a CONSTRAINT_ERROR (0x87) - [1676030395.441963][19525:19527] CHIP:DMG: } - [1676030395.442028][19525:19527] CHIP:DMG: WriteClient moving to [AwaitingDe] - [1676030395.442059][19525:19527] CHIP:TOO: Response Failure: IM Error 0x00000587: General error: 0x87 (CONSTRAINT_ERROR) - [1676030395.442147][19525:19527] CHIP:EM: <<< [E:35527i M:176995637 (Ack:93643096)] (S) Msg TX to 1:0000000000000001 [E8D5] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 9b: Test Harness Writes MaxCoolSetpointLimit to value above the - MaxCoolSetpointLimit " - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0006 - arguments: - value: 4000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 9b: Test Harness Writes MaxCoolSetpointLimit to value above the - MaxCoolSetpointLimit " - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0006 - arguments: - value: AbsMaxCoolSetpointLimitValue + 1000 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 9c: Test Harness Writes the limit of AbsMaxCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0006 - arguments: - value: 3200 - - - label: - "Step 9c: Test Harness Writes the limit of AbsMaxCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0006 - arguments: - value: AbsMaxCoolSetpointLimitValue - - - label: - "Step 9c: Test Harness Writes the limit of MinCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0017 && !TSTAT.S.F05 - arguments: - value: 1600 - - - label: - "Step 9c: Test Harness Writes the limit of MinCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0017 && TSTAT.S.F05 - arguments: - value: 1600 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 9c: Test Harness Writes the limit of MinCoolSetpointLimit to - MaxCoolSetpointLimit attribute" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0017 && !TSTAT.S.F05 - arguments: - value: MinCoolSetpointLimitValue - - #LowerLimit = Max(MinCoolSetpointLimit,(MaxHeatSetpointLimit + MinSetpointDeadBand)) not possible in YAML - - label: - "Step 9c: Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = - Max(MinCoolSetpointLimit, (MaxHeatSetpointLimit + - MinSetpointDeadBand)) to MaxCoolSetpointLimit attribute" - PICS: - TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0016 && TSTAT.S.F05 && - PICS_SKIP_SAMPLE_APP - verification: | - Optional Attribute - If it is supported, then in TH log it will results in displaying the value, else it will display UNSUPPORTED_ATTRIBUTE. Below is the log of RPI the result may be vary on the basis of dut implementation. - - Test Harness Client then attempts to write MaxCoolSetpointLimit to both of the limits of LowerLimit & AbsMaxCoolSetpointLimit and confirms that the device does accept the value. - below is an example command - - ./chip-tool thermostat write max-cool-setpoint-limit 2000 1 1 - - On TH verify that DUT sends a success response - - [1678947558.840324][773890:773892] CHIP:DMG: - [1678947558.840331][773890:773892] CHIP:DMG: StatusIB = - [1678947558.840339][773890:773892] CHIP:DMG: { - [1678947558.840347][773890:773892] CHIP:DMG: status = 0x00 (SUCCESS), - [1678947558.840354][773890:773892] CHIP:DMG: }, - [1678947558.840362][773890:773892] CHIP:DMG: - [1678947558.840369][773890:773892] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - arguments: - values: - - name: "message" - value: "Please enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 10a: Test Harness Writes (sets back) default value of - MinHeatSetpointLimit" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.A0003 - arguments: - value: AbsMinHeatSetpointLimitValue - - - label: - "Step 10a: Test Harness Writes (sets back) default value of - MinHeatSetpointLimit" - command: "writeAttribute" - attribute: "MinHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && !TSTAT.S.A0003 - arguments: - value: 700 - - - label: - "Step 10a: Test Harness Writes (sets back)default value of - MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && TSTAT.S.A0004 - arguments: - value: AbsMaxHeatSetpointLimitValue - - - label: - "Step 10a: Test Harness Writes (sets back)default value of - MaxHeatSetpointLimit" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && !TSTAT.S.F05 && !TSTAT.S.A0004 - arguments: - value: 3000 - - - label: - "Step 10a: Test Harness Writes MaxHeatSetpointLimit That meets the - deadband of 2.5C" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 && TSTAT.S.F05 - arguments: - value: 2950 - - - label: - "Step 10b: Test Harness Writes (sets back) default value of - MinCoolSetpointLimit" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && TSTAT.S.A0005 - arguments: - value: AbsMinCoolSetpointLimitValue - - - label: - "Step 10b: Test Harness Writes (sets back) default value of - MinCoolSetpointLimit" - command: "writeAttribute" - attribute: "MinCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 && !TSTAT.S.A0005 - arguments: - value: 1600 - - - label: - "Step 10b: Test Harness Writes (sets back) default value of - MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && TSTAT.S.A0006 - arguments: - value: AbsMaxCoolSetpointLimitValue - - - label: - "Step 10b: Test Harness Writes (sets back) default value of - MaxCoolSetpointLimit" - command: "writeAttribute" - attribute: "MaxCoolSetpointLimit" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 && !TSTAT.S.A0006 - arguments: - value: 3200 - - - label: - "Step 11a: Test Harness Reads MinSetpointDeadBand attribute from - Server DUT and verifies that the value is within range" - command: "readAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 - response: - constraints: - type: int8s - minValue: 0 - maxValue: 25 - - - label: - "Step 11a: Test Harness Writes a value back that is different but - valid for MinSetpointDeadBand attribute" - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: 5 - - - label: - "Step 11a: Test Harness Reads it back again to confirm the successful - write of MinSetpointDeadBand attribute" - command: "readAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - response: - value: 5 - - - label: "Step 11b: Test Harness Writes the value below MinSetpointDeadBand" - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: -1 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 11b: Test Harness Writes the value above MinSetpointDeadBand " - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: 30 - response: - error: CONSTRAINT_ERROR - - - label: - "Step 11c: Test Harness Writes the min limit of MinSetpointDeadBand" - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: 0 - - - label: - "Step 11c: Test Harness Writes the max limit of MinSetpointDeadBand" - command: "writeAttribute" - attribute: "MinSetpointDeadBand" - PICS: TSTAT.S.F05 && TSTAT.S.M.MinSetpointDeadBandWritable - arguments: - value: 25 - - - label: - "Step 12: Test Harness Reads ControlSequenceOfOperation from Server - DUT, if TSTAT.S.F01 is true" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F01 && !TSTAT.S.F00 - response: - constraints: - anyOf: [0, 1] - - - label: - "Step 12: Test Harness Reads ControlSequenceOfOperation from Server - DUT, if TSTAT.S.F00 is true" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && !TSTAT.S.F01 - response: - constraints: - anyOf: [2, 3] - - - label: - "Step 12: Test Harness Reads ControlSequenceOfOperation from Server - DUT, if both TSTAT.S.F01 and TSTAT.S.F01 are true" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && TSTAT.S.F01 - response: - constraints: - anyOf: [4, 5] - - - label: - "Step 12: Test Harness writes value 1 for attribute - ControlSequenceOfOperation. If TSTAT.S.F01 is true & TSTAT.S.F00 is - false" - command: "writeAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F01 && !TSTAT.S.F00 - arguments: - value: 1 - - - label: - "Step 12: Test Harness Read it back again to confirm the successful - write" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F01 && !TSTAT.S.F00 - response: - value: 1 - - - label: - "Step 12: Test Harness writes value 3 for attribute - ControlSequenceOfOperation. If TSTAT.S.F00 is true & TSTAT.S.F01 is - false" - command: "writeAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && !TSTAT.S.F01 - arguments: - value: 3 - - - label: - "Step 12: Test Harness Read it back again to confirm the successful - write" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && !TSTAT.S.F01 - response: - value: 3 - - - label: - "Step 12: Test Harness writes value 4 for attribute - ControlSequenceOfOperation. If TSTAT.S.F01 & TSTAT.S.F00 are true" - command: "writeAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && TSTAT.S.F01 - arguments: - value: 4 - - - label: - "Step 12: Test Harness Read it back again to confirm the successful - write" - command: "readAttribute" - attribute: "ControlSequenceOfOperation" - PICS: TSTAT.S.F00 && TSTAT.S.F01 - response: - value: 4 - - - label: - "Test Harness Writes MaxHeatSetpointLimit attribute to default value - of 2950 to meet deadband constraint" - command: "writeAttribute" - attribute: "MaxHeatSetpointLimit" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 && TSTAT.S.F05 - arguments: - value: 2950 - - - label: "Step 13: Sets OccupiedCoolingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2600 - - - label: "Step 13: Sets OccupiedHeatingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2000 - - - label: "Step 13: Sends SetpointRaise Command Heat Only" - PICS: TSTAT.S.F00 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 0 - - name: "Amount" - value: -30 - - - label: - "Step 13: Test Harness Reads back OccupiedHeatingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 1700 - - - label: "Step 14: Sets OccupiedHeatingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2000 - - - label: "Step 14: Test Harness Sends SetpointRaise Command Heat Only" - PICS: TSTAT.S.F00 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 0 - - name: "Amount" - value: 30 - - - label: - "Step 14: Test Harness Reads back OccupiedHeatingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 2300 - - - label: "Step 15: Test Harness Sends SetpointRaise Command Cool Only" - PICS: TSTAT.S.F01 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 1 - - name: "Amount" - value: -30 - - - label: - "Step 15: Test Harness Reads back OccupiedCoolingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2300 - - - label: "Step 16: Sets OccupiedCoolingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2600 - - - label: "Step 16: Test Harness Sends SetpointRaise Command Cool Only" - PICS: TSTAT.S.F01 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 1 - - name: "Amount" - value: 30 - - - label: - "Step 16: Test Harness Reads back OccupiedCoolingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2900 - - - label: "Step 17: Sets OccupiedCoolingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2600 - - - label: "Step 17: Sets OccupiedHeatingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2000 - - - label: "Step 17: Test Harness Sends SetpointRaise Command Heat & Cool" - PICS: TSTAT.S.F00 || TSTAT.S.F01 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 2 - - name: "Amount" - value: -30 - - - label: - "Step 17: Test Harness Reads back OccupiedCoolingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2300 - - - label: - "Step 17: Test Harness Reads back OccupiedHeatingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 1700 - - - label: "Step 18: Sets OccupiedCoolingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - arguments: - value: 2600 - - - label: "Step 18: Sets OccupiedHeatingSetpoint to default value" - command: "writeAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - arguments: - value: 2000 - - - label: "Step 18: Test Harness Sends SetpointRaise Command Heat & Cool" - PICS: TSTAT.S.F00 || TSTAT.S.F01 - command: "SetpointRaiseLower" - arguments: - values: - - name: "Mode" - value: 2 - - name: "Amount" - value: 30 - - - label: - "Step 18: Test Harness Reads back OccupiedCoolingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedCoolingSetpoint" - PICS: TSTAT.S.F01 - response: - value: 2900 - - - label: - "Step 18: Test Harness Reads back OccupiedHeatingSetpoint to confirm - the success of the write" - command: "readAttribute" - attribute: "OccupiedHeatingSetpoint" - PICS: TSTAT.S.F00 - response: - value: 2300 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 84b5720e165fe1..c63b6d5fa30cc8 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 @@ -843,6 +843,33 @@ limitations under the License. + + MA-camera + CHIP + Camera + 0x0103 + 0x0142 + Simple + Endpoint + + + + + + + + + + + + + + + + + + + MA-pump CHIP diff --git a/src/controller/java/BUILD.gn b/src/controller/java/BUILD.gn index f8eeee3fd7b93b..0ddc1f8a2a7d43 100644 --- a/src/controller/java/BUILD.gn +++ b/src/controller/java/BUILD.gn @@ -679,7 +679,7 @@ android_library("java") { ] # TODO: add classpath support (we likely need to add something like - # ..../platforms/android-26/android.jar to access BLE items) + # ..../platforms/android-30/android.jar to access BLE items) } if (chip_link_tests) { @@ -711,7 +711,7 @@ if (chip_link_tests) { javac_flags = [ "-Xlint:deprecation" ] # TODO: add classpath support (we likely need to add something like - # ..../platforms/android-26/android.jar to access BLE items) + # ..../platforms/android-30/android.jar to access BLE items) } android_library("tests") { @@ -746,12 +746,12 @@ if (chip_link_tests) { javac_flags = [ "-Xlint:deprecation" ] # TODO: add classpath support (we likely need to add something like - # ..../platforms/android-26/android.jar to access BLE items) + # ..../platforms/android-30/android.jar to access BLE items) } } if (!matter_enable_java_compilation) { java_prebuilt("android") { - jar_path = "${android_sdk_root}/platforms/android-26/android.jar" + jar_path = "${android_sdk_root}/platforms/android-30/android.jar" } } diff --git a/src/controller/python/chip/ble/LinuxImpl.cpp b/src/controller/python/chip/ble/LinuxImpl.cpp index 4e03d41e14949c..09aa0056f084f9 100644 --- a/src/controller/python/chip/ble/LinuxImpl.cpp +++ b/src/controller/python/chip/ble/LinuxImpl.cpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/controller/tests/data_model/TestWrite.cpp b/src/controller/tests/data_model/TestWrite.cpp index 218832702b230f..c50e7aac96aaef 100644 --- a/src/controller/tests/data_model/TestWrite.cpp +++ b/src/controller/tests/data_model/TestWrite.cpp @@ -21,8 +21,8 @@ #include "DataModelFixtures.h" -#include "app-common/zap-generated/ids/Clusters.h" #include +#include #include #include #include @@ -39,9 +39,72 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::UnitTesting; using namespace chip::app::DataModelTests; using namespace chip::Protocols; +using namespace chip::Test; namespace { +const MockNodeConfig & TestMockNodeConfig() +{ + using namespace Clusters::Globals::Attributes; + + // clang-format off + static const MockNodeConfig config({ + MockEndpointConfig(kRootEndpointId, { + MockClusterConfig(Clusters::IcdManagement::Id, { + ClusterRevision::Id, FeatureMap::Id, + Clusters::IcdManagement::Attributes::OperatingMode::Id, + }), + }), + MockEndpointConfig(kTestEndpointId, { + MockClusterConfig(Clusters::UnitTesting::Id, { + ClusterRevision::Id, FeatureMap::Id, + Clusters::UnitTesting::Attributes::Boolean::Id, + Clusters::UnitTesting::Attributes::Int16u::Id, + Clusters::UnitTesting::Attributes::Int8u::Id, + Clusters::UnitTesting::Attributes::ListFabricScoped::Id, + Clusters::UnitTesting::Attributes::ListStructOctetString::Id, + }), + }), + MockEndpointConfig(kMockEndpoint1, { + MockClusterConfig(MockClusterId(1), { + ClusterRevision::Id, FeatureMap::Id, + }, { + MockEventId(1), MockEventId(2), + }), + MockClusterConfig(MockClusterId(2), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), + }), + }), + MockEndpointConfig(kMockEndpoint2, { + MockClusterConfig(MockClusterId(1), { + ClusterRevision::Id, FeatureMap::Id, + }), + MockClusterConfig(MockClusterId(2), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), MockAttributeId(2), + }), + MockClusterConfig(MockClusterId(3), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), MockAttributeId(2), MockAttributeId(3), + }), + }), + MockEndpointConfig(kMockEndpoint3, { + MockClusterConfig(MockClusterId(1), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), + }), + MockClusterConfig(MockClusterId(2), { + ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), MockAttributeId(2), MockAttributeId(3), MockAttributeId(4), + }), + MockClusterConfig(MockClusterId(3), { + ClusterRevision::Id, FeatureMap::Id, + }), + MockClusterConfig(MockClusterId(4), { + ClusterRevision::Id, FeatureMap::Id, + }), + }), + }); + // clang-format on + return config; +} + class SingleWriteCallback : public WriteClient::Callback { public: @@ -89,11 +152,13 @@ class TestWrite : public chip::Test::AppContext { chip::Test::AppContext::SetUp(); mOldProvider = InteractionModelEngine::GetInstance()->SetDataModelProvider(&CustomDataModel::Instance()); + chip::Test::SetMockNodeConfig(TestMockNodeConfig()); } // Performs teardown for each individual test in the test suite void TearDown() override { + chip::Test::ResetMockNodeConfig(); InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider); chip::Test::AppContext::TearDown(); } diff --git a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h index 9edd153fd2410c..3719faa9442ca7 100644 --- a/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h +++ b/src/darwin/Framework/CHIP/MTRBaseSubscriptionCallback.h @@ -139,8 +139,6 @@ class MTRBaseSubscriptionCallback : public chip::app::ClusterStateCache::Callbac void OnDeallocatePaths(chip::app::ReadPrepareParams && aReadPrepareParams) override; - void OnSubscriptionEstablished(chip::SubscriptionId aSubscriptionId) override; - CHIP_ERROR OnResubscriptionNeeded(chip::app::ReadClient * apReadClient, CHIP_ERROR aTerminationCause) override; void OnUnsolicitedMessageFromPublisher(chip::app::ReadClient * apReadClient) override; @@ -153,6 +151,8 @@ class MTRBaseSubscriptionCallback : public chip::app::ClusterStateCache::Callbac void CallResubscriptionScheduledHandler(NSError * error, NSNumber * resubscriptionDelay); + void OnSubscriptionEstablished(chip::SubscriptionId aSubscriptionId) override; + private: DataReportCallback _Nullable mAttributeReportCallback = nil; DataReportCallback _Nullable mEventReportCallback = nil; diff --git a/src/darwin/Framework/CHIP/MTRCommissioningParameters.mm b/src/darwin/Framework/CHIP/MTRCommissioningParameters.mm index 72308a910ad3c7..41cf7e0fa6d556 100644 --- a/src/darwin/Framework/CHIP/MTRCommissioningParameters.mm +++ b/src/darwin/Framework/CHIP/MTRCommissioningParameters.mm @@ -45,6 +45,12 @@ - (void)setFailSafeExpiryTimeoutSecs:(NSNumber * _Nullable)failSafeExpiryTimeout self.failSafeTimeout = failSafeExpiryTimeoutSecs; } +- (NSString *)description +{ + return [NSString stringWithFormat:@"", self, + self.wifiSSID != nil, self.threadOperationalDataset != nil]; +} + @end NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm index 8a0057ca1ed9f2..7baa49060dd282 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.mm @@ -26,6 +26,9 @@ #include #include +// Log error each time sync storage takes longer than this threshold +#define SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS (2.0) + // FIXME: Are these good key strings? https://github.com/project-chip/connectedhomeip/issues/28973 static NSString * sResumptionNodeListKey = @"caseResumptionNodeList"; static NSString * sLastLocallyUsedNOCKey = @"lastLocallyUsedControllerNOC"; @@ -134,6 +137,7 @@ - (nullable instancetype)initWithController:(MTRDeviceController *)controller __block id resumptionNodeList; __block NSArray * nodesWithAttributeInfo; + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ @autoreleasepool { // NOTE: controller, not our weak ref, since we know it's still @@ -146,6 +150,10 @@ - (nullable instancetype)initWithController:(MTRDeviceController *)controller nodesWithAttributeInfo = [self _fetchNodeIndex]; } }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore init took %0.6lf seconds to read from storage", syncDuration); + } if (resumptionNodeList != nil) { if (![resumptionNodeList isKindOfClass:[NSArray class]]) { MTR_LOG_ERROR("List of CASE resumption node IDs is not an array"); @@ -177,11 +185,16 @@ - (void)fetchAttributeDataForAllDevices:(MTRDeviceControllerDataStoreClusterData MTRDeviceController * controller = _controller; VerifyOrReturn(controller != nil); // No way to call delegate without controller. + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ if ([self->_storageDelegate respondsToSelector:@selector(valuesForController:securityLevel:sharingType:)]) { dataStoreSecureLocalValues = [self->_storageDelegate valuesForController:controller securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; } }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore fetchAttributeDataForAllDevices took %0.6lf seconds to read from storage", syncDuration); + } if (dataStoreSecureLocalValues.count) { clusterDataHandler([self _getClusterDataFromSecureLocalValues:dataStoreSecureLocalValues]); @@ -204,6 +217,7 @@ - (void)storeResumptionInfo:(MTRCASESessionResumptionInfo *)resumptionInfo VerifyOrReturn(controller != nil); // No way to call delegate without controller. auto * oldInfo = [self findResumptionInfoByNodeID:resumptionInfo.nodeID]; + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ if (oldInfo != nil) { // Remove old resumption id key. No need to do that for the @@ -241,6 +255,10 @@ - (void)storeResumptionInfo:(MTRCASESessionResumptionInfo *)resumptionInfo securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore storeResumptionInfo took %0.6lf seconds to store to storage", syncDuration); + } } - (void)clearAllResumptionInfo @@ -274,6 +292,7 @@ - (void)_clearResumptionInfoForNodeID:(NSNumber *)nodeID controller:(MTRDeviceCo { auto * oldInfo = [self findResumptionInfoByNodeID:nodeID]; if (oldInfo != nil) { + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ [_storageDelegate controller:controller removeValueForKey:ResumptionByResumptionIDKey(oldInfo.resumptionID) @@ -284,6 +303,10 @@ - (void)_clearResumptionInfoForNodeID:(NSNumber *)nodeID controller:(MTRDeviceCo securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore _clearResumptionInfoForNodeID took %0.6lf seconds to remove from storage", syncDuration); + } } } @@ -293,6 +316,7 @@ - (CHIP_ERROR)storeLastLocallyUsedNOC:(MTRCertificateTLVBytes)noc VerifyOrReturnError(controller != nil, CHIP_ERROR_PERSISTED_STORAGE_FAILED); // No way to call delegate without controller. __block BOOL ok; + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ ok = [_storageDelegate controller:controller storeValue:noc @@ -300,6 +324,10 @@ - (CHIP_ERROR)storeLastLocallyUsedNOC:(MTRCertificateTLVBytes)noc securityLevel:MTRStorageSecurityLevelSecure sharingType:MTRStorageSharingTypeNotShared]; }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore storeLastLocallyUsedNOC took %0.6lf seconds to store to storage", syncDuration); + } return ok ? CHIP_NO_ERROR : CHIP_ERROR_PERSISTED_STORAGE_FAILED; } @@ -309,6 +337,7 @@ - (MTRCertificateTLVBytes _Nullable)fetchLastLocallyUsedNOC VerifyOrReturnValue(controller != nil, nil); // No way to call delegate without controller. __block id data; + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ @autoreleasepool { data = [_storageDelegate controller:controller @@ -317,6 +346,10 @@ - (MTRCertificateTLVBytes _Nullable)fetchLastLocallyUsedNOC sharingType:MTRStorageSharingTypeNotShared]; } }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore fetchLastLocallyUsedNOC took %0.6lf seconds to read from storage", syncDuration); + } if (data == nil) { return nil; @@ -340,6 +373,7 @@ - (nullable MTRCASESessionResumptionInfo *)_findResumptionInfoWithKey:(nullable } __block id resumptionInfo; + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ @autoreleasepool { resumptionInfo = [_storageDelegate controller:controller @@ -348,6 +382,10 @@ - (nullable MTRCASESessionResumptionInfo *)_findResumptionInfoWithKey:(nullable sharingType:MTRStorageSharingTypeNotShared]; } }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore _findResumptionInfoWithKey took %0.6lf seconds to read from storage", syncDuration); + } if (resumptionInfo == nil) { return nil; @@ -866,6 +904,7 @@ - (void)clearAllStoredClusterData } __block NSMutableDictionary * clusterDataToReturn = nil; + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ std::lock_guard lock(self->_nodeArrayLock); @@ -924,6 +963,10 @@ - (void)clearAllStoredClusterData } } }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore getStoredClusterDataForNodeID took %0.6lf seconds to read from storage", syncDuration); + } return clusterDataToReturn; } @@ -934,9 +977,14 @@ - (nullable MTRDeviceClusterData *)getStoredClusterDataForNodeID:(NSNumber *)nod // when the consumer knows that we're supposed to have data for this cluster // path. __block MTRDeviceClusterData * clusterDataToReturn = nil; + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ clusterDataToReturn = [self _fetchClusterDataForNodeID:nodeID endpointID:endpointID clusterID:clusterID]; }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore getStoredClusterDataForNodeID took %0.6lf seconds to read from storage", syncDuration); + } return clusterDataToReturn; } @@ -1173,6 +1221,7 @@ - (NSString *)_deviceDataKeyForNodeID:(NSNumber *)nodeID - (nullable NSDictionary *)getStoredDeviceDataForNodeID:(NSNumber *)nodeID { __block NSDictionary * deviceData = nil; + NSDate * startTime = [NSDate now]; dispatch_sync(_storageDelegateQueue, ^{ MTRDeviceController * controller = self->_controller; VerifyOrReturn(controller != nil); // No way to call delegate without controller. @@ -1204,6 +1253,10 @@ - (NSString *)_deviceDataKeyForNodeID:(NSNumber *)nodeID // to do that. deviceData = dictionary; }); + NSTimeInterval syncDuration = -[startTime timeIntervalSinceNow]; + if (syncDuration > SYNC_OPERATION_DURATION_LOG_THRESHOLD_SECONDS) { + MTR_LOG_ERROR("MTRDeviceControllerDataStore getStoredDeviceDataForNodeID took %0.6lf seconds to read from storage", syncDuration); + } return deviceData; } diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index f4e968a72cf268..3c38c7cfd65f5c 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -1133,8 +1133,6 @@ - (void)operationalInstanceAdded:(chip::PeerId &)operationalID for (MTRDeviceController_Concrete * controller in controllersCopy) { auto * compressedFabricId = controller.compressedFabricID; if (compressedFabricId != nil && compressedFabricId.unsignedLongLongValue == operationalID.GetCompressedFabricId()) { - ChipLogProgress(Controller, "Notifying controller at fabric index %u about new operational node 0x" ChipLogFormatX64, - controller.fabricIndex, ChipLogValueX64(operationalID.GetNodeId())); [controller operationalInstanceAdded:@(operationalID.GetNodeId())]; } diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h index 606d430847368e..13a5782ca5c60e 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.h @@ -223,6 +223,11 @@ NS_ASSUME_NONNULL_BEGIN queue:(dispatch_queue_t)queue completion:(void (^)(NSURL * _Nullable url, NSError * _Nullable error))completion; +/** + * Returns YES if the MTRDevice corrresponding to the given node ID is known to be a thread device, NO otherwise. + */ +- (BOOL)definitelyUsesThreadForDevice:(chip::NodeId)nodeID; + /** * Will return chip::kUndefinedFabricIndex if we do not have a fabric index. */ diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm index 04b541fc7783a6..3396c524b0dd55 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm @@ -950,6 +950,8 @@ - (BOOL)commissionNodeWithID:(NSNumber *)nodeID commissioningParams:(MTRCommissioningParameters *)commissioningParams error:(NSError * __autoreleasing *)error { + MTR_LOG("%@ trying to commission node with ID 0x%016llX parameters %@", self, nodeID.unsignedLongLongValue, commissioningParams); + if (self.suspended) { MTR_LOG_ERROR("%@ suspended: can't commission device ID 0x%016llX with parameters %@", self, nodeID.unsignedLongLongValue, commissioningParams); // TODO: Can we do a better error here? @@ -1427,33 +1429,42 @@ - (BOOL)checkIsRunning:(NSError * __autoreleasing *)error return NO; } -- (void)getSessionForNode:(chip::NodeId)nodeID completion:(MTRInternalDeviceConnectionCallback)completion +- (BOOL)definitelyUsesThreadForDevice:(chip::NodeId)nodeID { - // TODO: Figure out whether the synchronization here makes sense. What - // happens if this call happens mid-suspend or mid-resume? - if (self.suspended) { - MTR_LOG_ERROR("%@ suspended: can't get session for node %016llX-%016llx (%llu)", self, self.compressedFabricID.unsignedLongLongValue, nodeID, nodeID); - // TODO: Can we do a better error here? - completion(nullptr, chip::NullOptional, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil); - return; + if (!chip::IsOperationalNodeId(nodeID)) { + return NO; } - // Get the corresponding MTRDevice object to determine if the case/subscription pool is to be used + // Get the corresponding MTRDevice object for the node id MTRDevice * device = [self deviceForNodeID:@(nodeID)]; // TODO: Can we not just assume this isKindOfClass test is true? Would be // really nice if we had compile-time checking for this somehow... if (![device isKindOfClass:MTRDevice_Concrete.class]) { MTR_LOG_ERROR("%@ somehow has %@ instead of MTRDevice_Concrete for node ID 0x%016llX (%llu)", self, device, nodeID, nodeID); - completion(nullptr, chip::NullOptional, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil); - return; + return NO; } auto * concreteDevice = static_cast(device); + BOOL usesThread = [concreteDevice deviceUsesThread]; + return usesThread; +} + +- (void)getSessionForNode:(chip::NodeId)nodeID completion:(MTRInternalDeviceConnectionCallback)completion +{ + // TODO: Figure out whether the synchronization here makes sense. What + // happens if this call happens mid-suspend or mid-resume? + if (self.suspended) { + MTR_LOG_ERROR("%@ suspended: can't get session for node %016llX-%016llx (%llu)", self, self.compressedFabricID.unsignedLongLongValue, nodeID, nodeID); + // TODO: Can we do a better error here? + completion(nullptr, chip::NullOptional, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil); + return; + } + // In the case that this device is known to use thread, queue this with subscription attempts as well, to // help with throttling Thread traffic. - if ([concreteDevice deviceUsesThread]) { + if ([self definitelyUsesThreadForDevice:nodeID]) { MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; [workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull workItemCompletion) { MTRInternalDeviceConnectionCallback completionWrapper = ^(chip::Messaging::ExchangeManager * _Nullable exchangeManager, @@ -1664,6 +1675,9 @@ - (void)invalidateCASESessionForNode:(NSNumber *)nodeID; - (void)operationalInstanceAdded:(NSNumber *)nodeID { + MTR_LOG("%@ at fabric index %u notified about new operational node 0x%016llx (%llu)", self, self.fabricIndex, + nodeID.unsignedLongLongValue, nodeID.unsignedLongLongValue); + // If we don't have an existing MTRDevice for this node ID, that's fine; // nothing to do. MTRDevice * device = [self _deviceForNodeID:nodeID createIfNeeded:NO]; diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 4e29b0e5e3d3a3..0cb81e6b3f56dc 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -118,6 +118,8 @@ - (void)_deviceInternalStateChanged:(MTRDevice *)device; void ResetResubscriptionBackoff() { mResubscriptionNumRetries = 0; } private: + void OnSubscriptionEstablished(chip::SubscriptionId aSubscriptionId) override; + void OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus) override; void OnAttributeData(const ConcreteDataAttributePath & aPath, TLV::TLVReader * apData, const StatusIB & aStatus) override; @@ -334,6 +336,9 @@ @interface MTRDevice_Concrete () @property (nonatomic) NSDate * lastDeviceBecameActiveCallbackTime; @property (nonatomic) BOOL throttlingDeviceBecameActiveCallbacks; +// Keep track of the last time we received subscription related communication from the device +@property (nonatomic, nullable) NSDate * lastSubscriptionActiveTime; + /** * If currentReadClient is non-null, that means that we successfully * called SendAutoResubscribeRequest on the ReadClient and have not yet gotten @@ -358,6 +363,7 @@ - (void)unitTestSubscriptionPoolWorkComplete:(MTRDevice *)device; - (void)unitTestClusterDataPersisted:(MTRDevice *)device; - (BOOL)unitTestSuppressTimeBasedReachabilityChanges:(MTRDevice *)device; - (void)unitTestSubscriptionCallbackDeleteForDevice:(MTRDevice *)device; +- (void)unitTestSubscriptionResetForDevice:(MTRDevice *)device; @end #endif @@ -2667,6 +2673,14 @@ - (void)_resetSubscription [self.matterCPPObjectsHolder clearReadClientAndDeleteSubscriptionCallback]; [self _doHandleSubscriptionError:nil]; + +#ifdef DEBUG + [self _callFirstDelegateSynchronouslyWithBlock:^(id testDelegate) { + if ([testDelegate respondsToSelector:@selector(unitTestSubscriptionResetForDevice:)]) { + [testDelegate unitTestSubscriptionResetForDevice:self]; + } + }]; +#endif } #ifdef DEBUG @@ -2772,6 +2786,10 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason ^(NSArray * value) { mtr_strongify(self); VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription attribute report called back with nil MTRDevice")); + { + std::lock_guard lock(self->_lock); + self.lastSubscriptionActiveTime = [NSDate now]; + } MTR_LOG("%@ got attribute report (%p) %@", self, value, value); dispatch_async(self.queue, ^{ @@ -2788,6 +2806,10 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason ^(NSArray * value) { mtr_strongify(self); VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription event report called back with nil MTRDevice")); + { + std::lock_guard lock(self->_lock); + self.lastSubscriptionActiveTime = [NSDate now]; + } MTR_LOG("%@ got event report %@", self, value); dispatch_async(self.queue, ^{ @@ -2820,6 +2842,7 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason MTR_LOG("%@ got subscription established", self); std::lock_guard lock(self->_lock); + self.lastSubscriptionActiveTime = [NSDate now]; // First synchronously change state if (HadSubscriptionEstablishedOnce(self->_internalDeviceState)) { @@ -2864,6 +2887,10 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason ^(void) { mtr_strongify(self); VerifyOrReturn(self, MTR_LOG_DEBUG("_setupSubscriptionWithReason subscription report begin called back with nil MTRDevice")); + { + std::lock_guard lock(self->_lock); + self.lastSubscriptionActiveTime = [NSDate now]; + } MTR_LOG("%@ got report begin", self); [self _handleReportBegin]; @@ -4721,8 +4748,23 @@ - (BOOL)_deviceHasActiveSubscription return HaveSubscriptionEstablishedRightNow(_internalDeviceState); } +// TODO: make this configurable - for now use 1.5 second +#define MTRDEVICE_ACTIVE_COMMUNICATION_THRESHOLD_SECONDS (1.5) + - (void)_deviceMayBeReachable { + // Ignore this call if actively receiving communication from this device + { + std::lock_guard lock(self->_lock); + if (self.lastSubscriptionActiveTime) { + NSTimeInterval intervalSinceDeviceLastActive = -[self.lastSubscriptionActiveTime timeIntervalSinceNow]; + if (intervalSinceDeviceLastActive < MTRDEVICE_ACTIVE_COMMUNICATION_THRESHOLD_SECONDS) { + MTR_LOG("%@ _deviceMayBeReachable called and ignored, because last received communication from device %.6lf seconds ago", self, intervalSinceDeviceLastActive); + return; + } + } + } + MTR_LOG("%@ _deviceMayBeReachable called, resetting subscription", self); // TODO: This should only be allowed for thread devices mtr_weakify(self); @@ -4744,9 +4786,28 @@ - (void)_deviceMayBeReachable [self _resetSubscription]; } + auto peerScopeId = commissioner->GetPeerScopedId(self->_nodeID.unsignedLongLongValue); auto caseSessionMgr = commissioner->CASESessionMgr(); VerifyOrDie(caseSessionMgr != nullptr); - caseSessionMgr->ReleaseSession(commissioner->GetPeerScopedId(self->_nodeID.unsignedLongLongValue)); + caseSessionMgr->ReleaseSession(peerScopeId); + +// TODO: make this configurable - for now use 1.5 second +#define MTRDEVICE_ACTIVE_SESSION_THRESHOLD_MILLISECONDS (15000) + auto sessionMgr = commissioner->SessionMgr(); + VerifyOrDie(sessionMgr != nullptr); + sessionMgr->ForEachMatchingSession(peerScopeId, [](auto * session) { + auto secureSession = session->AsSecureSession(); + if (!secureSession) { + return; + } + + auto threshold = System::Clock::Timeout(MTRDEVICE_ACTIVE_SESSION_THRESHOLD_MILLISECONDS); + if ((System::SystemClock().GetMonotonicTimestamp() - session->GetLastPeerActivityTime()) < threshold) { + return; + } + + session->MarkAsDefunct(); + }); std::lock_guard lock(self->_lock); // Use _ensureSubscriptionForExistingDelegates so that the subscriptions @@ -4770,6 +4831,14 @@ + (MTRDevice *)deviceWithNodeID:(uint64_t)nodeID deviceController:(MTRDeviceCont #pragma mark - SubscriptionCallback namespace { +void SubscriptionCallback::OnSubscriptionEstablished(SubscriptionId aSubscriptionId) +{ + // The next time we need to do a resubscribe, we should start a new backoff + // sequence. + ResetResubscriptionBackoff(); + MTRBaseSubscriptionCallback::OnSubscriptionEstablished(aSubscriptionId); +} + void SubscriptionCallback::OnEventData(const EventHeader & aEventHeader, TLV::TLVReader * apData, const StatusIB * apStatus) { if (mEventReports == nil) { diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index 056d1f1b8236a3..77b55f315c6658 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -253,15 +253,23 @@ - (oneway void)deviceConfigurationChanged:(NSNumber *)nodeID }]; } -static const auto * requiredInternalStateKeys = @[ kMTRDeviceInternalPropertyDeviceState, kMTRDeviceInternalPropertyLastSubscriptionAttemptWait ]; -static const auto * optionalInternalStateKeys = @[ kMTRDeviceInternalPropertyKeyVendorID, kMTRDeviceInternalPropertyKeyProductID, kMTRDeviceInternalPropertyNetworkFeatures, kMTRDeviceInternalPropertyMostRecentReportTime, kMTRDeviceInternalPropertyLastSubscriptionFailureTime ]; - -- (BOOL)_internalState:(NSDictionary *)dictionary hasValidValuesForKeys:(const NSArray *)keys valueRequired:(BOOL)required +static const auto * requiredInternalStateKeys = @{ + kMTRDeviceInternalPropertyDeviceState : NSNumber.class, + kMTRDeviceInternalPropertyLastSubscriptionAttemptWait : NSNumber.class, +}; + +static const auto * optionalInternalStateKeys = @{ + kMTRDeviceInternalPropertyKeyVendorID : NSNumber.class, + kMTRDeviceInternalPropertyKeyProductID : NSNumber.class, + kMTRDeviceInternalPropertyNetworkFeatures : NSNumber.class, + kMTRDeviceInternalPropertyMostRecentReportTime : NSDate.class, + kMTRDeviceInternalPropertyLastSubscriptionFailureTime : NSDate.class, +}; + +- (BOOL)_ensureValidValuesForKeys:(const NSDictionary *)keys inInternalState:(NSMutableDictionary *)internalState valueRequired:(BOOL)required { - // At one point, all keys were NSNumber valued; now there are also NSDates. - // TODO: Create a mapping between keys and their expected types and use that in the type check below. for (NSString * key in keys) { - id value = dictionary[key]; + id value = internalState[key]; if (!value) { if (required) { MTR_LOG_ERROR("%@ device:internalStateUpdated: handed state with no value for \"%@\": %@", self, key, value); @@ -270,9 +278,17 @@ - (BOOL)_internalState:(NSDictionary *)dictionary hasValidValuesForKeys:(const N continue; } - if (!MTR_SAFE_CAST(value, NSNumber) && !MTR_SAFE_CAST(value, NSDate)) { - MTR_LOG_ERROR("%@ device:internalStateUpdated: handed state with invalid value for \"%@\": %@", self, key, value); - return NO; + if (![value isKindOfClass:keys[key]]) { + MTR_LOG_ERROR("%@ device:internalStateUpdated: handed state with invalid value of type %@ for \"%@\": %@", self, + NSStringFromClass([value class]), key, value); + if (required) { + return NO; + } + + // If an optional value is invalid, just drop it and press on with + // the other parts of the state, so we don't break those pieces + // just because something optional has gone awry. + [internalState removeObjectForKey:key]; } } @@ -292,13 +308,21 @@ - (oneway void)device:(NSNumber *)nodeID internalStateUpdated:(NSDictionary *)di return; } + [self _updateInternalState:[dictionary mutableCopy]]; +} + +- (void)_updateInternalState:(NSMutableDictionary *)newState +{ + VerifyOrReturn([self _ensureValidValuesForKeys:requiredInternalStateKeys inInternalState:newState valueRequired:YES]); + VerifyOrReturn([self _ensureValidValuesForKeys:optionalInternalStateKeys inInternalState:newState valueRequired:NO]); + NSNumber * oldStateNumber = MTR_SAFE_CAST(self._internalState[kMTRDeviceInternalPropertyDeviceState], NSNumber); - NSNumber * newStateNumber = MTR_SAFE_CAST(dictionary[kMTRDeviceInternalPropertyDeviceState], NSNumber); + NSNumber * newStateNumber = MTR_SAFE_CAST(newState[kMTRDeviceInternalPropertyDeviceState], NSNumber); - VerifyOrReturn([self _internalState:dictionary hasValidValuesForKeys:requiredInternalStateKeys valueRequired:YES]); - VerifyOrReturn([self _internalState:dictionary hasValidValuesForKeys:optionalInternalStateKeys valueRequired:NO]); + NSNumber * oldPrimedState = MTR_SAFE_CAST(self._internalState[kMTRDeviceInternalPropertyDeviceCachePrimed], NSNumber); + NSNumber * newPrimedState = MTR_SAFE_CAST(newState[kMTRDeviceInternalPropertyDeviceCachePrimed], NSNumber); - [self _setInternalState:dictionary]; + [self _setInternalState:newState]; if (!MTREqualObjects(oldStateNumber, newStateNumber)) { MTRDeviceState state = self.state; @@ -307,9 +331,6 @@ - (oneway void)device:(NSNumber *)nodeID internalStateUpdated:(NSDictionary *)di }]; } - NSNumber * oldPrimedState = MTR_SAFE_CAST(self._internalState[kMTRDeviceInternalPropertyDeviceCachePrimed], NSNumber); - NSNumber * newPrimedState = MTR_SAFE_CAST(dictionary[kMTRDeviceInternalPropertyDeviceCachePrimed], NSNumber); - if (!MTREqualObjects(oldPrimedState, newPrimedState)) { [self _lockAndCallDelegatesWithBlock:^(id delegate) { if ([delegate respondsToSelector:@selector(deviceCachePrimed:)]) { diff --git a/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.h b/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.h index bc45f6e0aed849..d3720e1e345eb0 100644 --- a/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.h +++ b/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.h @@ -74,6 +74,10 @@ class MTROTAImageTransferHandler : public chip::bdx::AsyncResponder { MTROTAImageTransferHandlerWrapper * mOTAImageTransferHandlerWrapper; bool mNeedToCallTransferSessionEnd = false; + + bool mIsPeerNodeAKnownThreadDevice = NO; + + chip::System::Clock::Milliseconds32 mBDXThrottleIntervalForThreadDevices; }; NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.mm b/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.mm index 6a6dce94df3d46..4368b4a318428b 100644 --- a/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.mm +++ b/src/darwin/Framework/CHIP/MTROTAImageTransferHandler.mm @@ -22,6 +22,9 @@ #import "MTROTAUnsolicitedBDXMessageHandler.h" #import "NSStringSpanConversion.h" +#include +#include + using namespace chip; using namespace chip::bdx; using namespace chip::app; @@ -31,6 +34,14 @@ // Timeout for the BDX transfer session. The OTA Spec mandates this should be >= 5 minutes. constexpr System::Clock::Timeout kBdxTimeout = System::Clock::Seconds16(5 * 60); +// For thread devices, we may want to throttle sending Blocks in response to BlockQuery messages +// to avoid spamming the network with too many BDX messages. For now, default to the old 50ms +// polling interval we used to have. +// To override the throttle interval, +// use ` defaults write BDXThrottleIntervalForThreadDevicesInMSecs ` +// See UserDefaults.mm for details. +constexpr auto kBdxThrottleDefaultInterval = System::Clock::Milliseconds32(50); + constexpr bdx::TransferRole kBdxRole = bdx::TransferRole::kSender; // An ARC-managed object that lets us do weak references to a MTROTAImageTransferHandler @@ -53,7 +64,7 @@ - (instancetype)initWithMTROTAImageTransferHandler:(MTROTAImageTransferHandler * } @end -MTROTAImageTransferHandler::MTROTAImageTransferHandler(chip::System::Layer * layer) +MTROTAImageTransferHandler::MTROTAImageTransferHandler(System::Layer * layer) { assertChipStackLockedByCurrentThread(); @@ -78,6 +89,10 @@ - (instancetype)initWithMTROTAImageTransferHandler:(MTROTAImageTransferHandler * VerifyOrReturnError(mDelegate != nil, CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(mDelegateNotificationQueue != nil, CHIP_ERROR_INCORRECT_STATE); + mIsPeerNodeAKnownThreadDevice = [controller definitelyUsesThreadForDevice:mPeer.GetNodeId()]; + + mBDXThrottleIntervalForThreadDevices = Platform::GetUserDefaultBDXThrottleIntervalForThread().value_or(kBdxThrottleDefaultInterval); + BitFlags flags(bdx::TransferControlFlags::kReceiverDrive); return AsyncResponder::Init(mSystemLayer, exchangeCtx, kBdxRole, flags, kMaxBdxBlockSize, kBdxTimeout); @@ -233,6 +248,10 @@ - (instancetype)initWithMTROTAImageTransferHandler:(MTROTAImageTransferHandler * { assertChipStackLockedByCurrentThread(); + // For thread devices, we need to throttle sending the response to + // BlockQuery, so need to track when we started handling BlockQuery. + auto startBlockQueryHandlingTimestamp = System::SystemClock().GetMonotonicTimestamp(); + auto blockSize = @(mTransfer.GetTransferBlockSize()); auto blockIndex = @(mTransfer.GetNextBlockNum()); @@ -241,7 +260,7 @@ - (instancetype)initWithMTROTAImageTransferHandler:(MTROTAImageTransferHandler * MTROTAImageTransferHandlerWrapper * __weak weakWrapper = mOTAImageTransferHandlerWrapper; - auto completionHandler = ^(NSData * _Nullable data, BOOL isEOF) { + auto respondWithBlock = ^(NSData * _Nullable data, BOOL isEOF) { [controller asyncDispatchToMatterQueue:^() { assertChipStackLockedByCurrentThread(); @@ -283,6 +302,31 @@ - (instancetype)initWithMTROTAImageTransferHandler:(MTROTAImageTransferHandler * return CHIP_ERROR_INCORRECT_STATE; } + void (^completionHandler)(NSData * _Nullable data, BOOL isEOF) = nil; + + // If the peer node is a Thread device, check how much time has elapsed since we started processing the BlockQuery, + // round it up to the nearest multiple of kBdxThrottleDefaultInterval, and respond with the block at that point. + if (mIsPeerNodeAKnownThreadDevice) { + completionHandler = ^(NSData * _Nullable data, BOOL isEOF) { + auto timeElapsed = System::SystemClock().GetMonotonicTimestamp() - startBlockQueryHandlingTimestamp; + // Integer division rounds down, so dividing by mBDXThrottleIntervalForThreadDevices and then multiplying + // by it again rounds down to the nearest multiple of mBDXThrottleIntervalForThreadDevices. + auto remainder = timeElapsed - (timeElapsed / mBDXThrottleIntervalForThreadDevices) * mBDXThrottleIntervalForThreadDevices; + + if (remainder == System::Clock::Milliseconds32(0)) { + respondWithBlock(data, isEOF); + } else { + auto nsRemaining = std::chrono::duration_cast(remainder); + dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, nsRemaining.count()); + dispatch_after(time, delegateQueue, ^{ + respondWithBlock(data, isEOF); + }); + } + }; + } else { + completionHandler = respondWithBlock; + } + dispatch_async(delegateQueue, ^{ if ([strongDelegate respondsToSelector:@selector(handleBDXQueryForNodeID: controller:blockSize:blockIndex:bytesToSkip:completion:)]) { diff --git a/src/darwin/Framework/CHIP/MTROperationalBrowser.mm b/src/darwin/Framework/CHIP/MTROperationalBrowser.mm index b5717373ab2933..b8bc3fd3b4f155 100644 --- a/src/darwin/Framework/CHIP/MTROperationalBrowser.mm +++ b/src/darwin/Framework/CHIP/MTROperationalBrowser.mm @@ -17,6 +17,7 @@ #import #import "MTRDeviceControllerFactory_Internal.h" +#import "MTRLogging_Internal.h" #import "MTROperationalBrowser.h" #include @@ -125,11 +126,6 @@ return; } - if (!(aFlags & kDNSServiceFlagsAdd)) { - // We only care about new things appearing. - return; - } - chip::PeerId peerId; CHIP_ERROR err = chip::Dnssd::ExtractIdFromInstanceName(aName, &peerId); if (err != CHIP_NO_ERROR) { @@ -137,6 +133,13 @@ return; } + if (!(aFlags & kDNSServiceFlagsAdd)) { + // We mostly only care about new things appearing, but log it when things + // disappear. + MTR_LOG("Matter operational instance advertisement removed: '%s'\n", aName); + return; + } + ChipLogProgress(Controller, "Notifying controller factory about new operational instance: '%s'", aName); [self->mDeviceControllerFactory operationalInstanceAdded:peerId]; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index d6f8f73697ae22..0c8d504650e9c9 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -7676,6 +7676,7 @@ typedef NS_ENUM(uint32_t, MTRDeviceTypeIDType) { MTRDeviceTypeIDTypeDimmablePlugInUnitID MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) = 0x0000010B, MTRDeviceTypeIDTypeColorTemperatureLightID MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) = 0x0000010C, MTRDeviceTypeIDTypeExtendedColorLightID MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) = 0x0000010D, + MTRDeviceTypeIDTypeCameraID MTR_PROVISIONALLY_AVAILABLE = 0x00000142, MTRDeviceTypeIDTypeWindowCoveringID MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) = 0x00000202, MTRDeviceTypeIDTypeWindowCoveringControllerID MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) = 0x00000203, MTRDeviceTypeIDTypeHeatingCoolingUnitID MTR_AVAILABLE(ios(18.2), macos(15.2), watchos(11.2), tvos(18.2)) = 0x00000300, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm index 9e4b98f3ffdb77..469a38092b722f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm @@ -77,6 +77,7 @@ { 0x0000010B, MTRDeviceTypeClass::Simple, @"Dimmable Plug-in Unit" }, { 0x0000010C, MTRDeviceTypeClass::Simple, @"Color Temperature Light" }, { 0x0000010D, MTRDeviceTypeClass::Simple, @"Extended Color Light" }, + { 0x00000142, MTRDeviceTypeClass::Simple, @"Camera" }, { 0x00000202, MTRDeviceTypeClass::Simple, @"Window Covering" }, { 0x00000203, MTRDeviceTypeClass::Simple, @"Window Covering Controller" }, { 0x00000300, MTRDeviceTypeClass::Simple, @"Heating/Cooling Unit" }, diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index d7c804b5d026bf..1a0b37c8f625d7 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -3691,4 +3691,94 @@ - (void)testMTRDeviceDealloc XCTAssertFalse([controller isRunning]); } +- (void)testMTRDeviceMaybeUnreachableIgnoredIfReceivingFromDevice +{ + __auto_type * storageDelegate = [[MTRTestPerControllerStorageWithBulkReadWrite alloc] initWithControllerID:[NSUUID UUID]]; + + __auto_type * factory = [MTRDeviceControllerFactory sharedInstance]; + XCTAssertNotNil(factory); + + __auto_type queue = dispatch_queue_create("test.queue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + + __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 * subscriptionReportBegin = [self expectationWithDescription:@"Subscription report begin"]; + XCTestExpectation * subscriptionReportEnd = [self expectationWithDescription:@"Subscription report end"]; + + __weak __auto_type weakDelegate = delegate; + delegate.onReportBegin = ^{ + [subscriptionReportBegin fulfill]; + __strong __auto_type strongDelegate = weakDelegate; + strongDelegate.onReportBegin = nil; + }; + + delegate.onReportEnd = ^{ + [subscriptionReportEnd fulfill]; + __strong __auto_type strongDelegate = weakDelegate; + strongDelegate.onReportEnd = nil; + }; + + delegate.onSubscriptionReset = ^{ + XCTFail("Subscription should not be reset from calling _deviceMayBeReachable"); + }; + + [device setDelegate:delegate queue:queue]; + + // First wait for report to begin coming in + [self waitForExpectations:@[ subscriptionReportBegin ] timeout:60]; + + // Call _deviceMayBeReachable and expect it to be ignored + [device _deviceMayBeReachable]; + + [self waitForExpectations:@[ subscriptionReportEnd ] timeout:60]; + + [device _deviceMayBeReachable]; + + // Since subscription reset runs on the matter queue, synchronously run a block on the matter queue here to prove the reset did not happen + [controller syncRunOnWorkQueue:^{ + ; + } error:nil]; + + // 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/MTRDeviceTestDelegate.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h index 4eb0ce75439ac9..e01081183f1b07 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRDeviceTestDelegate.h @@ -37,6 +37,7 @@ typedef void (^MTRDeviceTestDelegateDataHandler)(NSArray controllerDataStore; @end @interface MTRDevice (Test) - (NSMutableArray *)arrayOfNumbersFromAttributeValue:(MTRDeviceDataValueDictionary)dataDictionary; - (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration; +- (void)_deviceMayBeReachable; @end #pragma mark - Declarations for items compiled only for DEBUG configuration diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index c1b0cb48c3fc97..16ed12a0322224 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -438,6 +438,10 @@ B4C8E6B72B3453AD00FCD54D /* MTRDiagnosticLogsDownloader.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4C8E6B42B3453AD00FCD54D /* MTRDiagnosticLogsDownloader.mm */; }; B4D67A412D00DD3D00C49965 /* DFTKeypair.h in Headers */ = {isa = PBXBuildFile; fileRef = B4D67A3F2D00DD3D00C49965 /* DFTKeypair.h */; }; B4D67A422D00DD3D00C49965 /* DFTKeypair.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A402D00DD3D00C49965 /* DFTKeypair.mm */; }; + B4D67A922D527F4A00C49965 /* DCLClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A8E2D527F4A00C49965 /* DCLClient.cpp */; }; + B4D67A932D527F4A00C49965 /* DisplayTermsAndConditions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A8F2D527F4A00C49965 /* DisplayTermsAndConditions.cpp */; }; + B4D67A952D527F4A00C49965 /* JsonSchemaMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A912D527F4A00C49965 /* JsonSchemaMacros.cpp */; }; + B4D67A9B2D538E9700C49965 /* HTTPSRequest.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A992D538E9700C49965 /* HTTPSRequest.mm */; }; B4E262162AA0CF1C00DBA5BC /* RemoteDataModelLogger.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4E262122AA0C7A300DBA5BC /* RemoteDataModelLogger.mm */; }; B4E262172AA0CF2000DBA5BC /* RemoteDataModelLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = B4E262132AA0C7A300DBA5BC /* RemoteDataModelLogger.h */; }; B4E2621B2AA0D02000DBA5BC /* SleepCommand.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4E262192AA0D01D00DBA5BC /* SleepCommand.mm */; }; @@ -455,10 +459,6 @@ CF3B63D12CA31E71003C1C87 /* MTROTAImageTransferHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF3B63CD2CA31E71003C1C87 /* MTROTAImageTransferHandler.mm */; }; CF3B63D22CA31E71003C1C87 /* MTROTAUnsolicitedBDXMessageHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF3B63CE2CA31E71003C1C87 /* MTROTAUnsolicitedBDXMessageHandler.mm */; }; D4288E872C8A273F002FEC53 /* MTRDevice_XPC_Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = D4288E862C8A273F002FEC53 /* MTRDevice_XPC_Internal.h */; }; - B4D67A922D527F4A00C49965 /* DCLClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A8E2D527F4A00C49965 /* DCLClient.cpp */; }; - B4D67A932D527F4A00C49965 /* DisplayTermsAndConditions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A8F2D527F4A00C49965 /* DisplayTermsAndConditions.cpp */; }; - B4D67A952D527F4A00C49965 /* JsonSchemaMacros.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A912D527F4A00C49965 /* JsonSchemaMacros.cpp */; }; - B4D67A9B2D538E9700C49965 /* HTTPSRequest.mm in Sources */ = {isa = PBXBuildFile; fileRef = B4D67A992D538E9700C49965 /* HTTPSRequest.mm */; }; D444F9A72C6E8F9D007761E5 /* MTRXPCServerProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D444F9A62C6E8F9D007761E5 /* MTRXPCServerProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D444F9AA2C6E9A08007761E5 /* MTRXPCClientProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D444F9A82C6E99CA007761E5 /* MTRXPCClientProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D4772A46285AE98400383630 /* MTRClusterConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = D4772A45285AE98300383630 /* MTRClusterConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -648,6 +648,58 @@ 3DECCB6F2934AC1C00585AEC /* MTRLogging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRLogging.h; sourceTree = ""; }; 3DECCB712934AFE200585AEC /* MTRLogging.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRLogging.mm; sourceTree = ""; }; 3DECCB732934C21B00585AEC /* MTRDefines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDefines.h; sourceTree = ""; }; + 3DF521682D5E90BE008F8E52 /* BleApplicationDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BleApplicationDelegate.h; sourceTree = ""; }; + 3DF521692D5E90BE008F8E52 /* BleApplicationDelegateImpl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = BleApplicationDelegateImpl.mm; sourceTree = ""; }; + 3DF5216A2D5E90BE008F8E52 /* BleConnectionDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BleConnectionDelegate.h; sourceTree = ""; }; + 3DF5216B2D5E90BE008F8E52 /* BleConnectionDelegateImpl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = BleConnectionDelegateImpl.mm; sourceTree = ""; }; + 3DF5216C2D5E90BE008F8E52 /* BLEManagerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BLEManagerImpl.h; sourceTree = ""; }; + 3DF5216D2D5E90BE008F8E52 /* BLEManagerImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = BLEManagerImpl.cpp; sourceTree = ""; }; + 3DF5216E2D5E90BE008F8E52 /* BlePlatformConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BlePlatformConfig.h; sourceTree = ""; }; + 3DF5216F2D5E90BE008F8E52 /* BlePlatformDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BlePlatformDelegate.h; sourceTree = ""; }; + 3DF521702D5E90BE008F8E52 /* BlePlatformDelegateImpl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = BlePlatformDelegateImpl.mm; sourceTree = ""; }; + 3DF521712D5E90BE008F8E52 /* BleScannerDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BleScannerDelegate.h; sourceTree = ""; }; + 3DF521722D5E90BE008F8E52 /* BUILD.gn */ = {isa = PBXFileReference; lastKnownFileType = text; path = BUILD.gn; sourceTree = ""; }; + 3DF521732D5E90BE008F8E52 /* CHIPDevicePlatformConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPDevicePlatformConfig.h; sourceTree = ""; }; + 3DF521742D5E90BE008F8E52 /* CHIPDevicePlatformEvent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPDevicePlatformEvent.h; sourceTree = ""; }; + 3DF521752D5E90BE008F8E52 /* CHIPPlatformConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CHIPPlatformConfig.h; sourceTree = ""; }; + 3DF521762D5E90BE008F8E52 /* ConfigurationManagerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConfigurationManagerImpl.h; sourceTree = ""; }; + 3DF521772D5E90BE008F8E52 /* ConfigurationManagerImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ConfigurationManagerImpl.cpp; sourceTree = ""; }; + 3DF521782D5E90BE008F8E52 /* ConnectivityManagerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ConnectivityManagerImpl.h; sourceTree = ""; }; + 3DF521792D5E90BE008F8E52 /* ConnectivityManagerImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ConnectivityManagerImpl.cpp; sourceTree = ""; }; + 3DF5217A2D5E90BE008F8E52 /* DeviceInstanceInfoProviderImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceInstanceInfoProviderImpl.h; sourceTree = ""; }; + 3DF5217B2D5E90BE008F8E52 /* DeviceInstanceInfoProviderImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DeviceInstanceInfoProviderImpl.cpp; sourceTree = ""; }; + 3DF5217C2D5E90BE008F8E52 /* DiagnosticDataProviderImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DiagnosticDataProviderImpl.h; sourceTree = ""; }; + 3DF5217D2D5E90BE008F8E52 /* DiagnosticDataProviderImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DiagnosticDataProviderImpl.cpp; sourceTree = ""; }; + 3DF5217E2D5E90BE008F8E52 /* DispatchQueueNames.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DispatchQueueNames.h; sourceTree = ""; }; + 3DF5217F2D5E90BE008F8E52 /* DispatchQueueNames.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DispatchQueueNames.cpp; sourceTree = ""; }; + 3DF521802D5E90BE008F8E52 /* DnssdContexts.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DnssdContexts.cpp; sourceTree = ""; }; + 3DF521812D5E90BE008F8E52 /* DnssdHostNameRegistrar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DnssdHostNameRegistrar.h; sourceTree = ""; }; + 3DF521822D5E90BE008F8E52 /* DnssdHostNameRegistrar.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DnssdHostNameRegistrar.cpp; sourceTree = ""; }; + 3DF521832D5E90BE008F8E52 /* DnssdImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DnssdImpl.h; sourceTree = ""; }; + 3DF521842D5E90BE008F8E52 /* DnssdImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DnssdImpl.cpp; sourceTree = ""; }; + 3DF521852D5E90BE008F8E52 /* DnssdType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DnssdType.h; sourceTree = ""; }; + 3DF521862D5E90BE008F8E52 /* DnssdType.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DnssdType.cpp; sourceTree = ""; }; + 3DF521872D5E90BE008F8E52 /* InetPlatformConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InetPlatformConfig.h; sourceTree = ""; }; + 3DF521882D5E90BE008F8E52 /* KeyValueStoreManagerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KeyValueStoreManagerImpl.h; sourceTree = ""; }; + 3DF521892D5E90BE008F8E52 /* KeyValueStoreManagerImpl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyValueStoreManagerImpl.mm; sourceTree = ""; }; + 3DF5218A2D5E90BE008F8E52 /* Logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Logging.h; sourceTree = ""; }; + 3DF5218B2D5E90BE008F8E52 /* Logging.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Logging.mm; sourceTree = ""; }; + 3DF5218C2D5E90BE008F8E52 /* MdnsError.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MdnsError.h; sourceTree = ""; }; + 3DF5218D2D5E90BE008F8E52 /* MdnsError.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MdnsError.cpp; sourceTree = ""; }; + 3DF5218E2D5E90BE008F8E52 /* MTRUUIDHelper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRUUIDHelper.h; sourceTree = ""; }; + 3DF5218F2D5E90BE008F8E52 /* MTRUUIDHelperImpl.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRUUIDHelperImpl.mm; sourceTree = ""; }; + 3DF521902D5E90BE008F8E52 /* NetworkCommissioningDriver.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NetworkCommissioningDriver.h; sourceTree = ""; }; + 3DF521912D5E90BE008F8E52 /* PlatformManagerImpl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformManagerImpl.h; sourceTree = ""; }; + 3DF521922D5E90BE008F8E52 /* PlatformManagerImpl.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformManagerImpl.cpp; sourceTree = ""; }; + 3DF521932D5E90BE008F8E52 /* PlatformMetricKeys.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformMetricKeys.h; sourceTree = ""; }; + 3DF521942D5E90BE008F8E52 /* PosixConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PosixConfig.h; sourceTree = ""; }; + 3DF521952D5E90BE008F8E52 /* PosixConfig.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PosixConfig.cpp; sourceTree = ""; }; + 3DF521962D5E90BE008F8E52 /* SystemPlatformConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SystemPlatformConfig.h; sourceTree = ""; }; + 3DF521972D5E90BE008F8E52 /* SystemTimeSupport.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SystemTimeSupport.cpp; sourceTree = ""; }; + 3DF521982D5E90BE008F8E52 /* Tracing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Tracing.h; sourceTree = ""; }; + 3DF521992D5E90BE008F8E52 /* Tracing.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Tracing.mm; sourceTree = ""; }; + 3DF5219A2D5E90BE008F8E52 /* UserDefaults.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = UserDefaults.h; sourceTree = ""; }; + 3DF5219B2D5E90BE008F8E52 /* UserDefaults.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = UserDefaults.mm; sourceTree = ""; }; 3DFCB3282966684500332B35 /* MTRCertificateInfoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRCertificateInfoTests.m; sourceTree = ""; }; 3DFCB32A2966827F00332B35 /* MTRDefines_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDefines_Internal.h; sourceTree = ""; }; 3DFCB32B29678C9500332B35 /* MTRConversion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRConversion.h; sourceTree = ""; }; @@ -948,6 +1000,10 @@ B4C8E6B42B3453AD00FCD54D /* MTRDiagnosticLogsDownloader.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDiagnosticLogsDownloader.mm; sourceTree = ""; }; B4D67A3F2D00DD3D00C49965 /* DFTKeypair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DFTKeypair.h; sourceTree = ""; }; B4D67A402D00DD3D00C49965 /* DFTKeypair.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DFTKeypair.mm; sourceTree = ""; }; + B4D67A8E2D527F4A00C49965 /* DCLClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DCLClient.cpp; path = commands/dcl/DCLClient.cpp; sourceTree = ""; }; + B4D67A8F2D527F4A00C49965 /* DisplayTermsAndConditions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayTermsAndConditions.cpp; path = commands/dcl/DisplayTermsAndConditions.cpp; sourceTree = ""; }; + B4D67A912D527F4A00C49965 /* JsonSchemaMacros.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JsonSchemaMacros.cpp; path = commands/dcl/JsonSchemaMacros.cpp; sourceTree = ""; }; + B4D67A992D538E9700C49965 /* HTTPSRequest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HTTPSRequest.mm; sourceTree = ""; }; B4E262122AA0C7A300DBA5BC /* RemoteDataModelLogger.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = RemoteDataModelLogger.mm; sourceTree = ""; }; B4E262132AA0C7A300DBA5BC /* RemoteDataModelLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoteDataModelLogger.h; sourceTree = ""; }; B4E262192AA0D01D00DBA5BC /* SleepCommand.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = SleepCommand.mm; sourceTree = ""; }; @@ -965,10 +1021,6 @@ CF3B63CD2CA31E71003C1C87 /* MTROTAImageTransferHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROTAImageTransferHandler.mm; sourceTree = ""; }; CF3B63CE2CA31E71003C1C87 /* MTROTAUnsolicitedBDXMessageHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROTAUnsolicitedBDXMessageHandler.mm; sourceTree = ""; }; D4288E862C8A273F002FEC53 /* MTRDevice_XPC_Internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDevice_XPC_Internal.h; sourceTree = ""; }; - B4D67A8E2D527F4A00C49965 /* DCLClient.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DCLClient.cpp; path = commands/dcl/DCLClient.cpp; sourceTree = ""; }; - B4D67A8F2D527F4A00C49965 /* DisplayTermsAndConditions.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DisplayTermsAndConditions.cpp; path = commands/dcl/DisplayTermsAndConditions.cpp; sourceTree = ""; }; - B4D67A912D527F4A00C49965 /* JsonSchemaMacros.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = JsonSchemaMacros.cpp; path = commands/dcl/JsonSchemaMacros.cpp; sourceTree = ""; }; - B4D67A992D538E9700C49965 /* HTTPSRequest.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HTTPSRequest.mm; sourceTree = ""; }; D437613E285BDC0D0051FEA2 /* MTRErrorTestUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRErrorTestUtils.h; sourceTree = ""; }; D437613F285BDC0D0051FEA2 /* MTRTestKeys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRTestKeys.h; sourceTree = ""; }; D4376140285BDC0D0051FEA2 /* MTRTestStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRTestStorage.h; sourceTree = ""; }; @@ -1327,6 +1379,66 @@ path = partials; sourceTree = ""; }; + 3DF521672D5E901D008F8E52 /* platform */ = { + isa = PBXGroup; + children = ( + 3DF521722D5E90BE008F8E52 /* BUILD.gn */, + 3DF521682D5E90BE008F8E52 /* BleApplicationDelegate.h */, + 3DF521692D5E90BE008F8E52 /* BleApplicationDelegateImpl.mm */, + 3DF5216A2D5E90BE008F8E52 /* BleConnectionDelegate.h */, + 3DF5216B2D5E90BE008F8E52 /* BleConnectionDelegateImpl.mm */, + 3DF5216C2D5E90BE008F8E52 /* BLEManagerImpl.h */, + 3DF5216D2D5E90BE008F8E52 /* BLEManagerImpl.cpp */, + 3DF5216E2D5E90BE008F8E52 /* BlePlatformConfig.h */, + 3DF5216F2D5E90BE008F8E52 /* BlePlatformDelegate.h */, + 3DF521702D5E90BE008F8E52 /* BlePlatformDelegateImpl.mm */, + 3DF521712D5E90BE008F8E52 /* BleScannerDelegate.h */, + 3DF521732D5E90BE008F8E52 /* CHIPDevicePlatformConfig.h */, + 3DF521742D5E90BE008F8E52 /* CHIPDevicePlatformEvent.h */, + 3DF521752D5E90BE008F8E52 /* CHIPPlatformConfig.h */, + 3DF521762D5E90BE008F8E52 /* ConfigurationManagerImpl.h */, + 3DF521772D5E90BE008F8E52 /* ConfigurationManagerImpl.cpp */, + 3DF521782D5E90BE008F8E52 /* ConnectivityManagerImpl.h */, + 3DF521792D5E90BE008F8E52 /* ConnectivityManagerImpl.cpp */, + 3DF5217A2D5E90BE008F8E52 /* DeviceInstanceInfoProviderImpl.h */, + 3DF5217B2D5E90BE008F8E52 /* DeviceInstanceInfoProviderImpl.cpp */, + 3DF5217C2D5E90BE008F8E52 /* DiagnosticDataProviderImpl.h */, + 3DF5217D2D5E90BE008F8E52 /* DiagnosticDataProviderImpl.cpp */, + 3DF5217E2D5E90BE008F8E52 /* DispatchQueueNames.h */, + 3DF5217F2D5E90BE008F8E52 /* DispatchQueueNames.cpp */, + 3DF521802D5E90BE008F8E52 /* DnssdContexts.cpp */, + 3DF521812D5E90BE008F8E52 /* DnssdHostNameRegistrar.h */, + 3DF521822D5E90BE008F8E52 /* DnssdHostNameRegistrar.cpp */, + 3DF521832D5E90BE008F8E52 /* DnssdImpl.h */, + 3DF521842D5E90BE008F8E52 /* DnssdImpl.cpp */, + 3DF521852D5E90BE008F8E52 /* DnssdType.h */, + 3DF521862D5E90BE008F8E52 /* DnssdType.cpp */, + 3DF521872D5E90BE008F8E52 /* InetPlatformConfig.h */, + 3DF521882D5E90BE008F8E52 /* KeyValueStoreManagerImpl.h */, + 3DF521892D5E90BE008F8E52 /* KeyValueStoreManagerImpl.mm */, + 3DF5218A2D5E90BE008F8E52 /* Logging.h */, + 3DF5218B2D5E90BE008F8E52 /* Logging.mm */, + 3DF5218C2D5E90BE008F8E52 /* MdnsError.h */, + 3DF5218D2D5E90BE008F8E52 /* MdnsError.cpp */, + 3DF5218E2D5E90BE008F8E52 /* MTRUUIDHelper.h */, + 3DF5218F2D5E90BE008F8E52 /* MTRUUIDHelperImpl.mm */, + 3DF521902D5E90BE008F8E52 /* NetworkCommissioningDriver.h */, + 3DF521912D5E90BE008F8E52 /* PlatformManagerImpl.h */, + 3DF521922D5E90BE008F8E52 /* PlatformManagerImpl.cpp */, + 3DF521932D5E90BE008F8E52 /* PlatformMetricKeys.h */, + 3DF521942D5E90BE008F8E52 /* PosixConfig.h */, + 3DF521952D5E90BE008F8E52 /* PosixConfig.cpp */, + 3DF521962D5E90BE008F8E52 /* SystemPlatformConfig.h */, + 3DF521972D5E90BE008F8E52 /* SystemTimeSupport.cpp */, + 3DF521982D5E90BE008F8E52 /* Tracing.h */, + 3DF521992D5E90BE008F8E52 /* Tracing.mm */, + 3DF5219A2D5E90BE008F8E52 /* UserDefaults.h */, + 3DF5219B2D5E90BE008F8E52 /* UserDefaults.mm */, + ); + name = platform; + path = ../../platform/Darwin; + sourceTree = SOURCE_ROOT; + }; 51189FC72A33ACE900184508 /* TestHelpers */ = { isa = PBXGroup; children = ( @@ -1434,6 +1546,7 @@ B202528F2459E34F00F97062 /* CHIP */, B202529A2459E34F00F97062 /* CHIPTests */, 037C3CA82991A44B00B7EEE2 /* darwin-framework-tool */, + 3DF521672D5E901D008F8E52 /* platform */, B202528E2459E34F00F97062 /* Products */, BA09EB3E2474762900605257 /* Frameworks */, ); diff --git a/src/data-model-providers/codegen/CodegenDataModelProvider.cpp b/src/data-model-providers/codegen/CodegenDataModelProvider.cpp index b891346d170432..7fd6d241704b0e 100644 --- a/src/data-model-providers/codegen/CodegenDataModelProvider.cpp +++ b/src/data-model-providers/codegen/CodegenDataModelProvider.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -267,8 +269,14 @@ CHIP_ERROR CodegenDataModelProvider::Attributes(const ConcreteClusterPath & path VerifyOrReturnValue(cluster->attributeCount > 0, CHIP_NO_ERROR); VerifyOrReturnValue(cluster->attributes != nullptr, CHIP_NO_ERROR); - // TODO: if ember would encode data in AttributeEntry form, we could reference things directly - ReturnErrorOnFailure(builder.EnsureAppendCapacity(cluster->attributeCount)); + // TODO: if ember would encode data in AttributeEntry form, we could reference things directly (shorter code, + // although still allocation overhead due to global attributes not in metadata) + // + // We have Attributes from ember + global attributes that are NOT in ember metadata. + // We have to report them all + constexpr size_t kGlobalAttributeNotInMetadataCount = ArraySize(GlobalAttributesNotInMetadata); + + ReturnErrorOnFailure(builder.EnsureAppendCapacity(cluster->attributeCount + kGlobalAttributeNotInMetadataCount)); Span attributeSpan(cluster->attributes, cluster->attributeCount); @@ -277,6 +285,24 @@ CHIP_ERROR CodegenDataModelProvider::Attributes(const ConcreteClusterPath & path ReturnErrorOnFailure(builder.Append(AttributeEntryFrom(path, attribute))); } + // This "GlobalListEntry" is specific for metadata that ember does not include + // in its attribute list metadata. + // + // By spec these Attribute/AcceptedCommands/GeneratedCommants lists are: + // - lists of elements + // - read-only, with read privilege view + // - fixed value (no such flag exists, so this is not a quality flag we set/track) + DataModel::AttributeEntry globalListEntry; + + globalListEntry.readPrivilege = Access::Privilege::kView; + globalListEntry.flags.Set(DataModel::AttributeQualityFlags::kListAttribute); + + for (auto & attribute : GlobalAttributesNotInMetadata) + { + globalListEntry.attributeId = attribute; + ReturnErrorOnFailure(builder.Append(globalListEntry)); + } + return CHIP_NO_ERROR; } diff --git a/src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp b/src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp index e0d9c159fd3c4a..3160bbdaf26722 100644 --- a/src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp +++ b/src/data-model-providers/codegen/CodegenDataModelProvider_Write.cpp @@ -92,18 +92,6 @@ std::optional TryWriteViaAccessInterface(const ConcreteDataAttribute 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)); - - // TODO: ordering is to check writability/existence BEFORE ACL and this seems wrong, however - // existing unit tests (TC_AcessChecker.py) validate that we get UnsupportedWrite instead of UnsupportedAccess - // - // This should likely be fixed in spec (probably already fixed by - // https://github.com/CHIP-Specifications/connectedhomeip-spec/pull/9024) - // and tests and implementation - // - // Open issue that needs fixing: https://github.com/project-chip/connectedhomeip/issues/33735 - auto metadata = Ember::FindAttributeMetadata(request.path); // Explicit failure in finding a suitable metadata @@ -130,74 +118,11 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat const EmberAfAttributeMetadata ** attributeMetadata = std::get_if(&metadata); VerifyOrDie(*attributeMetadata != nullptr); - // All the global attributes that we do not have metadata for are - // read-only. Specifically only the following list-based attributes match the - // "global attributes not in metadata" (see GlobalAttributes.h :: GlobalAttributesNotInMetadata): - // - AttributeList - // - EventList - // - AcceptedCommands - // - GeneratedCommands + // Extra check: internal requests can bypass the read only check, however global attributes + // have no underlying storage, so write still cannot be done // - // Given the above, UnsupportedWrite should be correct (attempt to write to a read-only list) - bool isReadOnly = (*attributeMetadata)->IsReadOnly(); - - // Internal is allowed to bypass timed writes and read-only. - if (!request.operationFlags.Has(DataModel::OperationFlags::kInternal)) - { - VerifyOrReturnError(!isReadOnly, Status::UnsupportedWrite); - } - - // ACL check for non-internal requests - bool checkAcl = !request.operationFlags.Has(DataModel::OperationFlags::kInternal); - - // For chunking, ACL check is not re-done if the previous write was successful for the exact same - // path. We apply this everywhere as a shortcut, although realistically this is only for AccessControl cluster - if (checkAcl && request.previousSuccessPath.has_value()) - { - // NOTE: explicit cast/check only for attribute path and nothing else. - // - // In particular `request.path` is a DATA path (contains a list index) - // and we do not want request.previousSuccessPath to be auto-cast to a - // data path with a empty list and fail the compare. - // - // This could be `request.previousSuccessPath != request.path` (where order - // is important) however that would seem more brittle (relying that a != b - // behaves differently than b != a due to casts). Overall Data paths are not - // the same as attribute paths. - // - // Also note that Concrete path have a mExpanded that is not used in compares. - const ConcreteAttributePath & attributePathA = request.path; - const ConcreteAttributePath & attributePathB = *request.previousSuccessPath; - - checkAcl = (attributePathA != attributePathB); - } - - if (checkAcl) - { - VerifyOrReturnError(request.subjectDescriptor != nullptr, Status::UnsupportedAccess); - - Access::RequestPath requestPath{ .cluster = request.path.mClusterId, - .endpoint = request.path.mEndpointId, - .requestType = Access::RequestType::kAttributeWriteRequest, - .entityId = request.path.mAttributeId }; - CHIP_ERROR err = Access::GetAccessControl().Check(*request.subjectDescriptor, requestPath, - RequiredPrivilege::ForWriteAttribute(request.path)); - - if (err != CHIP_NO_ERROR) - { - VerifyOrReturnValue(err != CHIP_ERROR_ACCESS_DENIED, Status::UnsupportedAccess); - VerifyOrReturnValue(err != CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL, Status::AccessRestricted); - - return err; - } - } - - // Internal is allowed to bypass timed writes and read-only. - if (!request.operationFlags.Has(DataModel::OperationFlags::kInternal)) - { - VerifyOrReturnError(!(*attributeMetadata)->MustUseTimedWrite() || request.writeFlags.Has(DataModel::WriteFlags::kTimed), - Status::NeedsTimedInteraction); - } + // I.e. if we get a `EmberAfCluster*` value from finding metadata, we fail here. + VerifyOrReturnError(attributeMetadata != nullptr, Status::UnsupportedWrite); if (request.path.mDataVersion.HasValue()) { diff --git a/src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp b/src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp index 4d54a194b1e0c5..a0b0dcd7ba1a15 100644 --- a/src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp +++ b/src/data-model-providers/codegen/tests/TestCodegenModelViaMocks.cpp @@ -1073,7 +1073,7 @@ TEST_F(TestCodegenModelViaMocks, IterateOverAttributes) EXPECT_EQ(model.Attributes(ConcreteClusterPath(kMockEndpoint2, MockClusterId(2)), builder), CHIP_NO_ERROR); auto attributes = builder.TakeBuffer(); - ASSERT_EQ(attributes.size(), 4u); + ASSERT_EQ(attributes.size(), 7u); ASSERT_EQ(attributes[0].attributeId, ClusterRevision::Id); ASSERT_FALSE(attributes[0].flags.Has(AttributeQualityFlags::kListAttribute)); @@ -1086,6 +1086,16 @@ TEST_F(TestCodegenModelViaMocks, IterateOverAttributes) ASSERT_EQ(attributes[3].attributeId, MockAttributeId(2)); ASSERT_TRUE(attributes[3].flags.Has(AttributeQualityFlags::kListAttribute)); + + // Ends with global list attributes + ASSERT_EQ(attributes[4].attributeId, GeneratedCommandList::Id); + ASSERT_TRUE(attributes[4].flags.Has(AttributeQualityFlags::kListAttribute)); + + ASSERT_EQ(attributes[5].attributeId, AcceptedCommandList::Id); + ASSERT_TRUE(attributes[5].flags.Has(AttributeQualityFlags::kListAttribute)); + + ASSERT_EQ(attributes[6].attributeId, AttributeList::Id); + ASSERT_TRUE(attributes[6].flags.Has(AttributeQualityFlags::kListAttribute)); } TEST_F(TestCodegenModelViaMocks, FindAttribute) @@ -1127,7 +1137,7 @@ TEST_F(TestCodegenModelViaMocks, FindAttribute) EXPECT_FALSE(info->writePrivilege.has_value()); // NOLINT(bugprone-unchecked-optional-access) } -// global attributes are EXPLICITLY not supported +// global attributes are EXPLICITLY supported TEST_F(TestCodegenModelViaMocks, GlobalAttributeInfo) { UseMockNodeConfig config(gTestNodeConfig); @@ -1138,10 +1148,14 @@ TEST_F(TestCodegenModelViaMocks, GlobalAttributeInfo) std::optional info = finder.Find( ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), Clusters::Globals::Attributes::GeneratedCommandList::Id)); - ASSERT_FALSE(info.has_value()); + ASSERT_TRUE(info.has_value()); info = finder.Find(ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), Clusters::Globals::Attributes::AttributeList::Id)); - ASSERT_FALSE(info.has_value()); + ASSERT_TRUE(info.has_value()); + + info = finder.Find( + ConcreteAttributePath(kMockEndpoint1, MockClusterId(1), Clusters::Globals::Attributes::AcceptedCommandList::Id)); + ASSERT_TRUE(info.has_value()); } TEST_F(TestCodegenModelViaMocks, IterateOverAcceptedCommands) @@ -1905,29 +1919,6 @@ TEST_F(TestCodegenModelViaMocks, AttributeAccessInterfaceListIncrementalRead) } } -TEST_F(TestCodegenModelViaMocks, EmberAttributeWriteAclDeny) -{ - UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelProviderWithContext model; - ScopedMockAccessControl accessControl; - - /* Using this path is also failing existence checks, so this cannot be enabled - * until we fix ordering of ACL to be done before existence checks - - WriteOperation test(kMockEndpoint1, MockClusterId(1), MockAttributeId(10)); - AttributeValueDecoder decoder = test.DecoderFor(1234); - - ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), Status::UnsupportedAccess); - ASSERT_TRUE(model.ChangeListener().DirtyList().empty()); - */ - - WriteOperation test(kMockEndpoint3, MockClusterId(4), MOCK_ATTRIBUTE_ID_FOR_NULLABLE_TYPE(ZCL_INT32U_ATTRIBUTE_TYPE)); - AttributeValueDecoder decoder = test.DecoderFor(1234); - - ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), Status::UnsupportedAccess); - ASSERT_TRUE(model.ChangeListener().DirtyList().empty()); -} - TEST_F(TestCodegenModelViaMocks, EmberAttributeWriteBasicTypes) { TestEmberScalarTypeWrite(0x12); @@ -2208,42 +2199,6 @@ TEST_F(TestCodegenModelViaMocks, EmberAttributeWriteLongBytes) EXPECT_EQ(writtenData[4], 13u); } -TEST_F(TestCodegenModelViaMocks, EmberAttributeWriteTimedWrite) -{ - UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelProviderWithContext model; - ScopedMockAccessControl accessControl; - - WriteOperation test(kMockEndpoint3, MockClusterId(4), kAttributeIdTimedWrite); - test.SetSubjectDescriptor(kAdminSubjectDescriptor); - - AttributeValueDecoder decoder = test.DecoderFor(1234); - - ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), Status::NeedsTimedInteraction); - - // writing as timed should be fine - test.SetWriteFlags(WriteFlags::kTimed); - ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), CHIP_NO_ERROR); -} - -TEST_F(TestCodegenModelViaMocks, EmberAttributeWriteReadOnlyAttribute) -{ - UseMockNodeConfig config(gTestNodeConfig); - CodegenDataModelProviderWithContext model; - ScopedMockAccessControl accessControl; - - WriteOperation test(kMockEndpoint3, MockClusterId(4), kAttributeIdReadOnly); - test.SetSubjectDescriptor(kAdminSubjectDescriptor); - - AttributeValueDecoder decoder = test.DecoderFor(1234); - - ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), Status::UnsupportedWrite); - - // Internal writes bypass the read only requirement - test.SetOperationFlags(OperationFlags::kInternal); - ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), CHIP_NO_ERROR); -} - TEST_F(TestCodegenModelViaMocks, EmberAttributeWriteDataVersion) { UseMockNodeConfig config(gTestNodeConfig); diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp index 383e14fed3a680..1230a91517bc69 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp +++ b/src/include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp @@ -46,18 +46,7 @@ CHIP_ERROR GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(void) vTaskSetTimeOutState(&mNextTimerBaseTime); mNextTimerDurationTicks = 0; - // TODO: This nulling out of mEventLoopTask should happen when we shut down - // the task, not here! - mEventLoopTask = NULL; -#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING - mBackgroundEventLoopTask = NULL; -#endif - mChipTimerActive = false; - - // We support calling Shutdown followed by InitChipStack, because some tests - // do that. To keep things simple for existing consumers, we keep not - // destroying our lock and queue in shutdown, but rather check whether they - // already exist here before trying to create them. + mChipTimerActive = false; if (mChipStackLock == NULL) { @@ -277,10 +266,11 @@ template void GenericPlatformManagerImpl_FreeRTOS::EventLoopTaskMain(void * arg) { ChipLogDetail(DeviceLayer, "CHIP event task running"); - static_cast *>(arg)->Impl()->RunEventLoop(); - // TODO: At this point, should we not - // vTaskDelete(static_cast *>(arg)->mEventLoopTask)? - // Or somehow get our caller to do it once this thread is joined? + GenericPlatformManagerImpl_FreeRTOS * platformManager = + static_cast *>(arg); + platformManager->Impl()->RunEventLoop(); + vTaskDelete(NULL); + platformManager->mEventLoopTask = NULL; } template @@ -376,7 +366,11 @@ template void GenericPlatformManagerImpl_FreeRTOS::BackgroundEventLoopTaskMain(void * arg) { ChipLogDetail(DeviceLayer, "CHIP background task running"); - static_cast *>(arg)->Impl()->RunBackgroundEventLoop(); + GenericPlatformManagerImpl_FreeRTOS * platformManager = + static_cast *>(arg); + platformManager->Impl()->RunBackgroundEventLoop(); + vTaskDelete(NULL); + platformManager->mBackgroundEventLoopTask = NULL; } #endif @@ -416,6 +410,20 @@ void GenericPlatformManagerImpl_FreeRTOS::PostEventFromISR(const Chip template void GenericPlatformManagerImpl_FreeRTOS::_Shutdown(void) { + if (mChipEventQueue) + { + vQueueDelete(mChipEventQueue); + mChipEventQueue = NULL; + } +#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING + if (mBackgroundEventQueue) + { + vQueueDelete(mBackgroundEventQueue); + mBackgroundEventQueue = NULL; + } +#endif + vSemaphoreDelete(mChipStackLock); + mChipStackLock = NULL; GenericPlatformManagerImpl::_Shutdown(); } diff --git a/src/messaging/tests/java/BUILD.gn b/src/messaging/tests/java/BUILD.gn index c33257846ca8f5..021d937add2a0c 100644 --- a/src/messaging/tests/java/BUILD.gn +++ b/src/messaging/tests/java/BUILD.gn @@ -79,11 +79,11 @@ android_library("java") { javac_flags = [ "-Xlint:deprecation" ] # TODO: add classpath support (we likely need to add something like - # ..../platforms/android-26/android.jar to access BLE items) + # ..../platforms/android-30/android.jar to access BLE items) } if (!matter_enable_java_compilation) { java_prebuilt("android") { - jar_path = "${android_sdk_root}/platforms/android-26/android.jar" + jar_path = "${android_sdk_root}/platforms/android-30/android.jar" } } diff --git a/src/platform/Darwin/UserDefaults.h b/src/platform/Darwin/UserDefaults.h index 5df5d2064256b9..46796048df4426 100644 --- a/src/platform/Darwin/UserDefaults.h +++ b/src/platform/Darwin/UserDefaults.h @@ -18,11 +18,14 @@ #include #include +#include namespace chip { namespace Platform { std::optional GetUserDefaultDnssdSRPTimeoutInMSecs(); +std::optional GetUserDefaultBDXThrottleIntervalForThread(); + } // namespace Platform } // namespace chip diff --git a/src/platform/Darwin/UserDefaults.mm b/src/platform/Darwin/UserDefaults.mm index e28c1fa90fc0de..e731d0dd24a17b 100644 --- a/src/platform/Darwin/UserDefaults.mm +++ b/src/platform/Darwin/UserDefaults.mm @@ -23,6 +23,8 @@ static NSString * const kSRPTimeoutInMsecsUserDefaultKey = @"SRPTimeoutInMSecsOverride"; +static NSString * const kBDXThrottleIntervalInMsecsUserDefaultKey = @"BDXThrottleIntervalForThreadDevicesInMSecs"; + namespace chip { namespace Platform { @@ -38,5 +40,21 @@ return std::nullopt; } + std::optional GetUserDefaultBDXThrottleIntervalForThread() + { + NSUserDefaults * defaults = [NSUserDefaults standardUserDefaults]; + NSInteger bdxThrottleIntervalInMsecs = [defaults integerForKey:kBDXThrottleIntervalInMsecsUserDefaultKey]; + + if (bdxThrottleIntervalInMsecs > 0 && CanCastTo(bdxThrottleIntervalInMsecs)) { + uint16_t intervalInMsecs = static_cast(bdxThrottleIntervalInMsecs); + ChipLogProgress(BDX, "Got a user default value for BDX Throttle Interval for Thread devices - %d msecs", intervalInMsecs); + return std::make_optional(System::Clock::Milliseconds16(intervalInMsecs)); + } + + // For now return NullOptional if value returned in bdxThrottleIntervalInMsecs is 0, since that either means the key was not found or value was zero. + // Since 0 is not a feasible value for this interval for now, we will treat that as not being set. + return std::nullopt; + } + } // namespace Platform } // namespace chip diff --git a/src/platform/ESP32/SystemTimeSupport.cpp b/src/platform/ESP32/SystemTimeSupport.cpp index 613e79b6067858..266bef5e67389a 100644 --- a/src/platform/ESP32/SystemTimeSupport.cpp +++ b/src/platform/ESP32/SystemTimeSupport.cpp @@ -94,9 +94,9 @@ CHIP_ERROR ClockImpl::SetClock_RealTime(Microseconds64 aNewCurTime) const time_t timep = tv.tv_sec; struct tm calendar; localtime_r(&timep, &calendar); - ChipLogProgress(DeviceLayer, "Real time clock set to %lld (%04d/%02d/%02d %02d:%02d:%02d UTC)", - static_cast(tv.tv_sec), calendar.tm_year, calendar.tm_mon, calendar.tm_mday, calendar.tm_hour, - calendar.tm_min, calendar.tm_sec); + char time_str[64]; + strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S UTC", &calendar); + ChipLogProgress(DeviceLayer, "Real time clock set to %lld (%s)", static_cast(tv.tv_sec), time_str); } #endif // CHIP_PROGRESS_LOGGING return CHIP_NO_ERROR; diff --git a/src/platform/ESP32/nimble/BLEManagerImpl.cpp b/src/platform/ESP32/nimble/BLEManagerImpl.cpp index 0a2ddb176332b2..5ce08f1d727ca8 100644 --- a/src/platform/ESP32/nimble/BLEManagerImpl.cpp +++ b/src/platform/ESP32/nimble/BLEManagerImpl.cpp @@ -925,7 +925,8 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void) SuccessOrExit(err); #endif - nimble_port_init(); + err = MapBLEError(nimble_port_init()); + SuccessOrExit(err); /* Initialize the NimBLE host configuration. */ ble_hs_cfg.reset_cb = bleprph_on_reset; @@ -973,7 +974,9 @@ CHIP_ERROR BLEManagerImpl::InitESPBleLayer(void) void BLEManagerImpl::DeinitESPBleLayer() { VerifyOrReturn(DeinitBLE() == CHIP_NO_ERROR); +#ifdef CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING BLEManagerImpl::ClaimBLEMemory(nullptr, nullptr); +#endif /* CONFIG_USE_BLE_ONLY_FOR_COMMISSIONING */ } void BLEManagerImpl::ClaimBLEMemory(System::Layer *, void *) diff --git a/src/platform/Linux/ConnectivityManagerImpl.cpp b/src/platform/Linux/ConnectivityManagerImpl.cpp index 0ba16f90d874a9..050eab734bdceb 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.cpp +++ b/src/platform/Linux/ConnectivityManagerImpl.cpp @@ -84,13 +84,13 @@ namespace chip { #if CHIP_DEVICE_CONFIG_ENABLE_WPA template <> -struct GAutoPtrDeleter +struct GAutoPtrDeleter { using deleter = GObjectDeleter; }; template <> -struct GAutoPtrDeleter +struct GAutoPtrDeleter { using deleter = GObjectDeleter; }; @@ -234,7 +234,7 @@ bool ConnectivityManagerImpl::_IsWiFiStationConnected() return false; } - state = wpa_fi_w1_wpa_supplicant1_interface_get_state(mWpaSupplicant.iface); + state = wpa_supplicant_1_interface_get_state(mWpaSupplicant.iface); if (g_strcmp0(state, "completed") == 0) { mConnectivityFlag.Set(ConnectivityFlags::kHaveIPv4InternetConnectivity) @@ -263,7 +263,7 @@ bool ConnectivityManagerImpl::_IsWiFiStationProvisioned() return false; } - bss = wpa_fi_w1_wpa_supplicant1_interface_get_current_bss(mWpaSupplicant.iface); + bss = wpa_supplicant_1_interface_get_current_bss(mWpaSupplicant.iface); if (g_str_match_string("BSSs", bss, true)) { ret = true; @@ -285,7 +285,7 @@ void ConnectivityManagerImpl::_ClearWiFiStationProvision() if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) { GAutoPtr err; - wpa_fi_w1_wpa_supplicant1_interface_call_remove_all_networks_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); + wpa_supplicant_1_interface_call_remove_all_networks_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); if (err != nullptr) { @@ -394,7 +394,7 @@ void ConnectivityManagerImpl::UpdateNetworkStatus() MakeOptional(GetDisconnectReason())); } -void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * changedProperties) +void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaSupplicant1Interface * proxy, GVariant * changedProperties) { std::lock_guard lock(mWpaSupplicantMutex); @@ -422,7 +422,7 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte } else if (g_strcmp0(value_str.get(), "\'disconnected\'") == 0) { - gint reason = wpa_fi_w1_wpa_supplicant1_interface_get_disconnect_reason(mWpaSupplicant.iface); + gint reason = wpa_supplicant_1_interface_get_disconnect_reason(mWpaSupplicant.iface); if (delegate) { @@ -444,13 +444,13 @@ void ConnectivityManagerImpl::_OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Inte case WLAN_REASON_DISASSOC_LOW_ACK: case WLAN_REASON_BSS_TRANSITION_DISASSOC: associationFailureCause = static_cast(AssociationFailureCauseEnum::kAssociationFailed); - status = wpa_fi_w1_wpa_supplicant1_interface_get_assoc_status_code(mWpaSupplicant.iface); + status = wpa_supplicant_1_interface_get_assoc_status_code(mWpaSupplicant.iface); break; case WLAN_REASON_PREV_AUTH_NOT_VALID: case WLAN_REASON_DEAUTH_LEAVING: case WLAN_REASON_IEEE_802_1X_AUTH_FAILED: associationFailureCause = static_cast(AssociationFailureCauseEnum::kAuthenticationFailed); - status = wpa_fi_w1_wpa_supplicant1_interface_get_auth_status_code(mWpaSupplicant.iface); + status = wpa_supplicant_1_interface_get_auth_status_code(mWpaSupplicant.iface); break; default: break; @@ -515,7 +515,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * sourceObject, std::lock_guard lock(mWpaSupplicantMutex); - WpaFiW1Wpa_supplicant1Interface * iface = wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus_finish(res, &err.GetReceiver()); + WpaSupplicant1Interface * iface = wpa_supplicant_1_interface_proxy_new_for_bus_finish(res, &err.GetReceiver()); if (mWpaSupplicant.iface) { @@ -529,14 +529,13 @@ void ConnectivityManagerImpl::_OnWpaInterfaceProxyReady(GObject * sourceObject, mWpaSupplicant.state = GDBusWpaSupplicant::WpaState::INTERFACE_CONNECTED; ChipLogProgress(DeviceLayer, "wpa_supplicant: connected to wpa_supplicant interface proxy"); - g_signal_connect( - mWpaSupplicant.iface, "properties-changed", - G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * properties, ConnectivityManagerImpl * self) { - return self->_OnWpaPropertiesChanged(proxy, properties); - }), - this); + g_signal_connect(mWpaSupplicant.iface, "properties-changed", + G_CALLBACK(+[](WpaSupplicant1Interface * proxy, GVariant * properties, ConnectivityManagerImpl * self) { + return self->_OnWpaPropertiesChanged(proxy, properties); + }), + this); g_signal_connect(mWpaSupplicant.iface, "scan-done", - G_CALLBACK(+[](WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success, ConnectivityManagerImpl * self) { + G_CALLBACK(+[](WpaSupplicant1Interface * proxy, gboolean success, ConnectivityManagerImpl * self) { return self->_OnWpaInterfaceScanDone(proxy, success); }), this); @@ -569,7 +568,7 @@ void ConnectivityManagerImpl::_OnWpaBssProxyReady(GObject * sourceObject, GAsync std::lock_guard lock(mWpaSupplicantMutex); - WpaFiW1Wpa_supplicant1BSS * bss = wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus_finish(res, &err.GetReceiver()); + WpaSupplicant1BSS * bss = wpa_supplicant_1_bss_proxy_new_for_bus_finish(res, &err.GetReceiver()); if (mWpaSupplicant.bss) { @@ -599,14 +598,14 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * sourceObject, GAsyn std::lock_guard lock(mWpaSupplicantMutex); - gboolean result = wpa_fi_w1_wpa_supplicant1_call_get_interface_finish(mWpaSupplicant.proxy, &mWpaSupplicant.interfacePath, res, - &err.GetReceiver()); + gboolean result = + wpa_supplicant_1_call_get_interface_finish(mWpaSupplicant.proxy, &mWpaSupplicant.interfacePath, res, &err.GetReceiver()); if (result) { mWpaSupplicant.state = GDBusWpaSupplicant::WpaState::GOT_INTERFACE_PATH; ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface: %s", mWpaSupplicant.interfacePath); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + wpa_supplicant_1_interface_proxy_new_for_bus( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, reinterpret_cast( +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { @@ -614,7 +613,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * sourceObject, GAsyn }), this); - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + wpa_supplicant_1_bss_proxy_new_for_bus( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, reinterpret_cast( +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { @@ -637,8 +636,8 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * sourceObject, GAsyn g_variant_builder_add(&builder, "{sv}", "Ifname", g_variant_new_string(CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME)); args = g_variant_builder_end(&builder); - result = wpa_fi_w1_wpa_supplicant1_call_create_interface_sync(mWpaSupplicant.proxy, args, &mWpaSupplicant.interfacePath, - nullptr, &error.GetReceiver()); + result = wpa_supplicant_1_call_create_interface_sync(mWpaSupplicant.proxy, args, &mWpaSupplicant.interfacePath, nullptr, + &error.GetReceiver()); if (result) { @@ -647,7 +646,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * sourceObject, GAsyn Platform::CopyString(sWiFiIfName, CHIP_DEVICE_CONFIG_WIFI_STATION_IF_NAME); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + wpa_supplicant_1_interface_proxy_new_for_bus( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, reinterpret_cast( +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { @@ -655,7 +654,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * sourceObject, GAsyn }), this); - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + wpa_supplicant_1_bss_proxy_new_for_bus( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, reinterpret_cast( +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { @@ -679,7 +678,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceReady(GObject * sourceObject, GAsyn } } -void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties) +void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaSupplicant1 * proxy, const char * path, GVariant * properties) { // When creating D-Bus proxy object, the thread default context must be initialized. Otherwise, // all D-Bus signals will be delivered to the GLib global default main context. @@ -698,7 +697,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * prox mWpaSupplicant.state = GDBusWpaSupplicant::WpaState::GOT_INTERFACE_PATH; ChipLogProgress(DeviceLayer, "wpa_supplicant: WiFi interface added: %s", mWpaSupplicant.interfacePath); - wpa_fi_w1_wpa_supplicant1_interface_proxy_new_for_bus( + wpa_supplicant_1_interface_proxy_new_for_bus( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, reinterpret_cast( +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { @@ -706,7 +705,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * prox }), this); - wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus( + wpa_supplicant_1_bss_proxy_new_for_bus( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, mWpaSupplicant.interfacePath, nullptr, reinterpret_cast( +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { @@ -716,7 +715,7 @@ void ConnectivityManagerImpl::_OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * prox } } -void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties) +void ConnectivityManagerImpl::_OnWpaInterfaceRemoved(WpaSupplicant1 * proxy, const char * path, GVariant * properties) { std::lock_guard lock(mWpaSupplicantMutex); @@ -763,7 +762,7 @@ void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * sourceObject, GAsyncRes std::lock_guard lock(mWpaSupplicantMutex); - mWpaSupplicant.proxy = wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus_finish(res, &err.GetReceiver()); + mWpaSupplicant.proxy = wpa_supplicant_1_proxy_new_for_bus_finish(res, &err.GetReceiver()); if (mWpaSupplicant.proxy != nullptr && err.get() == nullptr) { mWpaSupplicant.state = GDBusWpaSupplicant::WpaState::CONNECTED; @@ -771,22 +770,23 @@ void ConnectivityManagerImpl::_OnWpaProxyReady(GObject * sourceObject, GAsyncRes g_signal_connect( mWpaSupplicant.proxy, "interface-added", - G_CALLBACK(+[](WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties, - ConnectivityManagerImpl * self) { return self->_OnWpaInterfaceAdded(proxy, path, properties); }), + G_CALLBACK(+[](WpaSupplicant1 * proxy, const char * path, GVariant * properties, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceAdded(proxy, path, properties); + }), this); g_signal_connect( mWpaSupplicant.proxy, "interface-removed", - G_CALLBACK(+[](WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties, - ConnectivityManagerImpl * self) { return self->_OnWpaInterfaceRemoved(proxy, path, properties); }), + G_CALLBACK(+[](WpaSupplicant1 * proxy, const char * path, GVariant * properties, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceRemoved(proxy, path, properties); + }), this); - wpa_fi_w1_wpa_supplicant1_call_get_interface( - mWpaSupplicant.proxy, sWiFiIfName, nullptr, - reinterpret_cast( - +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { - return self->_OnWpaInterfaceReady(sourceObject_, res_); - }), - this); + wpa_supplicant_1_call_get_interface(mWpaSupplicant.proxy, sWiFiIfName, nullptr, + reinterpret_cast( + +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { + return self->_OnWpaInterfaceReady(sourceObject_, res_); + }), + this); } else { @@ -878,11 +878,11 @@ CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFPublish(ConnectivityManager::WiFiPAF 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()); + wpa_supplicant_1_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) { + G_CALLBACK(+[](WpaSupplicant1Interface * proxy, GVariant * obj, ConnectivityManagerImpl * self) { return self->OnNanReceive(obj); }), this); @@ -896,7 +896,7 @@ CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFCancelPublish() 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()); + wpa_supplicant_1_interface_call_nancancel_publish_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); return CHIP_NO_ERROR; } @@ -1020,7 +1020,7 @@ void ConnectivityManagerImpl::DriveAPState() { GAutoPtr error(nullptr); - gboolean result = wpa_fi_w1_wpa_supplicant1_interface_call_remove_network_sync( + gboolean result = wpa_supplicant_1_interface_call_remove_network_sync( mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, &error.GetReceiver()); if (result) @@ -1085,8 +1085,8 @@ CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP() g_variant_builder_add(&builder, "{sv}", "frequency", g_variant_new_int32(channel)); args = g_variant_builder_end(&builder); - gboolean result = wpa_fi_w1_wpa_supplicant1_interface_call_add_network_sync( - mWpaSupplicant.iface, args, &mWpaSupplicant.networkPath, nullptr, &err.GetReceiver()); + gboolean result = wpa_supplicant_1_interface_call_add_network_sync(mWpaSupplicant.iface, args, &mWpaSupplicant.networkPath, + nullptr, &err.GetReceiver()); if (result) { @@ -1094,8 +1094,8 @@ CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP() ChipLogProgress(DeviceLayer, "wpa_supplicant: added network: SSID: %s: %s", ssid, mWpaSupplicant.networkPath); - result = wpa_fi_w1_wpa_supplicant1_interface_call_select_network_sync(mWpaSupplicant.iface, mWpaSupplicant.networkPath, - nullptr, &error.GetReceiver()); + result = wpa_supplicant_1_interface_call_select_network_sync(mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, + &error.GetReceiver()); if (result) { ChipLogProgress(DeviceLayer, "wpa_supplicant: succeeded to start softAP: SSID: %s", ssid); @@ -1148,15 +1148,15 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args, GAutoPtr err; gboolean result; - const gchar * networkPath = wpa_fi_w1_wpa_supplicant1_interface_get_current_network(mWpaSupplicant.iface); + const gchar * networkPath = wpa_supplicant_1_interface_get_current_network(mWpaSupplicant.iface); // wpa_supplicant DBus API: if network path of current network is not "/", means we have already selected some network. if (strcmp(networkPath, "/") != 0) { GAutoPtr error; - result = wpa_fi_w1_wpa_supplicant1_interface_call_remove_network_sync(mWpaSupplicant.iface, networkPath, nullptr, - &error.GetReceiver()); + result = + wpa_supplicant_1_interface_call_remove_network_sync(mWpaSupplicant.iface, networkPath, nullptr, &error.GetReceiver()); if (result) { @@ -1177,18 +1177,18 @@ ConnectivityManagerImpl::_ConnectWiFiNetworkAsync(GVariant * args, SuccessOrExit(ret); } - result = wpa_fi_w1_wpa_supplicant1_interface_call_add_network_sync(mWpaSupplicant.iface, args, &mWpaSupplicant.networkPath, - nullptr, &err.GetReceiver()); + result = wpa_supplicant_1_interface_call_add_network_sync(mWpaSupplicant.iface, args, &mWpaSupplicant.networkPath, nullptr, + &err.GetReceiver()); if (result) { // Note: wpa_supplicant will return immediately if the network is already connected, but it will still try reconnect in the // background. The client still need to wait for a few seconds for this reconnect operation. So we always disconnect from // the network we are connected and ignore any errors. - wpa_fi_w1_wpa_supplicant1_interface_call_disconnect_sync(mWpaSupplicant.iface, nullptr, nullptr); + wpa_supplicant_1_interface_call_disconnect_sync(mWpaSupplicant.iface, nullptr, nullptr); ChipLogProgress(DeviceLayer, "wpa_supplicant: added network: %s", mWpaSupplicant.networkPath); - wpa_fi_w1_wpa_supplicant1_interface_call_select_network( + wpa_supplicant_1_interface_call_select_network( mWpaSupplicant.iface, mWpaSupplicant.networkPath, nullptr, reinterpret_cast( +[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { @@ -1243,14 +1243,14 @@ ConnectivityManagerImpl::ConnectWiFiNetworkAsync(ByteSpan ssid, ByteSpan credent } #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_PDC -static CHIP_ERROR AddOrReplaceBlob(WpaFiW1Wpa_supplicant1Interface * iface, const char * nameOrRef, ByteSpan data) +static CHIP_ERROR AddOrReplaceBlob(WpaSupplicant1Interface * iface, const char * nameOrRef, ByteSpan data) { // Strip the blob:// prefix off the name (if present), so we don't need as many string constants. constexpr auto refPrefix = "blob://"_span; const char * name = (strncmp(nameOrRef, refPrefix.data(), refPrefix.size()) == 0) ? nameOrRef + refPrefix.size() : nameOrRef; GAutoPtr err; - if (!wpa_fi_w1_wpa_supplicant1_interface_call_remove_blob_sync(iface, name, nullptr, &err.GetReceiver())) + if (!wpa_supplicant_1_interface_call_remove_blob_sync(iface, name, nullptr, &err.GetReceiver())) { GAutoPtr remoteError(g_dbus_error_get_remote_error(err.get())); if (!(remoteError && strcmp(remoteError.get(), kWpaSupplicantBlobUnknown) == 0)) @@ -1260,7 +1260,7 @@ static CHIP_ERROR AddOrReplaceBlob(WpaFiW1Wpa_supplicant1Interface * iface, cons } err.reset(); } - if (!wpa_fi_w1_wpa_supplicant1_interface_call_add_blob_sync( + if (!wpa_supplicant_1_interface_call_add_blob_sync( iface, name, g_variant_new_fixed_array(G_VARIANT_TYPE_BYTE, data.data(), data.size(), 1), nullptr, &err.GetReceiver())) { ChipLogError(DeviceLayer, "wpa_supplicant: failed to add blob: %s", err ? err->message : "unknown error"); @@ -1489,27 +1489,27 @@ CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFConnect(const SetupDiscriminator & c 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()); + wpa_supplicant_1_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, + G_CALLBACK(+[](WpaSupplicant1Interface * 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) { + G_CALLBACK(+[](WpaSupplicant1Interface * 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); }), + G_CALLBACK(+[](WpaSupplicant1Interface * proxy, gint term_subscribe_id, gint reason, ConnectivityManagerImpl * self) { + return self->OnNanSubscribeTerminated(term_subscribe_id, reason); + }), this); return CHIP_NO_ERROR; @@ -1525,7 +1525,7 @@ CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFCancelConnect() 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()); + wpa_supplicant_1_interface_call_nancancel_subscribe_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); return CHIP_NO_ERROR; } @@ -1570,7 +1570,7 @@ CHIP_ERROR ConnectivityManagerImpl::_WiFiPAFSend(System::PacketBufferHandle && m 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()); + wpa_supplicant_1_interface_call_nantransmit_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); ChipLogProgress(Controller, "WiFi-PAF: Outbound message (%lu) done", msgBuf->DataLength()); return ret; } @@ -1584,8 +1584,7 @@ void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * sourceO std::lock_guard lock(mWpaSupplicantMutex); { - gboolean result = - wpa_fi_w1_wpa_supplicant1_interface_call_select_network_finish(mWpaSupplicant.iface, res, &err.GetReceiver()); + gboolean result = wpa_supplicant_1_interface_call_select_network_finish(mWpaSupplicant.iface, res, &err.GetReceiver()); if (!result) { ChipLogError(DeviceLayer, "Failed to perform connect network: %s", err == nullptr ? "unknown error" : err->message); @@ -1602,7 +1601,7 @@ void ConnectivityManagerImpl::_ConnectWiFiNetworkAsyncCallback(GObject * sourceO return; } - result = wpa_fi_w1_wpa_supplicant1_interface_call_save_config_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); + result = wpa_supplicant_1_interface_call_save_config_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); if (result) { ChipLogProgress(DeviceLayer, "wpa_supplicant: save config succeeded!"); @@ -1677,7 +1676,7 @@ CHIP_ERROR ConnectivityManagerImpl::CommitConfig() ChipLogProgress(DeviceLayer, "wpa_supplicant: save config"); - result = wpa_fi_w1_wpa_supplicant1_interface_call_save_config_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); + result = wpa_supplicant_1_interface_call_save_config_sync(mWpaSupplicant.iface, nullptr, &err.GetReceiver()); if (!result) { @@ -1744,7 +1743,7 @@ CHIP_ERROR ConnectivityManagerImpl::GetWiFiSecurityType(SecurityTypeEnum & secur return CHIP_ERROR_INCORRECT_STATE; } - mode = wpa_fi_w1_wpa_supplicant1_interface_get_current_auth_mode(mWpaSupplicant.iface); + mode = wpa_supplicant_1_interface_get_current_auth_mode(mWpaSupplicant.iface); ChipLogProgress(DeviceLayer, "wpa_supplicant: current Wi-Fi security type: %s", StringOrNullMarker(mode)); if (strncmp(mode, "WPA-PSK", 7) == 0) @@ -1796,7 +1795,7 @@ int32_t ConnectivityManagerImpl::GetDisconnectReason() std::lock_guard lock(mWpaSupplicantMutex); GAutoPtr err; - gint errorValue = wpa_fi_w1_wpa_supplicant1_interface_get_disconnect_reason(mWpaSupplicant.iface); + gint errorValue = wpa_supplicant_1_interface_get_disconnect_reason(mWpaSupplicant.iface); // wpa_supplicant DBus API: DisconnectReason: The most recent IEEE 802.11 reason code for disconnect. Negative value // indicates locally generated disconnection. return errorValue; @@ -1818,7 +1817,7 @@ CHIP_ERROR ConnectivityManagerImpl::GetConfiguredNetwork(NetworkCommissioning::N return CHIP_ERROR_INCORRECT_STATE; } - const gchar * networkPath = wpa_fi_w1_wpa_supplicant1_interface_get_current_network(mWpaSupplicant.iface); + const gchar * networkPath = wpa_supplicant_1_interface_get_current_network(mWpaSupplicant.iface); // wpa_supplicant DBus API: if network path of current network is "/", means no networks is currently selected. if ((networkPath == nullptr) || (strcmp(networkPath, "/") == 0)) @@ -1826,15 +1825,15 @@ CHIP_ERROR ConnectivityManagerImpl::GetConfiguredNetwork(NetworkCommissioning::N return CHIP_ERROR_KEY_NOT_FOUND; } - GAutoPtr networkInfo(wpa_fi_w1_wpa_supplicant1_network_proxy_new_for_bus_sync( + GAutoPtr networkInfo(wpa_supplicant_1_network_proxy_new_for_bus_sync( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, networkPath, nullptr, &err.GetReceiver())); if (networkInfo == nullptr) { return CHIP_ERROR_INTERNAL; } - network.connected = wpa_fi_w1_wpa_supplicant1_network_get_enabled(networkInfo.get()); - GVariant * properties = wpa_fi_w1_wpa_supplicant1_network_get_properties(networkInfo.get()); + network.connected = wpa_supplicant_1_network_get_enabled(networkInfo.get()); + GVariant * properties = wpa_supplicant_1_network_get_properties(networkInfo.get()); GAutoPtr ssid(g_variant_lookup_value(properties, "ssid", nullptr)); gsize length; const gchar * ssidStr = g_variant_get_string(ssid.get(), &length); @@ -1857,8 +1856,8 @@ CHIP_ERROR ConnectivityManagerImpl::StopAutoScan() ChipLogDetail(DeviceLayer, "wpa_supplicant: disabling auto scan"); - result = wpa_fi_w1_wpa_supplicant1_interface_call_auto_scan_sync( - mWpaSupplicant.iface, "" /* empty string means disabling auto scan */, nullptr, &err.GetReceiver()); + result = wpa_supplicant_1_interface_call_auto_scan_sync(mWpaSupplicant.iface, "" /* empty string means disabling auto scan */, + nullptr, &err.GetReceiver()); if (!result) { ChipLogError(DeviceLayer, "wpa_supplicant: Failed to stop auto network scan: %s", err ? err->message : "unknown"); @@ -1888,7 +1887,7 @@ CHIP_ERROR ConnectivityManagerImpl::StartWiFiScan(ByteSpan ssid, WiFiDriver::Sca g_variant_builder_add(&builder, "{sv}", "Type", g_variant_new_string("active")); args = g_variant_builder_end(&builder); - result = wpa_fi_w1_wpa_supplicant1_interface_call_scan_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); + result = wpa_supplicant_1_interface_call_scan_sync(mWpaSupplicant.iface, args, nullptr, &err.GetReceiver()); if (result) { @@ -2015,7 +2014,7 @@ bool ConnectivityManagerImpl::_GetBssInfo(const gchar * bssPath, NetworkCommissi // with the proxy object. GAutoPtr err; - GAutoPtr bss(wpa_fi_w1_wpa_supplicant1_bss_proxy_new_for_bus_sync( + GAutoPtr bss(wpa_supplicant_1_bss_proxy_new_for_bus_sync( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, bssPath, nullptr, &err.GetReceiver())); if (bss == nullptr) @@ -2023,7 +2022,7 @@ bool ConnectivityManagerImpl::_GetBssInfo(const gchar * bssPath, NetworkCommissi return false; } - WpaFiW1Wpa_supplicant1BSSProxy * bssProxy = WPA_FI_W1_WPA_SUPPLICANT1_BSS_PROXY(bss.get()); + WpaSupplicant1BSSProxy * bssProxy = WPA_SUPPLICANT_1_BSS_PROXY(bss.get()); GAutoPtr ssid(g_dbus_proxy_get_cached_property(G_DBUS_PROXY(bssProxy), "SSID")); GAutoPtr bssid(g_dbus_proxy_get_cached_property(G_DBUS_PROXY(bssProxy), "BSSID")); @@ -2041,8 +2040,8 @@ bool ConnectivityManagerImpl::_GetBssInfo(const gchar * bssPath, NetworkCommissi char bssidStr[2 * 6 + 5 + 1] = { 0 }; gsize ssidLen = 0; gsize bssidLen = 0; - gint16 signal = wpa_fi_w1_wpa_supplicant1_bss_get_signal(bss.get()); - guint16 frequency = wpa_fi_w1_wpa_supplicant1_bss_get_frequency(bss.get()); + gint16 signal = wpa_supplicant_1_bss_get_signal(bss.get()); + guint16 frequency = wpa_supplicant_1_bss_get_frequency(bss.get()); ssidStr = reinterpret_cast(g_variant_get_fixed_array(ssid.get(), &ssidLen, sizeof(guchar))); bssidBuf = reinterpret_cast(g_variant_get_fixed_array(bssid.get(), &bssidLen, sizeof(guchar))); @@ -2135,7 +2134,7 @@ bool ConnectivityManagerImpl::_GetBssInfo(const gchar * bssPath, NetworkCommissi return res; }; - auto GetNetworkSecurityType = [IsNetworkWPAPSK, IsNetworkWPA2PSK](WpaFiW1Wpa_supplicant1BSSProxy * proxy) -> uint8_t { + auto GetNetworkSecurityType = [IsNetworkWPAPSK, IsNetworkWPA2PSK](WpaSupplicant1BSSProxy * proxy) -> uint8_t { GAutoPtr wpa(g_dbus_proxy_get_cached_property(G_DBUS_PROXY(proxy), "WPA")); GAutoPtr rsn(g_dbus_proxy_get_cached_property(G_DBUS_PROXY(proxy), "RSN")); @@ -2174,12 +2173,12 @@ bool ConnectivityManagerImpl::_GetBssInfo(const gchar * bssPath, NetworkCommissi return true; } -void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success) +void ConnectivityManagerImpl::_OnWpaInterfaceScanDone(WpaSupplicant1Interface * proxy, gboolean success) { std::lock_guard lock(mWpaSupplicantMutex); ChipLogProgress(DeviceLayer, "wpa_supplicant: network scan done"); - gchar ** bsss = wpa_fi_w1_wpa_supplicant1_interface_dup_bsss(mWpaSupplicant.iface); + gchar ** bsss = wpa_supplicant_1_interface_dup_bsss(mWpaSupplicant.iface); gchar ** oldBsss = bsss; if (bsss == nullptr) { @@ -2235,7 +2234,7 @@ CHIP_ERROR ConnectivityManagerImpl::_StartWiFiManagement() VerifyOrDie(g_main_context_get_thread_default() != nullptr); ChipLogProgress(DeviceLayer, "wpa_supplicant: Start WiFi management"); - wpa_fi_w1_wpa_supplicant1_proxy_new_for_bus( + wpa_supplicant_1_proxy_new_for_bus( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kWpaSupplicantServiceName, kWpaSupplicantObjectPath, nullptr, reinterpret_cast(+[](GObject * sourceObject_, GAsyncResult * res_, ConnectivityManagerImpl * self) { return self->_OnWpaProxyReady(sourceObject_, res_); diff --git a/src/platform/Linux/ConnectivityManagerImpl.h b/src/platform/Linux/ConnectivityManagerImpl.h index 2025f228532961..deb014a00e1610 100644 --- a/src/platform/Linux/ConnectivityManagerImpl.h +++ b/src/platform/Linux/ConnectivityManagerImpl.h @@ -86,13 +86,13 @@ struct GDBusWpaSupplicant SCANNING, }; - WpaState state = WpaState::INIT; - WpaScanningState scanState = WpaScanningState::IDLE; - WpaFiW1Wpa_supplicant1 * proxy = nullptr; - WpaFiW1Wpa_supplicant1Interface * iface = nullptr; - WpaFiW1Wpa_supplicant1BSS * bss = nullptr; - gchar * interfacePath = nullptr; - gchar * networkPath = nullptr; + WpaState state = WpaState::INIT; + WpaScanningState scanState = WpaScanningState::IDLE; + WpaSupplicant1 * proxy = nullptr; + WpaSupplicant1Interface * iface = nullptr; + WpaSupplicant1BSS * bss = nullptr; + gchar * interfacePath = nullptr; + gchar * networkPath = nullptr; }; #endif @@ -222,10 +222,10 @@ class ConnectivityManagerImpl final : public ConnectivityManager, CHIP_ERROR StopAutoScan(); void _OnWpaProxyReady(GObject * sourceObject, GAsyncResult * res); - void _OnWpaInterfaceRemoved(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties); - void _OnWpaInterfaceAdded(WpaFiW1Wpa_supplicant1 * proxy, const char * path, GVariant * properties); - void _OnWpaPropertiesChanged(WpaFiW1Wpa_supplicant1Interface * proxy, GVariant * properties); - void _OnWpaInterfaceScanDone(WpaFiW1Wpa_supplicant1Interface * proxy, gboolean success); + void _OnWpaInterfaceRemoved(WpaSupplicant1 * proxy, const char * path, GVariant * properties); + void _OnWpaInterfaceAdded(WpaSupplicant1 * proxy, const char * path, GVariant * properties); + void _OnWpaPropertiesChanged(WpaSupplicant1Interface * proxy, GVariant * properties); + void _OnWpaInterfaceScanDone(WpaSupplicant1Interface * proxy, gboolean success); void _OnWpaInterfaceReady(GObject * sourceObject, GAsyncResult * res); void _OnWpaInterfaceProxyReady(GObject * sourceObject, GAsyncResult * res); void _OnWpaBssProxyReady(GObject * sourceObject, GAsyncResult * res); diff --git a/src/platform/Linux/ThreadStackManagerImpl.cpp b/src/platform/Linux/ThreadStackManagerImpl.cpp index 76fd478a050f89..a67942be8dac06 100644 --- a/src/platform/Linux/ThreadStackManagerImpl.cpp +++ b/src/platform/Linux/ThreadStackManagerImpl.cpp @@ -51,7 +51,7 @@ namespace { struct SetActiveDatasetContext { - OpenthreadIoOpenthreadBorderRouter * proxy; + OpenthreadBorderRouter * proxy; ByteSpan netInfo; }; @@ -67,7 +67,7 @@ CHIP_ERROR GLibMatterContextSetActiveDataset(SetActiveDatasetContext * context) GAutoPtr value(g_variant_new_from_bytes(G_VARIANT_TYPE_BYTESTRING, bytes.release(), true)); if (!value) return CHIP_ERROR_NO_MEMORY; - openthread_io_openthread_border_router_set_active_dataset_tlvs(context->proxy, value.release()); + openthread_border_router_set_active_dataset_tlvs(context->proxy, value.release()); return CHIP_NO_ERROR; } @@ -82,9 +82,9 @@ CHIP_ERROR ThreadStackManagerImpl::GLibMatterContextInitThreadStack(ThreadStackM VerifyOrDie(g_main_context_get_thread_default() != nullptr); GAutoPtr err; - self->mProxy.reset(openthread_io_openthread_border_router_proxy_new_for_bus_sync( - G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, kDBusOpenThreadService, kDBusOpenThreadObjectPath, nullptr, - &err.GetReceiver())); + self->mProxy.reset(openthread_border_router_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, + kDBusOpenThreadService, kDBusOpenThreadObjectPath, nullptr, + &err.GetReceiver())); VerifyOrReturnError( self->mProxy != nullptr, CHIP_ERROR_INTERNAL, ChipLogError(DeviceLayer, "openthread: failed to create openthread dbus proxy %s", err ? err->message : "unknown error")); @@ -103,7 +103,7 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack() // If get property is called inside dbus thread (we are going to make it so), XXX_get_XXX can be used instead of XXX_dup_XXX // which is a little bit faster and the returned object doesn't need to be freed. Same for all following get properties. - GAutoPtr role(openthread_io_openthread_border_router_dup_device_role(mProxy.get())); + GAutoPtr role(openthread_border_router_dup_device_role(mProxy.get())); if (role) { ThreadDeviceRoleChangedHandler(role.get()); @@ -112,7 +112,7 @@ CHIP_ERROR ThreadStackManagerImpl::_InitThreadStack() return CHIP_NO_ERROR; } -void ThreadStackManagerImpl::OnDbusPropertiesChanged(OpenthreadIoOpenthreadBorderRouter * proxy, GVariant * changed_properties, +void ThreadStackManagerImpl::OnDbusPropertiesChanged(OpenthreadBorderRouter * proxy, GVariant * changed_properties, const gchar * const * invalidated_properties, gpointer user_data) { ThreadStackManagerImpl * me = reinterpret_cast(user_data); @@ -182,7 +182,7 @@ bool ThreadStackManagerImpl::_HaveRouteToAddress(const Inet::IPAddress & destAdd return true; } - GAutoPtr routes(openthread_io_openthread_border_router_dup_external_routes(mProxy.get())); + GAutoPtr routes(openthread_border_router_dup_external_routes(mProxy.get())); if (!routes) return false; @@ -368,7 +368,7 @@ bool ThreadStackManagerImpl::_IsThreadAttached() const CHIP_ERROR ThreadStackManagerImpl::GLibMatterContextCallAttach(ThreadStackManagerImpl * self) { VerifyOrDie(g_main_context_get_thread_default() != nullptr); - openthread_io_openthread_border_router_call_attach(self->mProxy.get(), nullptr, _OnThreadBrAttachFinished, self); + openthread_border_router_call_attach(self->mProxy.get(), nullptr, _OnThreadBrAttachFinished, self); return CHIP_NO_ERROR; } @@ -383,7 +383,7 @@ CHIP_ERROR ThreadStackManagerImpl::_SetThreadEnabled(bool val) else { GAutoPtr err; - gboolean result = openthread_io_openthread_border_router_call_reset_sync(mProxy.get(), nullptr, &err.GetReceiver()); + gboolean result = openthread_border_router_call_reset_sync(mProxy.get(), nullptr, &err.GetReceiver()); if (err) { ChipLogError(DeviceLayer, "openthread: _SetThreadEnabled calling %s failed: %s", "Reset", err->message); @@ -405,7 +405,7 @@ void ThreadStackManagerImpl::_OnThreadBrAttachFinished(GObject * source_object, GAutoPtr attachRes; GAutoPtr err; { - gboolean result = openthread_io_openthread_border_router_call_attach_finish(this_->mProxy.get(), res, &err.GetReceiver()); + gboolean result = openthread_border_router_call_attach_finish(this_->mProxy.get(), res, &err.GetReceiver()); if (!result) { ChipLogError(DeviceLayer, "Failed to perform finish Thread network scan: %s", @@ -442,7 +442,7 @@ ConnectivityManager::ThreadDeviceType ThreadStackManagerImpl::_GetThreadDeviceTy return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported; } - GAutoPtr role(openthread_io_openthread_border_router_dup_device_role(mProxy.get())); + GAutoPtr role(openthread_border_router_dup_device_role(mProxy.get())); if (!role) return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported; if (strcmp(role.get(), kOpenthreadDeviceRoleDetached) == 0 || strcmp(role.get(), kOpenthreadDeviceRoleDisabled) == 0) @@ -451,7 +451,7 @@ ConnectivityManager::ThreadDeviceType ThreadStackManagerImpl::_GetThreadDeviceTy } if (strcmp(role.get(), kOpenthreadDeviceRoleChild) == 0) { - GAutoPtr linkMode(openthread_io_openthread_border_router_dup_link_mode(mProxy.get())); + GAutoPtr linkMode(openthread_border_router_dup_link_mode(mProxy.get())); if (!linkMode) return ConnectivityManager::ThreadDeviceType::kThreadDeviceType_NotSupported; gboolean rx_on_when_idle; @@ -499,7 +499,7 @@ CHIP_ERROR ThreadStackManagerImpl::_SetThreadDeviceType(ConnectivityManager::Thr GAutoPtr linkMode(g_variant_new("(bbb)", rx_on_when_idle, device_type, network_data)); if (!linkMode) return CHIP_ERROR_NO_MEMORY; - openthread_io_openthread_border_router_set_link_mode(mProxy.get(), linkMode.release()); + openthread_border_router_set_link_mode(mProxy.get(), linkMode.release()); } return CHIP_NO_ERROR; @@ -546,7 +546,7 @@ CHIP_ERROR ThreadStackManagerImpl::_GetAndLogThreadTopologyFull() CHIP_ERROR ThreadStackManagerImpl::_GetPrimary802154MACAddress(uint8_t * buf) { VerifyOrReturnError(mProxy, CHIP_ERROR_INCORRECT_STATE); - guint64 extAddr = openthread_io_openthread_border_router_get_extended_address(mProxy.get()); + guint64 extAddr = openthread_border_router_get_extended_address(mProxy.get()); for (size_t i = 0; i < sizeof(extAddr); i++) { @@ -579,7 +579,7 @@ CHIP_ERROR ThreadStackManagerImpl::_GetPollPeriod(uint32_t & buf) CHIP_ERROR ThreadStackManagerImpl::GLibMatterContextCallScan(ThreadStackManagerImpl * self) { VerifyOrDie(g_main_context_get_thread_default() != nullptr); - openthread_io_openthread_border_router_call_scan(self->mProxy.get(), nullptr, _OnNetworkScanFinished, self); + openthread_border_router_call_scan(self->mProxy.get(), nullptr, _OnNetworkScanFinished, self); return CHIP_NO_ERROR; } @@ -604,8 +604,8 @@ void ThreadStackManagerImpl::_OnNetworkScanFinished(GAsyncResult * res) GAutoPtr scan_result; GAutoPtr err; { - gboolean result = openthread_io_openthread_border_router_call_scan_finish(mProxy.get(), &scan_result.GetReceiver(), res, - &err.GetReceiver()); + gboolean result = + openthread_border_router_call_scan_finish(mProxy.get(), &scan_result.GetReceiver(), res, &err.GetReceiver()); if (!result) { ChipLogError(DeviceLayer, "Failed to perform finish Thread network scan: %s", diff --git a/src/platform/Linux/ThreadStackManagerImpl.h b/src/platform/Linux/ThreadStackManagerImpl.h index 685348a4ae4a72..20cf85f2faf54c 100755 --- a/src/platform/Linux/ThreadStackManagerImpl.h +++ b/src/platform/Linux/ThreadStackManagerImpl.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -31,7 +31,7 @@ namespace chip { template <> -struct GAutoPtrDeleter +struct GAutoPtrDeleter { using deleter = GObjectDeleter; }; @@ -149,12 +149,12 @@ class ThreadStackManagerImpl : public ThreadStackManager uint8_t lqi; }; - GAutoPtr mProxy; + GAutoPtr mProxy; static CHIP_ERROR GLibMatterContextInitThreadStack(ThreadStackManagerImpl * self); static CHIP_ERROR GLibMatterContextCallAttach(ThreadStackManagerImpl * self); static CHIP_ERROR GLibMatterContextCallScan(ThreadStackManagerImpl * self); - static void OnDbusPropertiesChanged(OpenthreadIoOpenthreadBorderRouter * proxy, GVariant * changed_properties, + static void OnDbusPropertiesChanged(OpenthreadBorderRouter * proxy, GVariant * changed_properties, const gchar * const * invalidated_properties, gpointer user_data); void ThreadDeviceRoleChangedHandler(const gchar * role); diff --git a/src/platform/Linux/bluez/AdapterIterator.cpp b/src/platform/Linux/bluez/AdapterIterator.cpp index dd51ea470ae319..b2f9e394f2de69 100644 --- a/src/platform/Linux/bluez/AdapterIterator.cpp +++ b/src/platform/Linux/bluez/AdapterIterator.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include "BluezObjectIterator.h" #include "BluezObjectList.h" diff --git a/src/platform/Linux/bluez/AdapterIterator.h b/src/platform/Linux/bluez/AdapterIterator.h index 3de2db068fb634..8a85795dfb9424 100644 --- a/src/platform/Linux/bluez/AdapterIterator.h +++ b/src/platform/Linux/bluez/AdapterIterator.h @@ -20,7 +20,7 @@ #include #include -#include +#include #include "BluezObjectIterator.h" #include "BluezObjectManager.h" diff --git a/src/platform/Linux/bluez/BluezAdvertisement.cpp b/src/platform/Linux/bluez/BluezAdvertisement.cpp index 859c1bf64fa07b..40db7a17032e1f 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.cpp +++ b/src/platform/Linux/bluez/BluezAdvertisement.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include "BluezEndpoint.h" diff --git a/src/platform/Linux/bluez/BluezAdvertisement.h b/src/platform/Linux/bluez/BluezAdvertisement.h index fcae7713a43efc..9b69e297cef524 100644 --- a/src/platform/Linux/bluez/BluezAdvertisement.h +++ b/src/platform/Linux/bluez/BluezAdvertisement.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "BluezEndpoint.h" #include "Types.h" diff --git a/src/platform/Linux/bluez/BluezConnection.cpp b/src/platform/Linux/bluez/BluezConnection.cpp index d39411d18d6aef..24c9c2d7f3df14 100644 --- a/src/platform/Linux/bluez/BluezConnection.cpp +++ b/src/platform/Linux/bluez/BluezConnection.cpp @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/platform/Linux/bluez/BluezConnection.h b/src/platform/Linux/bluez/BluezConnection.h index f4efb3a5b22f2b..773b3928e2e57d 100644 --- a/src/platform/Linux/bluez/BluezConnection.h +++ b/src/platform/Linux/bluez/BluezConnection.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include "Types.h" diff --git a/src/platform/Linux/bluez/BluezEndpoint.cpp b/src/platform/Linux/bluez/BluezEndpoint.cpp index 9915abceb49712..9b873a707ff99b 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.cpp +++ b/src/platform/Linux/bluez/BluezEndpoint.cpp @@ -66,7 +66,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/platform/Linux/bluez/BluezEndpoint.h b/src/platform/Linux/bluez/BluezEndpoint.h index 01821bf11c6507..457062e7bb5292 100644 --- a/src/platform/Linux/bluez/BluezEndpoint.h +++ b/src/platform/Linux/bluez/BluezEndpoint.h @@ -55,7 +55,7 @@ #include #include #include -#include +#include #include "BluezConnection.h" #include "BluezObjectManager.h" diff --git a/src/platform/Linux/bluez/BluezObjectIterator.h b/src/platform/Linux/bluez/BluezObjectIterator.h index 6b177acd03027b..4df65295c6ca54 100644 --- a/src/platform/Linux/bluez/BluezObjectIterator.h +++ b/src/platform/Linux/bluez/BluezObjectIterator.h @@ -22,7 +22,7 @@ #include #include -#include +#include namespace chip { namespace DeviceLayer { diff --git a/src/platform/Linux/bluez/BluezObjectList.h b/src/platform/Linux/bluez/BluezObjectList.h index c79141f6a73cad..bff461e0d82626 100644 --- a/src/platform/Linux/bluez/BluezObjectList.h +++ b/src/platform/Linux/bluez/BluezObjectList.h @@ -21,7 +21,7 @@ #include #include -#include +#include #include "BluezObjectIterator.h" diff --git a/src/platform/Linux/bluez/BluezObjectManager.cpp b/src/platform/Linux/bluez/BluezObjectManager.cpp index 3a694dd64601d3..c11e15c07a27ef 100644 --- a/src/platform/Linux/bluez/BluezObjectManager.cpp +++ b/src/platform/Linux/bluez/BluezObjectManager.cpp @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include "Types.h" diff --git a/src/platform/Linux/bluez/ChipDeviceScanner.h b/src/platform/Linux/bluez/ChipDeviceScanner.h index 274af60d32d442..e0043e83172718 100644 --- a/src/platform/Linux/bluez/ChipDeviceScanner.h +++ b/src/platform/Linux/bluez/ChipDeviceScanner.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include "BluezObjectManager.h" diff --git a/src/platform/Linux/bluez/Types.h b/src/platform/Linux/bluez/Types.h index 4bd2c89d9a7966..3c1d60cdd4c234 100644 --- a/src/platform/Linux/bluez/Types.h +++ b/src/platform/Linux/bluez/Types.h @@ -50,7 +50,7 @@ #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE -#include +#include namespace chip { diff --git a/src/platform/Linux/dbus/bluez/BUILD.gn b/src/platform/Linux/dbus/bluez/BUILD.gn index 308feccb9b8b35..a90c3429a01619 100644 --- a/src/platform/Linux/dbus/bluez/BUILD.gn +++ b/src/platform/Linux/dbus/bluez/BUILD.gn @@ -17,7 +17,7 @@ import("//build_overrides/chip.gni") import("${chip_root}/build/chip/linux/gdbus_library.gni") gdbus_library("bluez") { - sources = [ "DbusBluez.xml" ] + sources = [ "DBusBluez.xml" ] c_namespace = "Bluez" interface_prefix = "org.bluez" diff --git a/src/platform/Linux/dbus/bluez/DbusBluez.xml b/src/platform/Linux/dbus/bluez/DBusBluez.xml similarity index 96% rename from src/platform/Linux/dbus/bluez/DbusBluez.xml rename to src/platform/Linux/dbus/bluez/DBusBluez.xml index 1e193ceafb8586..601a555365c9cb 100644 --- a/src/platform/Linux/dbus/bluez/DbusBluez.xml +++ b/src/platform/Linux/dbus/bluez/DBusBluez.xml @@ -1,4 +1,3 @@ - + @@ -158,9 +159,9 @@ diff --git a/src/platform/Linux/dbus/openthread/BUILD.gn b/src/platform/Linux/dbus/openthread/BUILD.gn index b18b534c2e1b6d..9aca9d806d7301 100644 --- a/src/platform/Linux/dbus/openthread/BUILD.gn +++ b/src/platform/Linux/dbus/openthread/BUILD.gn @@ -17,9 +17,10 @@ import("//build_overrides/chip.gni") import("${chip_root}/build/chip/linux/gdbus_library.gni") gdbus_library("openthread") { - sources = [ "introspect.xml" ] + sources = [ "DBusOpenthread.xml" ] c_namespace = "Openthread" + interface_prefix = "io.openthread" c_generate_object_manager = false dbus_out_dir = "platform/Linux/dbus/openthread" } diff --git a/src/platform/Linux/dbus/openthread/DBusOpenthread.xml b/src/platform/Linux/dbus/openthread/DBusOpenthread.xml new file mode 100644 index 00000000000000..3e48e5ca625d0e --- /dev/null +++ b/src/platform/Linux/dbus/openthread/DBusOpenthread.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/platform/Linux/dbus/openthread/introspect.xml b/src/platform/Linux/dbus/openthread/introspect.xml deleted file mode 100644 index a520c0afbfae5f..00000000000000 --- a/src/platform/Linux/dbus/openthread/introspect.xml +++ /dev/null @@ -1,476 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/platform/Linux/dbus/wpa/BUILD.gn b/src/platform/Linux/dbus/wpa/BUILD.gn index 5080622540339c..2cd77d02eb23a2 100644 --- a/src/platform/Linux/dbus/wpa/BUILD.gn +++ b/src/platform/Linux/dbus/wpa/BUILD.gn @@ -24,7 +24,8 @@ gdbus_library("wpa") { "DBusWpaNetwork.xml", ] - c_namespace = "Wpa" + c_namespace = "WpaSupplicant" + interface_prefix = "fi.w1.wpa_supplicant" c_generate_object_manager = false dbus_out_dir = "platform/Linux/dbus/wpa" } diff --git a/src/platform/Linux/dbus/wpa/DBusWpa.xml b/src/platform/Linux/dbus/wpa/DBusWpa.xml index f43d6916e76b10..395dc3f3542eb9 100644 --- a/src/platform/Linux/dbus/wpa/DBusWpa.xml +++ b/src/platform/Linux/dbus/wpa/DBusWpa.xml @@ -1,36 +1,42 @@ - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/platform/Linux/dbus/wpa/DBusWpaBss.xml b/src/platform/Linux/dbus/wpa/DBusWpaBss.xml index 8ec5c4aa749dcb..feabafdc42b14a 100644 --- a/src/platform/Linux/dbus/wpa/DBusWpaBss.xml +++ b/src/platform/Linux/dbus/wpa/DBusWpaBss.xml @@ -1,19 +1,25 @@ - - + + + + - - - - - - - - - - - - diff --git a/src/platform/Linux/dbus/wpa/DBusWpaInterface.xml b/src/platform/Linux/dbus/wpa/DBusWpaInterface.xml index 721ca0033cca09..1669c2ae0f0fd1 100644 --- a/src/platform/Linux/dbus/wpa/DBusWpaInterface.xml +++ b/src/platform/Linux/dbus/wpa/DBusWpaInterface.xml @@ -1,33 +1,57 @@ - - + + + + + + + - - - + + - - - + + + - - - - - + @@ -35,266 +59,47 @@ - - - - + - - - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - diff --git a/src/platform/Linux/dbus/wpa/DBusWpaNetwork.xml b/src/platform/Linux/dbus/wpa/DBusWpaNetwork.xml index 1b0ea70f4d0ca6..ec78e6fe229ce9 100644 --- a/src/platform/Linux/dbus/wpa/DBusWpaNetwork.xml +++ b/src/platform/Linux/dbus/wpa/DBusWpaNetwork.xml @@ -1,10 +1,25 @@ - - + + + + - - - diff --git a/src/platform/NuttX/ThreadStackManagerImpl.h b/src/platform/NuttX/ThreadStackManagerImpl.h index ce66d51c2201a2..b511da0f3b7af3 100644 --- a/src/platform/NuttX/ThreadStackManagerImpl.h +++ b/src/platform/NuttX/ThreadStackManagerImpl.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include diff --git a/src/platform/Zephyr/InetUtils.cpp b/src/platform/Zephyr/InetUtils.cpp index a4879884da41f0..b692cdafa80c59 100644 --- a/src/platform/Zephyr/InetUtils.cpp +++ b/src/platform/Zephyr/InetUtils.cpp @@ -45,7 +45,7 @@ net_if * GetWiFiInterface() { // TODO: Remove dependency after Telink Zephyr update // net_if_get_first_wifi() is not available in Zephyr 3.3.99 -#if !defined(CONFIG_SOC_SERIES_RISCV_TELINK_W91) +#if !defined(CONFIG_SOC_RISCV_TELINK_W91) return net_if_get_first_wifi(); #else return GetInterface(); diff --git a/src/platform/android/BUILD.gn b/src/platform/android/BUILD.gn index e5e915a850fa06..52be2673fffdb9 100644 --- a/src/platform/android/BUILD.gn +++ b/src/platform/android/BUILD.gn @@ -142,5 +142,5 @@ android_library("java") { } java_prebuilt("android_sdk") { - jar_path = "${android_sdk_root}/platforms/android-26/android.jar" + jar_path = "${android_sdk_root}/platforms/android-30/android.jar" } diff --git a/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.cpp b/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.cpp index 87136268afd0d2..3da54f09457664 100644 --- a/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.cpp +++ b/src/platform/bouffalolab/BL602/NetworkCommissioningDriver.cpp @@ -268,7 +268,7 @@ void BLWiFiDriver::OnScanWiFiNetworkDone() } wifi_mgmr_ap_item_t * ScanResult = (wifi_mgmr_ap_item_t *) pvPortMalloc(ap_num * sizeof(wifi_mgmr_ap_item_t)); - wifi_mgmr_get_scan_result(ScanResult, &ap_num, 0, mScanSSID); + wifi_mgmr_get_scan_result(ScanResult, &ap_num, mScanType, mScanSSID); if (ScanResult) { diff --git a/src/platform/bouffalolab/BL616/ThreadStackManagerImpl.cpp b/src/platform/bouffalolab/BL616/ThreadStackManagerImpl.cpp index 251ccf5113a294..17d73f9ea2309e 100644 --- a/src/platform/bouffalolab/BL616/ThreadStackManagerImpl.cpp +++ b/src/platform/bouffalolab/BL616/ThreadStackManagerImpl.cpp @@ -63,6 +63,12 @@ bool ThreadStackManagerImpl::IsInitialized() return sInstance.mThreadStackLock != NULL; } +void ThreadStackManagerImpl::FactoryResetThreadStack(void) +{ + VerifyOrReturn(ThreadStackMgrImpl().OTInstance() != NULL); + otInstanceFactoryReset(ThreadStackMgrImpl().OTInstance()); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/bouffalolab/BL702/ConnectivityManagerImpl.cpp b/src/platform/bouffalolab/BL702/ConnectivityManagerImpl.cpp index 24df9f365ad4ba..4b2b8b736a4016 100644 --- a/src/platform/bouffalolab/BL702/ConnectivityManagerImpl.cpp +++ b/src/platform/bouffalolab/BL702/ConnectivityManagerImpl.cpp @@ -106,8 +106,15 @@ extern "C" void wifiInterface_eventGotIP(struct netif * interface) extern "C" void wifiInterface_eventScanDone(struct netif * interface, netbus_fs_scan_ind_cmd_msg_t * pmsg) { + ChipDeviceEvent event; + ChipLogProgress(DeviceLayer, "wifiInterface_eventScanDone"); + + memset(&event, 0, sizeof(ChipDeviceEvent)); NetworkCommissioning::BLWiFiDriver::GetInstance().OnScanWiFiNetworkDone(pmsg); + + event.Type = kWiFiOnScanDone; + PlatformMgr().PostEventOrDie(&event); } #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI diff --git a/src/platform/bouffalolab/BL702/NetworkCommissioningDriver.cpp b/src/platform/bouffalolab/BL702/NetworkCommissioningDriver.cpp index 22df7c3b4f90c2..43f813a7587450 100644 --- a/src/platform/bouffalolab/BL702/NetworkCommissioningDriver.cpp +++ b/src/platform/bouffalolab/BL702/NetworkCommissioningDriver.cpp @@ -211,15 +211,15 @@ void BLWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callba { if (callback != nullptr) { - ChipLogError(NetworkProvisioning, "ssid.data(): %s", ssid.data()); - if (ssid.data()) { memset(mScanSSID, 0, sizeof(mScanSSID)); memcpy(mScanSSID, ssid.data(), ssid.size()); mScanSpecific = true; } - mpScanCallback = callback; + + mScanResponseNum = 0; + mpScanCallback = callback; wifiInterface_startScan(); } } @@ -229,81 +229,100 @@ void BLWiFiDriver::OnScanWiFiNetworkDone(void * opaque) netbus_wifi_mgmr_msg_cmd_t * pkg_data = (netbus_wifi_mgmr_msg_cmd_t *) ((struct pkg_protocol *) opaque)->payload; netbus_fs_scan_ind_cmd_msg_t * pmsg = (netbus_fs_scan_ind_cmd_msg_t *) ((netbus_fs_scan_ind_cmd_msg_t *) pkg_data); - size_t i = 0, ap_num = 0; + size_t i = 0, ap_num = 0, ap_cnt = 0; WiFiScanResponse *pScanResponse, *p; - for (i = 0; i < pmsg->num; i++) - { - ChipLogProgress(DeviceLayer, "OnScanWiFiNetworkDone %s", pmsg->records[i].ssid); - if (mScanSpecific && !strcmp(mScanSSID, (char *) (pmsg->records[i].ssid))) - { - ap_num = 1; - break; - } - } + ChipLogProgress(DeviceLayer, "expected ssid %s. get %d in total, %d", mScanSSID, pmsg->num, mScanSpecific); - if (0 == pmsg->num || (mScanSpecific && 0 == ap_num)) + if (mScanSpecific) { - ChipLogProgress(DeviceLayer, "No AP found"); - if (mpScanCallback != nullptr) + for (i = 0; i < pmsg->num; i++) { - mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), nullptr); - mpScanCallback = nullptr; + if (mScanSpecific && !strcmp(mScanSSID, (char *) (pmsg->records[i].ssid))) + { + ap_num = 1; + break; + } } - return; - } - - if (ap_num) - { - p = pScanResponse = (WiFiScanResponse *) malloc(sizeof(WiFiScanResponse) * ap_num); } else { - p = pScanResponse = (WiFiScanResponse *) malloc(sizeof(WiFiScanResponse) * pmsg->num); - ap_num = pmsg->num; + ap_num = pmsg->num; } - for (i = 0; i < pmsg->num; i++) + + if (ap_num) { - if (mScanSpecific && strcmp(mScanSSID, (char *) (pmsg->records[i].ssid))) + p = mScanResponse = (WiFiScanResponse *) malloc(sizeof(WiFiScanResponse) * ap_num); + if (mScanResponse == nullptr) { - continue; + return; } - p->security.SetRaw(pmsg->records[i].auth_mode); - p->ssidLen = strlen((char *) pmsg->records[i].ssid) < chip::DeviceLayer::Internal::kMaxWiFiSSIDLength - ? strlen((char *) pmsg->records[i].ssid) - : chip::DeviceLayer::Internal::kMaxWiFiSSIDLength; - p->channel = pmsg->records[i].channel; - p->wiFiBand = chip::DeviceLayer::NetworkCommissioning::WiFiBand::k2g4; - p->rssi = pmsg->records[i].rssi; - memcpy(p->ssid, pmsg->records[i].ssid, p->ssidLen); - memcpy(p->bssid, pmsg->records[i].bssid, 6); - - if (mScanSpecific) + for (i = 0; i < pmsg->num; i++) { - break; - } - - p++; - } - - if (CHIP_NO_ERROR == DeviceLayer::SystemLayer().ScheduleLambda([ap_num, pScanResponse]() { - BLScanResponseIterator iter(ap_num, pScanResponse); - if (GetInstance().mpScanCallback) + if (mScanSpecific && strcmp(mScanSSID, (char *) (pmsg->records[i].ssid))) { - GetInstance().mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), &iter); - GetInstance().mpScanCallback = nullptr; + continue; } - else + + p->security.SetRaw(pmsg->records[i].auth_mode); + strncpy((char *) p->ssid, (const char *) pmsg->records[i].ssid, kMaxWiFiSSIDLength); + p->ssidLen = strlen((char *) pmsg->records[i].ssid); + p->channel = pmsg->records[i].channel; + p->wiFiBand = chip::DeviceLayer::NetworkCommissioning::WiFiBand::k2g4; + p->rssi = pmsg->records[i].rssi; + memcpy(p->bssid, pmsg->records[i].bssid, 6); + + p++; + ap_cnt++; + + if (ap_cnt >= ap_num) { - ChipLogError(DeviceLayer, "can't find the ScanCallback function"); + break; } - })) + } + } + + mScanResponseNum = ap_cnt; +} + +void BLWiFiDriver::OnScanWiFiNetworkDone(void) +{ + size_t ap_cnt = mScanResponseNum; + WiFiScanResponse * pScanResponse = mScanResponse; + + if (mScanResponse) + { + if (CHIP_NO_ERROR == DeviceLayer::SystemLayer().ScheduleLambda([ap_cnt, pScanResponse]() { + BLScanResponseIterator iter(ap_cnt, pScanResponse); + if (GetInstance().mpScanCallback) + { + GetInstance().mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), &iter); + GetInstance().mpScanCallback = nullptr; + } + else + { + ChipLogError(DeviceLayer, "can't find the ScanCallback function"); + } + })) + { + ChipLogProgress(DeviceLayer, "ScheduleLambda OK"); + } + + free(mScanResponse); + mScanResponse = nullptr; + } + else { - ChipLogProgress(DeviceLayer, "ScheduleLambda OK"); + ChipLogProgress(DeviceLayer, "No AP found"); + if (mpScanCallback != nullptr) + { + mpScanCallback->OnFinished(Status::kSuccess, CharSpan(), nullptr); + mpScanCallback = nullptr; + } } - free(pScanResponse); + mScanResponseNum = 0; } CHIP_ERROR GetConfiguredNetwork(Network & network) diff --git a/src/platform/bouffalolab/BL702/NetworkCommissioningDriver.h b/src/platform/bouffalolab/BL702/NetworkCommissioningDriver.h index 8e5557b8787438..b98ea60ab6127d 100644 --- a/src/platform/bouffalolab/BL702/NetworkCommissioningDriver.h +++ b/src/platform/bouffalolab/BL702/NetworkCommissioningDriver.h @@ -113,7 +113,8 @@ class BLWiFiDriver final : public WiFiDriver CHIP_ERROR ConnectWiFiNetwork(const char * ssid, uint8_t ssidLen, const char * key, uint8_t keyLen); void OnConnectWiFiNetwork(bool isConnected); - void OnScanWiFiNetworkDone(void * opaque = NULL); + void OnScanWiFiNetworkDone(void); + void OnScanWiFiNetworkDone(void * opaque); void OnNetworkStatusChange(void); CHIP_ERROR SetLastDisconnectReason(const ChipDeviceEvent * event); @@ -128,6 +129,9 @@ class BLWiFiDriver final : public WiFiDriver private: bool NetworkMatch(const WiFiNetwork & network, ByteSpan networkId); + WiFiScanResponse * mScanResponse = nullptr; + size_t mScanResponseNum = 0; + WiFiNetwork mSavedNetwork; WiFiNetwork mStagingNetwork; ScanCallback * mpScanCallback; diff --git a/src/platform/bouffalolab/BL702/ThreadStackManagerImpl.cpp b/src/platform/bouffalolab/BL702/ThreadStackManagerImpl.cpp index 784dfa396cd371..a2072eff6be32d 100644 --- a/src/platform/bouffalolab/BL702/ThreadStackManagerImpl.cpp +++ b/src/platform/bouffalolab/BL702/ThreadStackManagerImpl.cpp @@ -65,6 +65,12 @@ bool ThreadStackManagerImpl::IsInitialized() return sInstance.mThreadStackLock != NULL; } +void ThreadStackManagerImpl::FactoryResetThreadStack(void) +{ + VerifyOrReturn(ThreadStackMgrImpl().OTInstance() != NULL); + otInstanceFactoryReset(ThreadStackMgrImpl().OTInstance()); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/bouffalolab/BL702L/ThreadStackManagerImpl.cpp b/src/platform/bouffalolab/BL702L/ThreadStackManagerImpl.cpp index 784dfa396cd371..a2072eff6be32d 100644 --- a/src/platform/bouffalolab/BL702L/ThreadStackManagerImpl.cpp +++ b/src/platform/bouffalolab/BL702L/ThreadStackManagerImpl.cpp @@ -65,6 +65,12 @@ bool ThreadStackManagerImpl::IsInitialized() return sInstance.mThreadStackLock != NULL; } +void ThreadStackManagerImpl::FactoryResetThreadStack(void) +{ + VerifyOrReturn(ThreadStackMgrImpl().OTInstance() != NULL); + otInstanceFactoryReset(ThreadStackMgrImpl().OTInstance()); +} + } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/bouffalolab/common/BLConfig_littlefs.cpp b/src/platform/bouffalolab/common/BLConfig_littlefs.cpp index 7f5e221195e8d3..84b7db21ead7b2 100644 --- a/src/platform/bouffalolab/common/BLConfig_littlefs.cpp +++ b/src/platform/bouffalolab/common/BLConfig_littlefs.cpp @@ -278,7 +278,7 @@ CHIP_ERROR BLConfig::WriteConfigValue(const char * key, uint8_t * val, size_t si blconfig_lfs->cfg->lock(blconfig_lfs->cfg); - ret = lfs_file_open(blconfig_lfs, &file, write_key, LFS_O_CREAT | LFS_O_RDWR); + ret = lfs_file_open(blconfig_lfs, &file, write_key, LFS_O_CREAT | LFS_O_RDWR | LFS_O_TRUNC); VerifyOrExit(ret == LFS_ERR_OK, err = CHIP_ERROR_PERSISTED_STORAGE_FAILED); lfs_file_write(blconfig_lfs, &file, val, size); @@ -353,7 +353,7 @@ CHIP_ERROR BLConfig::FactoryResetConfig(void) blconfig_lfs->cfg->lock(blconfig_lfs->cfg); - ret = lfs_file_open(blconfig_lfs, &file, reset_key, LFS_O_CREAT | LFS_O_RDWR); + ret = lfs_file_open(blconfig_lfs, &file, reset_key, LFS_O_CREAT | LFS_O_RDWR | LFS_O_TRUNC); if (ret != LFS_ERR_OK) { blconfig_lfs->cfg->unlock(blconfig_lfs->cfg); diff --git a/src/platform/bouffalolab/common/CHIPDevicePlatformConfig.h b/src/platform/bouffalolab/common/CHIPDevicePlatformConfig.h index bc34d9124b6d92..7f1bbf360fdd7f 100644 --- a/src/platform/bouffalolab/common/CHIPDevicePlatformConfig.h +++ b/src/platform/bouffalolab/common/CHIPDevicePlatformConfig.h @@ -58,4 +58,6 @@ #define CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE 1 #elif CHIP_DEVICE_LAYER_TARGET_BL702 #define CHIP_CONFIG_FREERTOS_USE_STATIC_TASK 1 +#elif CHIP_DEVICE_LAYER_TARGET_BL702L +#define CHIP_CONFIG_FREERTOS_USE_STATIC_TASK 1 #endif diff --git a/src/platform/bouffalolab/common/ConfigurationManagerImpl.cpp b/src/platform/bouffalolab/common/ConfigurationManagerImpl.cpp index 176803d00a1ebe..39d535aba6ade1 100644 --- a/src/platform/bouffalolab/common/ConfigurationManagerImpl.cpp +++ b/src/platform/bouffalolab/common/ConfigurationManagerImpl.cpp @@ -190,6 +190,17 @@ void ConfigurationManagerImpl::RunConfigUnitTest(void) BLConfig::RunConfigUnitTest(); } +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +void ConfigurationManagerImpl::ClearThreadStack() +{ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + ThreadStackMgr().ClearAllSrpHostAndServices(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT + ChipLogProgress(DeviceLayer, "Clearing Thread provision"); + ThreadStackMgr().ErasePersistentInfo(); +} +#endif + void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) { CHIP_ERROR err; diff --git a/src/platform/bouffalolab/common/ConfigurationManagerImpl.h b/src/platform/bouffalolab/common/ConfigurationManagerImpl.h index 1e7bb53922eb79..765d6b53b1a904 100644 --- a/src/platform/bouffalolab/common/ConfigurationManagerImpl.h +++ b/src/platform/bouffalolab/common/ConfigurationManagerImpl.h @@ -38,6 +38,10 @@ class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImp CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours); bool IsFullyProvisioned(); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + void ClearThreadStack(); +#endif + private: // ===== Members that implement the ConfigurationManager private interface. diff --git a/src/platform/bouffalolab/common/DiagnosticDataProviderImpl.cpp b/src/platform/bouffalolab/common/DiagnosticDataProviderImpl.cpp index a5d70240ba5a04..12a58f995d7d26 100644 --- a/src/platform/bouffalolab/common/DiagnosticDataProviderImpl.cpp +++ b/src/platform/bouffalolab/common/DiagnosticDataProviderImpl.cpp @@ -78,7 +78,10 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeap CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) { #if CHIP_DEVICE_LAYER_TARGET_BL616 - return CHIP_ERROR_NOT_IMPLEMENTED; + struct meminfo info; + bflb_mem_usage(KMEM_HEAP, &info); + currentHeapHighWatermark = info.total_size - info.max_free_size; + #else #ifdef CFG_USE_PSRAM currentHeapHighWatermark = @@ -86,8 +89,9 @@ CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & cu #else currentHeapHighWatermark = get_heap_size() - xPortGetMinimumEverFreeHeapSize(); #endif - return CHIP_NO_ERROR; #endif + + return CHIP_NO_ERROR; } CHIP_ERROR DiagnosticDataProviderImpl::GetThreadMetrics(ThreadMetrics ** threadMetricsOut) diff --git a/src/platform/bouffalolab/common/DiagnosticDataProviderImpl.h b/src/platform/bouffalolab/common/DiagnosticDataProviderImpl.h index 8001afb0544cb3..6ff0d07ad30d1e 100644 --- a/src/platform/bouffalolab/common/DiagnosticDataProviderImpl.h +++ b/src/platform/bouffalolab/common/DiagnosticDataProviderImpl.h @@ -32,6 +32,7 @@ class DiagnosticDataProviderImpl : public DiagnosticDataProvider static DiagnosticDataProviderImpl & GetDefaultInstance(); // ===== Methods that implement the PlatformManager abstract interface. + bool SupportsWatermarks() override { return true; } CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override; CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override; diff --git a/src/platform/bouffalolab/common/SystemPlatformConfig.h b/src/platform/bouffalolab/common/SystemPlatformConfig.h index 89a0a5a8f9a966..5802b386225b28 100644 --- a/src/platform/bouffalolab/common/SystemPlatformConfig.h +++ b/src/platform/bouffalolab/common/SystemPlatformConfig.h @@ -38,9 +38,13 @@ struct ChipDeviceEvent; // #define CHIP_CONFIG_SHA256_CONTEXT_SIZE sizeof(mbedtls_sha256_context) in hw_acc/sha256_alt.h #define CHIP_CONFIG_SHA256_CONTEXT_SIZE (32 + 64 + 64 + 19 * 32) #define CHIP_CONFIG_SHA256_CONTEXT_ALIGN 32 -#define CHIP_SYSTEM_CRYPTO_HEADER_RESERVE_SIZE (388) #else // #define CHIP_CONFIG_SHA256_CONTEXT_SIZE sizeof(bl_sha_ctx_t) #define CHIP_CONFIG_SHA256_CONTEXT_SIZE ((7 + 1 + 5 + 18 + 16 + 16 + 7) * sizeof(unsigned int)) #endif + +#if CHIP_SYSTEM_CONFIG_USE_LWIP +#define CHIP_SYSTEM_CONFIG_HEADER_RESERVE_SIZE \ + (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN + CHIP_SYSTEM_HEADER_RESERVE_SIZE) +#endif diff --git a/src/platform/bouffalolab/common/ThreadStackManagerImpl.h b/src/platform/bouffalolab/common/ThreadStackManagerImpl.h index 462d2de76ac32d..cd743bf93848eb 100644 --- a/src/platform/bouffalolab/common/ThreadStackManagerImpl.h +++ b/src/platform/bouffalolab/common/ThreadStackManagerImpl.h @@ -65,6 +65,7 @@ class ThreadStackManagerImpl final : public ThreadStackManager, using ThreadStackManager::InitThreadStack; CHIP_ERROR InitThreadStack(otInstance * otInst); + void FactoryResetThreadStack(void); private: // ===== Methods that implement the ThreadStackManager abstract interface. diff --git a/src/platform/silabs/MigrationManager.cpp b/src/platform/silabs/MigrationManager.cpp index d9bba0b249be4e..022bb709798e3c 100644 --- a/src/platform/silabs/MigrationManager.cpp +++ b/src/platform/silabs/MigrationManager.cpp @@ -40,6 +40,7 @@ static migrationData_t migrationTable[] = { { .migrationGroup = 1, .migrationFunc = MigrateKvsMap }, { .migrationGroup = 2, .migrationFunc = MigrateDacProvider }, { .migrationGroup = 3, .migrationFunc = MigrateCounterConfigs }, + { .migrationGroup = 4, .migrationFunc = MigrateHardwareVersion }, // add any additional migration neccesary. migrationGroup should stay equal if done in the same commit or increment by 1 for // each new entry. }; @@ -62,6 +63,20 @@ void MigrationManager::applyMigrations() } SilabsConfig::WriteConfigValue(SilabsConfig::kConfigKey_MigrationCounter, completedMigrationGroup); } + +void MigrationManager::MigrateUint16(uint32_t old_key, uint32_t new_key) +{ + uint16_t value = 0; + if (SilabsConfig::ConfigValueExists(old_key) && (CHIP_NO_ERROR == SilabsConfig::ReadConfigValue(old_key, value))) + { + if (CHIP_NO_ERROR == SilabsConfig::WriteConfigValue(new_key, value)) + { + // Free memory of old key location + SilabsConfig::ClearConfigValue(old_key); + } + } +} + void MigrationManager::MigrateUint32(uint32_t old_key, uint32_t new_key) { uint32_t value = 0; @@ -90,6 +105,33 @@ MigrationManager & MigrationManager::GetMigrationInstance() return sMigrationManager; } +void MigrateDacProvider(void) +{ + constexpr uint32_t kOldKey_Creds_KeyId = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x21); + constexpr uint32_t kOldKey_Creds_Base_Addr = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x22); + constexpr uint32_t kOldKey_Creds_DAC_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x23); + constexpr uint32_t kOldKey_Creds_DAC_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x24); + constexpr uint32_t kOldKey_Creds_PAI_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x26); + constexpr uint32_t kOldKey_Creds_PAI_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x25); + constexpr uint32_t kOldKey_Creds_CD_Offset = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x27); + constexpr uint32_t kOldKey_Creds_CD_Size = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x28); + + MigrationManager::MigrateUint32(kOldKey_Creds_KeyId, SilabsConfig::kConfigKey_Creds_KeyId); + MigrationManager::MigrateUint32(kOldKey_Creds_Base_Addr, SilabsConfig::kConfigKey_Creds_Base_Addr); + MigrationManager::MigrateUint32(kOldKey_Creds_DAC_Offset, SilabsConfig::kConfigKey_Creds_DAC_Offset); + MigrationManager::MigrateUint32(kOldKey_Creds_DAC_Size, SilabsConfig::kConfigKey_Creds_DAC_Size); + MigrationManager::MigrateUint32(kOldKey_Creds_PAI_Offset, SilabsConfig::kConfigKey_Creds_PAI_Offset); + MigrationManager::MigrateUint32(kOldKey_Creds_PAI_Size, SilabsConfig::kConfigKey_Creds_PAI_Size); + MigrationManager::MigrateUint32(kOldKey_Creds_CD_Offset, SilabsConfig::kConfigKey_Creds_CD_Offset); + MigrationManager::MigrateUint32(kOldKey_Creds_CD_Size, SilabsConfig::kConfigKey_Creds_CD_Size); +} + +void MigrateHardwareVersion(void) +{ + constexpr uint32_t kOldKey_HardwareVersion = SilabsConfigKey(SilabsConfig::kMatterConfig_KeyBase, 0x08); + MigrationManager::MigrateUint16(kOldKey_HardwareVersion, SilabsConfig::kConfigKey_HardwareVersion); +} + } // namespace Silabs } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/silabs/MigrationManager.h b/src/platform/silabs/MigrationManager.h index 69afbf47ac7562..155cb7e3b78b47 100644 --- a/src/platform/silabs/MigrationManager.h +++ b/src/platform/silabs/MigrationManager.h @@ -31,6 +31,7 @@ class MigrationManager */ static MigrationManager & GetMigrationInstance(); static void applyMigrations(); + static void MigrateUint16(uint32_t old_key, uint32_t new_key); static void MigrateUint32(uint32_t old_key, uint32_t new_key); private: @@ -45,6 +46,7 @@ class MigrationManager void MigrateKvsMap(void); void MigrateDacProvider(void); void MigrateCounterConfigs(void); +void MigrateHardwareVersion(void); } // namespace Silabs } // namespace DeviceLayer diff --git a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp index 6c2a90f705a18a..dfbe8f17d11d04 100644 --- a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp +++ b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp @@ -19,9 +19,13 @@ #include #include #include - #include #include + +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#include +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + #ifdef __cplusplus extern "C" { #endif @@ -156,13 +160,9 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) imageProcessor->mHeaderParser.Init(); - // Setting the device is in high performace - no-sleepy mode while OTA tranfer -#if (CHIP_CONFIG_ENABLE_ICD_SERVER) - status = wfx_power_save(RSI_ACTIVE, HIGH_PERFORMANCE); - if (status != SL_STATUS_OK) - { - ChipLogError(DeviceLayer, "Failed to enable the TA Deep Sleep"); - } +#if CHIP_CONFIG_ENABLE_ICD_SERVER + // Setting the device in high performance - no-sleep mode during OTA tranfer + DeviceLayer::Silabs::WifiSleepManager::GetInstance().RequestHighPerformance(); #endif /* CHIP_CONFIG_ENABLE_ICD_SERVER*/ imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); @@ -199,13 +199,9 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context) } imageProcessor->ReleaseBlock(); +#if CHIP_CONFIG_ENABLE_ICD_SERVER // Setting the device back to power save mode when transfer is completed successfully -#if (CHIP_CONFIG_ENABLE_ICD_SERVER) - sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE); - if (err != SL_STATUS_OK) - { - ChipLogError(DeviceLayer, "Power save config for Wifi failed"); - } + DeviceLayer::Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest(); #endif /* CHIP_CONFIG_ENABLE_ICD_SERVER*/ ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully"); @@ -222,13 +218,9 @@ void OTAImageProcessorImpl::HandleApply(intptr_t context) ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully in HandleApply"); +#if CHIP_CONFIG_ENABLE_ICD_SERVER // Setting the device is in high performace - no-sleepy mode before soft reset as soft reset is not happening in sleep mode -#if (CHIP_CONFIG_ENABLE_ICD_SERVER) - status = wfx_power_save(RSI_ACTIVE, HIGH_PERFORMANCE); - if (status != SL_STATUS_OK) - { - ChipLogError(DeviceLayer, "Failed to enable the TA Deep Sleep"); - } + DeviceLayer::Silabs::WifiSleepManager::GetInstance().RequestHighPerformance(); #endif /* CHIP_CONFIG_ENABLE_ICD_SERVER*/ if (mReset) @@ -249,13 +241,9 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context) return; } +#if CHIP_CONFIG_ENABLE_ICD_SERVER // Setting the device back to power save mode when transfer is aborted in the middle -#if (CHIP_CONFIG_ENABLE_ICD_SERVER) - sl_status_t err = wfx_power_save(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE); - if (err != SL_STATUS_OK) - { - ChipLogError(DeviceLayer, "Power save config for Wifi failed"); - } + DeviceLayer::Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest(); #endif /* CHIP_CONFIG_ENABLE_ICD_SERVER*/ // Not clearing the image storage area as it is done during each write diff --git a/src/platform/silabs/SilabsConfig.h b/src/platform/silabs/SilabsConfig.h index c30d4d653dd6c8..11187336716ad2 100644 --- a/src/platform/silabs/SilabsConfig.h +++ b/src/platform/silabs/SilabsConfig.h @@ -120,6 +120,7 @@ class SilabsConfig static constexpr Key kConfigKey_hostname = SilabsConfigKey(kMatterFactory_KeyBase, 0x15); static constexpr Key kConfigKey_clientid = SilabsConfigKey(kMatterFactory_KeyBase, 0x16); static constexpr Key kConfigKey_Test_Event_Trigger_Key = SilabsConfigKey(kMatterFactory_KeyBase, 0x17); + static constexpr Key kConfigKey_HardwareVersion = SilabsConfigKey(kMatterFactory_KeyBase, 0x18); // kConfigKey_PersistentUniqueId is the inputkey in the generating of the Rotating Device ID // SHALL NOT be the same as the UniqueID attribute exposed in the Basic Information cluster. static constexpr Key kConfigKey_PersistentUniqueId = SilabsConfigKey(kMatterFactory_KeyBase, 0x1F); @@ -142,7 +143,6 @@ class SilabsConfig static constexpr Key kConfigKey_LastUsedEpochKeyId = SilabsConfigKey(kMatterConfig_KeyBase, 0x05); static constexpr Key kConfigKey_FailSafeArmed = SilabsConfigKey(kMatterConfig_KeyBase, 0x06); static constexpr Key kConfigKey_GroupKey = SilabsConfigKey(kMatterConfig_KeyBase, 0x07); - static constexpr Key kConfigKey_HardwareVersion = SilabsConfigKey(kMatterConfig_KeyBase, 0x08); static constexpr Key kConfigKey_RegulatoryLocation = SilabsConfigKey(kMatterConfig_KeyBase, 0x09); static constexpr Key kConfigKey_CountryCode = SilabsConfigKey(kMatterConfig_KeyBase, 0x0A); static constexpr Key kConfigKey_WiFiSSID = SilabsConfigKey(kMatterConfig_KeyBase, 0x0C); diff --git a/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp b/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp index dd5f755c19648a..8794491d67affd 100644 --- a/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp +++ b/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp @@ -112,10 +112,10 @@ CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, c VerifyOrReturnError(aad != nullptr || aad_length == 0, CHIP_ERROR_INVALID_ARGUMENT); const psa_algorithm_t algorithm = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_length); - psa_status_t status = PSA_SUCCESS; psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; - size_t out_length; - size_t tag_out_length; + psa_status_t status = PSA_SUCCESS; + size_t out_length = 0; + size_t tag_out_length = 0; status = psa_aead_encrypt_setup(&operation, key.As(), algorithm); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); @@ -126,30 +126,71 @@ CHIP_ERROR AES_CCM_encrypt(const uint8_t * plaintext, size_t plaintext_length, c status = psa_aead_set_nonce(&operation, nonce, nonce_length); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - if (aad_length != 0) + if (0 == aad_length) { - status = psa_aead_update_ad(&operation, aad, aad_length); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + ChipLogDetail(Crypto, "AES_CCM_encrypt: Using aad == null path"); } else { - ChipLogDetail(Crypto, "AES_CCM_encrypt: Using aad == null path"); + status = psa_aead_update_ad(&operation, aad, aad_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); } - if (plaintext_length != 0) + if (0 == plaintext_length) { - status = psa_aead_update(&operation, plaintext, plaintext_length, ciphertext, - PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, plaintext_length), &out_length); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - - ciphertext += out_length; - - status = psa_aead_finish(&operation, ciphertext, PSA_AEAD_FINISH_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm), &out_length, tag, - tag_length, &tag_out_length); + // Empty plaintext + status = psa_aead_finish(&operation, nullptr, 0, &out_length, tag, tag_length, &tag_out_length); } else { - status = psa_aead_finish(&operation, nullptr, 0, &out_length, tag, tag_length, &tag_out_length); + // psa_aead_update() requires use of the macro PSA_AEAD_UPDATE_OUTPUT_SIZE to determine the output buffer size. + // For AES-CCM, PSA_AEAD_UPDATE_OUTPUT_SIZE will round up the size to the next multiple of the block size (16). + // If the ciphertext length is not a multiple of the block size, we will encrypt in two steps, first with the + // block_aligned_length, and then with a rounded up partial_block_length, where a temporary buffer will be used for the + // output. + constexpr uint8_t kBlockSize = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES); + size_t block_aligned_length = (plaintext_length / kBlockSize) * kBlockSize; + size_t partial_block_length = plaintext_length % kBlockSize; + size_t ciphertext_length = 0; + uint8_t temp[kBlockSize] = { 0 }; + + // Make sure the calculated block_aligned_length is compliant with PSA's output size requirements. + VerifyOrReturnError(block_aligned_length == PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, block_aligned_length), + CHIP_ERROR_INTERNAL); + + // Add the aligned part of the plaintext + status = psa_aead_update(&operation, plaintext, block_aligned_length, ciphertext, block_aligned_length, &out_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(out_length == block_aligned_length, CHIP_ERROR_INTERNAL); + ciphertext_length += out_length; + + if (partial_block_length > 0) + { + // The update output should fit in the temp buffer + size_t max_output = PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, partial_block_length); + + // Add the non-aligned end of the plaintext + status = + psa_aead_update(&operation, &plaintext[block_aligned_length], partial_block_length, temp, max_output, &out_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(ciphertext_length + out_length <= plaintext_length, CHIP_ERROR_INTERNAL); + // Add the encrypted output, if any + memcpy(&ciphertext[ciphertext_length], temp, out_length); + ciphertext_length += out_length; + } + + // The finish output should fit in the temp buffer + size_t max_finish = PSA_AEAD_FINISH_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm); + VerifyOrReturnError(max_finish <= sizeof(temp), CHIP_ERROR_BUFFER_TOO_SMALL); + + // The finish may return the last part of the ciphertext + status = psa_aead_finish(&operation, temp, max_finish, &out_length, tag, tag_length, &tag_out_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(ciphertext_length + out_length <= plaintext_length, CHIP_ERROR_INTERNAL); + // Add the encrypted output, if any + memcpy(&ciphertext[ciphertext_length], temp, out_length); + ciphertext_length += out_length; + VerifyOrReturnError(ciphertext_length == plaintext_length, CHIP_ERROR_INTERNAL); } VerifyOrReturnError(status == PSA_SUCCESS && tag_length == tag_out_length, CHIP_ERROR_INTERNAL); @@ -166,9 +207,9 @@ CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length, VerifyOrReturnError(aad != nullptr || aad_length == 0, CHIP_ERROR_INVALID_ARGUMENT); const psa_algorithm_t algorithm = PSA_ALG_AEAD_WITH_SHORTENED_TAG(PSA_ALG_CCM, tag_length); - psa_status_t status = PSA_SUCCESS; psa_aead_operation_t operation = PSA_AEAD_OPERATION_INIT; - size_t outLength; + psa_status_t status = PSA_SUCCESS; + size_t out_length = 0; status = psa_aead_decrypt_setup(&operation, key.As(), algorithm); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); @@ -179,32 +220,71 @@ CHIP_ERROR AES_CCM_decrypt(const uint8_t * ciphertext, size_t ciphertext_length, status = psa_aead_set_nonce(&operation, nonce, nonce_length); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - if (aad_length != 0) + if (0 == aad_length) { - status = psa_aead_update_ad(&operation, aad, aad_length); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + ChipLogDetail(Crypto, "AES_CCM_decrypt: Using aad == null path"); } else { - ChipLogDetail(Crypto, "AES_CCM_decrypt: Using aad == null path"); + status = psa_aead_update_ad(&operation, aad, aad_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); } - if (ciphertext_length != 0) + if (0 == ciphertext_length) { - status = psa_aead_update(&operation, ciphertext, ciphertext_length, plaintext, - PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, ciphertext_length), &outLength); - VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); - - plaintext += outLength; - - status = psa_aead_verify(&operation, plaintext, PSA_AEAD_VERIFY_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm), &outLength, tag, - tag_length); + status = psa_aead_verify(&operation, nullptr, 0, &out_length, tag, tag_length); } else { - status = psa_aead_verify(&operation, nullptr, 0, &outLength, tag, tag_length); - } + // psa_aead_update() requires use of the macro PSA_AEAD_UPDATE_OUTPUT_SIZE to determine the output buffer size. + // For AES-CCM, PSA_AEAD_UPDATE_OUTPUT_SIZE will round up the size to the next multiple of the block size (16). + // If the plaintext length is not a multiple of the block size, we will encrypt in two steps, first with the + // block_aligned_length, and then with a rounded up partial_block_length, where a temporary buffer will be used for the + // output. + constexpr uint8_t kBlockSize = PSA_BLOCK_CIPHER_BLOCK_LENGTH(PSA_KEY_TYPE_AES); + size_t block_aligned_length = (ciphertext_length / kBlockSize) * kBlockSize; + size_t partial_block_length = ciphertext_length % kBlockSize; + size_t plaintext_length = 0; + uint8_t temp[kBlockSize] = { 0 }; + + // Make sure the calculated block_aligned_length is compliant with PSA's output size requirements. + VerifyOrReturnError(block_aligned_length == PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, block_aligned_length), + CHIP_ERROR_INTERNAL); + + // Add the aligned part of the ciphertext + status = psa_aead_update(&operation, ciphertext, block_aligned_length, plaintext, block_aligned_length, &out_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(out_length == block_aligned_length, CHIP_ERROR_INTERNAL); + plaintext_length += out_length; + + if (partial_block_length > 0) + { + // The update output should fit in the temp buffer + size_t max_output = PSA_AEAD_UPDATE_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm, partial_block_length); + + // Add the non-aligned end of the ciphertext + status = + psa_aead_update(&operation, &ciphertext[block_aligned_length], partial_block_length, temp, max_output, &out_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(plaintext_length + out_length <= ciphertext_length, CHIP_ERROR_INTERNAL); + // Add the decrypted output, if any + memcpy(&plaintext[plaintext_length], temp, out_length); + plaintext_length += out_length; + } + + // The finish output should fit in the temp buffer + size_t max_verify = PSA_AEAD_VERIFY_OUTPUT_SIZE(PSA_KEY_TYPE_AES, algorithm); + VerifyOrReturnError(max_verify <= sizeof(temp), CHIP_ERROR_BUFFER_TOO_SMALL); + // Complete verification + status = psa_aead_verify(&operation, temp, max_verify, &out_length, tag, tag_length); + VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(plaintext_length + out_length <= ciphertext_length, CHIP_ERROR_INTERNAL); + // Add the decrypted output, if any + memcpy(&plaintext[plaintext_length], temp, out_length); + plaintext_length += out_length; + VerifyOrReturnError(ciphertext_length == plaintext_length, CHIP_ERROR_INTERNAL); + } VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); return CHIP_NO_ERROR; diff --git a/src/platform/silabs/efr32/efr32-psa-crypto-config.h b/src/platform/silabs/efr32/efr32-psa-crypto-config.h index 0d80b59be9be99..6bf099dcb1457c 100644 --- a/src/platform/silabs/efr32/efr32-psa-crypto-config.h +++ b/src/platform/silabs/efr32/efr32-psa-crypto-config.h @@ -34,9 +34,9 @@ #endif // SL_USE_COAP_CONFIG // Multi-chip OTA encryption processing -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION #define PSA_WANT_ALG_CTR -#endif // OTA_ENCRYPTION_ENABLE +#endif // SL_MATTER_ENABLE_OTA_ENCRYPTION // Include Generated fies #include "psa_crypto_config.h" diff --git a/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp index a39a39b8f3aa87..4419660c65d006 100644 --- a/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTAFactoryDataProcessor.cpp @@ -45,7 +45,7 @@ CHIP_ERROR OTAFactoryDataProcessor::ProcessInternal(ByteSpan & block) CHIP_ERROR error = CHIP_NO_ERROR; ReturnErrorOnFailure(mAccumulator.Accumulate(block)); -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION MutableByteSpan mBlock = MutableByteSpan(mAccumulator.data(), mAccumulator.GetThreshold()); OTATlvProcessor::vOtaProcessInternalEncryption(mBlock); #endif diff --git a/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp index 19abb72585da3a..8ffd81c38dde11 100644 --- a/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp @@ -46,7 +46,7 @@ CHIP_ERROR OTAFirmwareProcessor::Init() { VerifyOrReturnError(mCallbackProcessDescriptor != nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED); mAccumulator.Init(sizeof(Descriptor)); -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION mUnalignmentNum = 0; #endif @@ -58,7 +58,7 @@ CHIP_ERROR OTAFirmwareProcessor::Clear() OTATlvProcessor::ClearInternal(); mAccumulator.Clear(); mDescriptorProcessed = false; -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION mUnalignmentNum = 0; #endif @@ -71,12 +71,12 @@ CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block) if (!mDescriptorProcessed) { ReturnErrorOnFailure(ProcessDescriptor(block)); -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION /* 16 bytes to used to store undecrypted data because of unalignment */ mAccumulator.Init(requestedOtaMaxBlockSize + 16); #endif } -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION MutableByteSpan mBlock = MutableByteSpan(mAccumulator.data(), mAccumulator.GetThreshold()); memcpy(&mBlock[0], &mBlock[requestedOtaMaxBlockSize], mUnalignmentNum); memcpy(&mBlock[mUnalignmentNum], block.data(), block.size()); diff --git a/src/platform/silabs/multi-ota/OTAFirmwareProcessor.h b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.h index c383e7497b8b1a..25ed325c0f4af2 100644 --- a/src/platform/silabs/multi-ota/OTAFirmwareProcessor.h +++ b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.h @@ -44,7 +44,7 @@ class OTAFirmwareProcessor : public OTATlvProcessor OTADataAccumulator mAccumulator; bool mDescriptorProcessed = false; -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION uint32_t mUnalignmentNum; #endif static constexpr size_t kAlignmentBytes = 64; diff --git a/src/platform/silabs/multi-ota/OTATlvProcessor.cpp b/src/platform/silabs/multi-ota/OTATlvProcessor.cpp index e6601449faf63a..6b679eb9c09b3d 100644 --- a/src/platform/silabs/multi-ota/OTATlvProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTATlvProcessor.cpp @@ -22,7 +22,7 @@ #include #include -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION #include #include #endif @@ -31,7 +31,7 @@ using namespace ::chip::DeviceLayer::Internal; namespace chip { -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION constexpr uint8_t au8Iv[] = { 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00 }; #endif CHIP_ERROR OTATlvProcessor::Process(ByteSpan & block) @@ -66,7 +66,7 @@ void OTATlvProcessor::ClearInternal() mLength = 0; mProcessedLength = 0; mWasSelected = false; -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION mIVOffset = 0; #endif } @@ -105,7 +105,7 @@ CHIP_ERROR OTADataAccumulator::Accumulate(ByteSpan & block) return CHIP_NO_ERROR; } -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION CHIP_ERROR OTATlvProcessor::vOtaProcessInternalEncryption(MutableByteSpan & block) { uint32_t keyId; diff --git a/src/platform/silabs/multi-ota/OTATlvProcessor.h b/src/platform/silabs/multi-ota/OTATlvProcessor.h index fe2070b75e5634..a14c2f2442c07c 100644 --- a/src/platform/silabs/multi-ota/OTATlvProcessor.h +++ b/src/platform/silabs/multi-ota/OTATlvProcessor.h @@ -99,7 +99,7 @@ class OTATlvProcessor void SetLength(uint32_t length) { mLength = length; } void SetWasSelected(bool selected) { mWasSelected = selected; } bool WasSelected() { return mWasSelected; } -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION CHIP_ERROR vOtaProcessInternalEncryption(MutableByteSpan & block); #endif @@ -133,7 +133,7 @@ class OTATlvProcessor bool IsError(CHIP_ERROR & status); -#if OTA_ENCRYPTION_ENABLE +#ifdef SL_MATTER_ENABLE_OTA_ENCRYPTION /*ota decryption*/ uint32_t mIVOffset = 0; /* Expected byte size of the OTAEncryptionKeyLength */ diff --git a/src/platform/silabs/tests/BUILD.gn b/src/platform/silabs/tests/BUILD.gn new file mode 100644 index 00000000000000..3d98396cdc4d7e --- /dev/null +++ b/src/platform/silabs/tests/BUILD.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2025 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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_overrides/pigweed.gni") +import("${chip_root}/build/chip/chip_test_group.gni") +import("${chip_root}/build/chip/chip_test_suite.gni") +import("${chip_root}/src/platform/silabs/tests/args.gni") + +chip_test_group("silabs_platform_tests") { + tests = [] + + if (sl_build_unit_tests) { + tests += [ "${chip_root}/examples/platform/silabs/tests:examples_tests" ] + } +} diff --git a/src/platform/silabs/tests/args.gni b/src/platform/silabs/tests/args.gni new file mode 100644 index 00000000000000..1886b258120ab7 --- /dev/null +++ b/src/platform/silabs/tests/args.gni @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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/chip/tests.gni") + +declare_args() { + # Build argument to enable Silabs specific unit tests + sl_build_unit_tests = chip_build_all_platform_tests +} diff --git a/src/platform/silabs/wifi/BUILD.gn b/src/platform/silabs/wifi/BUILD.gn index af6d82fc30cbbc..7dddba2054527c 100644 --- a/src/platform/silabs/wifi/BUILD.gn +++ b/src/platform/silabs/wifi/BUILD.gn @@ -151,4 +151,14 @@ source_set("wifi-platform") { "${silabs_platform_dir}/wifi/lwip-support/lwip_netif.cpp", ] } + + # TODO: Once the WifiInterface refactor is done and becomes a class, we will inject an interface instead of having them in same source_set + if (chip_enable_icd_server) { + public_deps += [ "${chip_root}/src/app/icd/server:configuration-data" ] + + sources += [ + "${silabs_platform_dir}/wifi/icd/WifiSleepManager.cpp", + "${silabs_platform_dir}/wifi/icd/WifiSleepManager.h", + ] + } } diff --git a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp index 6ce7b2b66b4a34..68d9221f2e2822 100644 --- a/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp @@ -70,12 +70,17 @@ extern "C" { #include #endif -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#include // nogncheck +#include + +#if SLI_SI91X_MCU_INTERFACE // SoC Only #include "rsi_rom_power_save.h" #include "sl_gpio_board.h" #include "sl_si91x_driver_gpio.h" #include "sl_si91x_power_manager.h" -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE +#endif // SLI_SI91X_MCU_INTERFACE +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER // TODO : Temporary work-around for wifi-init failure in 917NCP and 917SOC ACX module boards. // Can be removed after Wiseconnect fixes region code for all ACX module boards. @@ -89,10 +94,9 @@ WfxRsi_t wfx_rsi; namespace { -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE -// TODO: should be removed once we are getting the press interrupt for button 0 with sleep -bool btn0_pressed = false; -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE +#if CHIP_CONFIG_ENABLE_ICD_SERVER +constexpr uint32_t kTimeToFullBeaconReception = 5000; // 5 seconds +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER wfx_wifi_scan_ext_t temp_reset; @@ -374,8 +378,8 @@ sl_status_t SetWifiConfigurations() sl_status_t status = SL_STATUS_OK; #if CHIP_CONFIG_ENABLE_ICD_SERVER - // Setting the listen interval to 0 which will set it to DTIM interval - sl_wifi_listen_interval_t sleep_interval = { .listen_interval = 0 }; + sl_wifi_listen_interval_t sleep_interval = { .listen_interval = + chip::ICDConfigurationData::GetInstance().GetSlowPollingInterval().count() }; status = sl_wifi_set_listen_interval(SL_WIFI_CLIENT_INTERFACE, sleep_interval); VerifyOrReturnError(status == SL_STATUS_OK, status, ChipLogError(DeviceLayer, "sl_wifi_set_listen_interval failed: 0x%lx", status)); @@ -384,6 +388,10 @@ sl_status_t SetWifiConfigurations() status = sl_wifi_set_advanced_client_configuration(SL_WIFI_CLIENT_INTERFACE, &client_config); VerifyOrReturnError(status == SL_STATUS_OK, status, ChipLogError(DeviceLayer, "sl_wifi_set_advanced_client_configuration failed: 0x%lx", status)); + + status = sl_si91x_set_join_configuration( + SL_WIFI_CLIENT_INTERFACE, (SL_SI91X_JOIN_FEAT_LISTEN_INTERVAL_VALID | SL_SI91X_JOIN_FEAT_PS_CMD_LISTEN_INTERVAL_VALID)); + VerifyOrReturnError(status == SL_STATUS_OK, status); #endif // CHIP_CONFIG_ENABLE_ICD_SERVER if (wfx_rsi.sec.passkey_length != 0) @@ -472,10 +480,21 @@ sl_status_t JoinWifiNetwork(void) status = sl_wifi_set_join_callback(JoinCallback, nullptr); VerifyOrReturnError(status == SL_STATUS_OK, status); +// To avoid IOP issues, it is recommended to enable high-performance mode before joining the network. +// TODO: Remove this once the IOP issue related to power save mode switching is fixed in the Wi-Fi SDK. +#if CHIP_CONFIG_ENABLE_ICD_SERVER + chip::DeviceLayer::Silabs::WifiSleepManager::GetInstance().RequestHighPerformance(); +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + status = sl_net_up((sl_net_interface_t) SL_NET_WIFI_CLIENT_INTERFACE, SL_NET_DEFAULT_WIFI_CLIENT_PROFILE_ID); if (status == SL_STATUS_OK || status == SL_STATUS_IN_PROGRESS) { +#if CHIP_CONFIG_ENABLE_ICD_SERVER + // Remove High performance request that might have been added during the connect/retry process + chip::DeviceLayer::Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest(); +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + WifiPlatformEvent event = WifiPlatformEvent::kStationConnect; PostWifiPlatformEvent(event); return status; @@ -791,6 +810,42 @@ void MatterWifiTask(void * arg) } } +#if CHIP_CONFIG_ENABLE_ICD_SERVER +CHIP_ERROR ConfigurePowerSave(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state, + uint32_t listenInterval) +{ + int32_t error = rsi_bt_power_save_profile(sl_si91x_ble_state, RSI_MAX_PSP); + VerifyOrReturnError(error == RSI_SUCCESS, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "rsi_bt_power_save_profile failed: %ld", error)); + + sl_wifi_performance_profile_t wifi_profile = { .profile = sl_si91x_wifi_state, + // TODO: Performance profile fails if not alligned with DTIM + .dtim_aligned_type = SL_SI91X_ALIGN_WITH_DTIM_BEACON, + // TODO: Different types need to be fixed in the Wi-Fi SDK + .listen_interval = static_cast(listenInterval) }; + + sl_status_t status = sl_wifi_set_performance_profile(&wifi_profile); + VerifyOrReturnError(status == SL_STATUS_OK, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "sl_wifi_set_performance_profile failed: 0x%lx", status)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConfigureBroadcastFilter(bool enableBroadcastFilter) +{ + sl_status_t status = SL_STATUS_OK; + + uint16_t beaconDropThreshold = (enableBroadcastFilter) ? kTimeToFullBeaconReception : 0; + uint8_t filterBcastInTim = (enableBroadcastFilter) ? 1 : 0; + + status = sl_wifi_filter_broadcast(beaconDropThreshold, filterBcastInTim, 1 /* valid till next update*/); + VerifyOrReturnError(status == SL_STATUS_OK, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "sl_wifi_filter_broadcast failed: 0x%lx", static_cast(status))); + + return CHIP_NO_ERROR; +} +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + #if CHIP_DEVICE_CONFIG_ENABLE_IPV4 /******************************************************************************************** * @fn void wfx_dhcp_got_ipv4(uint32_t ip) @@ -816,35 +871,3 @@ void wfx_dhcp_got_ipv4(uint32_t ip) NotifyIPv4Change(true); } #endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */ - -#if SL_ICD_ENABLED -/********************************************************************* - * @fn sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t - sl_si91x_wifi_state) - * @brief - * Implements the power save in sleepy application - * @param[in] sl_si91x_ble_state : State to set for the BLE - sl_si91x_wifi_state : State to set for the WiFi - * @return SL_STATUS_OK if successful, - * SL_STATUS_FAIL otherwise - ***********************************************************************/ -sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state) -{ - int32_t error = rsi_bt_power_save_profile(sl_si91x_ble_state, 0); - if (error != RSI_SUCCESS) - { - ChipLogError(DeviceLayer, "rsi_bt_power_save_profile failed: %ld", error); - return SL_STATUS_FAIL; - } - - sl_wifi_performance_profile_t wifi_profile = { .profile = sl_si91x_wifi_state }; - sl_status_t status = sl_wifi_set_performance_profile(&wifi_profile); - if (status != SL_STATUS_OK) - { - ChipLogError(DeviceLayer, "sl_wifi_set_performance_profile failed: 0x%lx", static_cast(status)); - return status; - } - - return SL_STATUS_OK; -} -#endif diff --git a/src/platform/silabs/wifi/WifiInterface.cpp b/src/platform/silabs/wifi/WifiInterface.cpp index 8174c58d8a5f86..2c206240da1441 100644 --- a/src/platform/silabs/wifi/WifiInterface.cpp +++ b/src/platform/silabs/wifi/WifiInterface.cpp @@ -15,8 +15,6 @@ * limitations under the License. */ -// SL MATTER WI-FI INTERFACE - #include "silabs_utils.h" #include #include @@ -24,10 +22,9 @@ #include #include #include -#include -#include -#include -#include +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#include +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER using namespace chip; using namespace chip::DeviceLayer; @@ -56,9 +53,6 @@ bool hasNotifiedIPV4 = false; */ void RetryConnectionTimerHandler(void * arg) { -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE - wfx_power_save(RSI_ACTIVE, HIGH_PERFORMANCE); -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE if (wfx_connect_to_ap() != SL_STATUS_OK) { ChipLogError(DeviceLayer, "wfx_connect_to_ap() failed."); @@ -192,11 +186,18 @@ void wfx_retry_connection(uint16_t retryAttempt) { ChipLogError(DeviceLayer, "wfx_connect_to_ap() failed."); } + +#if CHIP_CONFIG_ENABLE_ICD_SERVER + // Remove High performance request before giving up due to a timer start error to save battery life + Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest(); +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER return; } -#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE - wfx_power_save(RSI_SLEEP_MODE_8, DEEP_SLEEP_WITH_RAM_RETENTION); -#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE + +#if CHIP_CONFIG_ENABLE_ICD_SERVER + Silabs::WifiSleepManager::GetInstance().RemoveHighPerformanceRequest(); +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + ChipLogProgress(DeviceLayer, "wfx_retry_connection : Next attempt after %d Seconds", retryInterval); retryInterval += retryInterval; } diff --git a/src/platform/silabs/wifi/WifiInterface.h b/src/platform/silabs/wifi/WifiInterface.h index 598d1182a13a77..498f2741d9bc9e 100644 --- a/src/platform/silabs/wifi/WifiInterface.h +++ b/src/platform/silabs/wifi/WifiInterface.h @@ -360,8 +360,28 @@ CHIP_ERROR GetAccessPointExtendedInfo(wfx_wifi_scan_ext_t & info); */ CHIP_ERROR ResetCounters(); +/** + * @brief Configures the broadcast filter. + * + * @param[in] enableBroadcastFilter Boolean to enable or disable the broadcast filter. + * + * @return CHIP_ERROR CHIP_NO_ERROR, the counters were succesfully reset to 0. + * CHIP_ERROR_INTERNAL, if there was an error when configuring the broadcast filter + */ +CHIP_ERROR ConfigureBroadcastFilter(bool enableBroadcastFilter); + /* Function to update */ +// TODO: Harmonize the Power Save function inputs for all platforms +#if CHIP_CONFIG_ENABLE_ICD_SERVER +#if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) +CHIP_ERROR ConfigurePowerSave(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state, + uint32_t listenInterval); +#else +CHIP_ERROR ConfigurePowerSave(); +#endif /* (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) */ +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + void wfx_set_wifi_provision(wfx_wifi_provision_t * wifiConfig); bool wfx_get_wifi_provision(wfx_wifi_provision_t * wifiConfig); void wfx_clear_wifi_provision(void); @@ -399,17 +419,6 @@ int32_t wfx_rsi_send_data(void * p, uint16_t len); #endif //!(EXP_BOARD) #endif // RS911X_WIFI -#ifdef RS911X_WIFI // for RS9116, 917 NCP and 917 SoC -/* RSI Power Save */ -#if SL_ICD_ENABLED -#if (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) -sl_status_t wfx_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state); -#else -sl_status_t wfx_power_save(); -#endif /* (SLI_SI91X_MCU_INTERFACE | EXP_BOARD) */ -#endif /* SL_ICD_ENABLED */ -#endif /* RS911X_WIFI */ - #ifdef __cplusplus extern "C" { #endif diff --git a/src/platform/silabs/wifi/icd/WifiSleepManager.cpp b/src/platform/silabs/wifi/icd/WifiSleepManager.cpp new file mode 100644 index 00000000000000..702ee38203697f --- /dev/null +++ b/src/platform/silabs/wifi/icd/WifiSleepManager.cpp @@ -0,0 +1,170 @@ +/* + * + * 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 + +namespace { + +// TODO: Once the platform sleep calls are unified, we can removed this ifdef +#if SLI_SI917 // 917 SoC & NCP + +/** + * @brief Configures the Wi-Fi Chip to go to DTIM based sleep. + * Function sets the listen interval to be synced with the DTIM beacon and disables the broadcast filter. + * + * @return CHIP_ERROR CHIP_NO_ERROR if the configuration of the Wi-Fi chip was successful; otherwise CHIP_ERROR_INTERNAL + */ +CHIP_ERROR ConfigureDTIMBasedSleep() +{ + ReturnLogErrorOnFailure(ConfigureBroadcastFilter(false)); + + // Allowing the device to go to sleep must be the last actions to avoid configuration failures. + ReturnLogErrorOnFailure(ConfigurePowerSave(RSI_SLEEP_MODE_2, ASSOCIATED_POWER_SAVE, 0)); + + return CHIP_NO_ERROR; +} + +/** + * @brief Configures the Wi-Fi chip to go Deep Sleep. + * Function doesn't change the state of the broadcast filter. + * + * @return CHIP_ERROR CHIP_NO_ERROR if the configuration of the Wi-Fi chip was successful; otherwise CHIP_ERROR_INTERNAL + */ +CHIP_ERROR ConfigureDeepSleep() +{ + ReturnLogErrorOnFailure(ConfigurePowerSave(RSI_SLEEP_MODE_8, DEEP_SLEEP_WITH_RAM_RETENTION, 0)); + return CHIP_NO_ERROR; +} + +/** + * @brief Configures the Wi-Fi chip to go to High Performance. + * Function doesn't change the broad cast filter configuration. + * + * @return CHIP_ERROR CHIP_NO_ERROR if the configuration of the Wi-Fi chip was successful; otherwise CHIP_ERROR_INTERNAL + */ +CHIP_ERROR ConfigureHighPerformance() +{ + ReturnLogErrorOnFailure(ConfigurePowerSave(RSI_ACTIVE, HIGH_PERFORMANCE, 0)); + return CHIP_NO_ERROR; +} +#endif // SLI_SI917 + +} // namespace + +namespace chip { +namespace DeviceLayer { +namespace Silabs { + +// Initialize the static instance +WifiSleepManager WifiSleepManager::mInstance; + +CHIP_ERROR WifiSleepManager::Init() +{ + return VerifyAndTransitionToLowPowerMode(PowerEvent::kGenericEvent); +} + +CHIP_ERROR WifiSleepManager::RequestHighPerformance() +{ + VerifyOrReturnError(mHighPerformanceRequestCounter < std::numeric_limits::max(), CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "High performance request counter overflow")); + + mHighPerformanceRequestCounter++; + + // We don't do the mHighPerformanceRequestCounter check here; the check is in the VerifyAndTransitionToLowPowerMode function + ReturnErrorOnFailure(VerifyAndTransitionToLowPowerMode(PowerEvent::kGenericEvent)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WifiSleepManager::RemoveHighPerformanceRequest() +{ + VerifyOrReturnError(mHighPerformanceRequestCounter > 0, CHIP_NO_ERROR, + ChipLogError(DeviceLayer, "Wi-Fi configuration already in low power mode")); + + mHighPerformanceRequestCounter--; + + // We don't do the mHighPerformanceRequestCounter check here; the check is in the VerifyAndTransitionToLowPowerMode function + ReturnErrorOnFailure(VerifyAndTransitionToLowPowerMode(PowerEvent::kGenericEvent)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WifiSleepManager::HandlePowerEvent(PowerEvent event) +{ + switch (event) + { + case PowerEvent::kCommissioningComplete: + ChipLogProgress(AppServer, "WifiSleepManager: Handling Commissioning Complete Event"); + mIsCommissioningInProgress = false; + + // TODO: Remove High Performance Req during commissioning when sleep issues are resolved + WifiSleepManager::GetInstance().RemoveHighPerformanceRequest(); + break; + + case PowerEvent::kConnectivityChange: + case PowerEvent::kGenericEvent: + // No additional processing needed for these events at the moment + break; + + default: + ChipLogError(AppServer, "Unknown Power Event"); + return CHIP_ERROR_INVALID_ARGUMENT; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WifiSleepManager::VerifyAndTransitionToLowPowerMode(PowerEvent event) +{ + ReturnErrorOnFailure(HandlePowerEvent(event)); + +#if SLI_SI917 // 917 SoC & NCP + if (mHighPerformanceRequestCounter > 0) + { + return ConfigureHighPerformance(); + } + + if (mIsCommissioningInProgress) + { + // During commissioning, don't let the device go to sleep + // This is needed to interrupt the sleep and retry joining the network + return CHIP_NO_ERROR; + } + + // TODO: Clean this up when the Wi-Fi interface re-work is finished + wfx_wifi_provision_t wifiConfig; + wfx_get_wifi_provision(&wifiConfig); + + if (!(wifiConfig.ssid[0] != 0)) + { + return ConfigureDeepSleep(); + } + + return ConfigureDTIMBasedSleep(); + +#else + ReturnErrorOnFailure(ConfigurePowerSave()); + return CHIP_NO_ERROR; +#endif +} + +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/wifi/icd/WifiSleepManager.h b/src/platform/silabs/wifi/icd/WifiSleepManager.h new file mode 100644 index 00000000000000..a9677e4ab9321d --- /dev/null +++ b/src/platform/silabs/wifi/icd/WifiSleepManager.h @@ -0,0 +1,137 @@ + +/* + * + * 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 DeviceLayer { +namespace Silabs { + +/** + * @brief WifiSleepManager is a singleton class that manages the sleep modes for Wi-Fi devices. + * The class contains the business logic associated with optimizing the sleep states based on the Matter SDK internal states + */ +class WifiSleepManager +{ +public: + WifiSleepManager(const WifiSleepManager &) = delete; + WifiSleepManager & operator=(const WifiSleepManager &) = delete; + + static WifiSleepManager & GetInstance() { return mInstance; } + + enum class PowerEvent : uint8_t + { + kGenericEvent = 0, + kCommissioningComplete = 1, + kConnectivityChange = 2, + }; + + /** + * @brief Init function that configure the SleepManager APIs based on the type of ICD. + * Function validates that the SleepManager configuration were correctly set as well. + * + * Triggers an initial VerifyAndTransitionToLowPowerMode to set the initial sleep mode. + * + * @return CHIP_ERROR CHIP_NO_ERROR if the device was transitionned to low power + * CHIP_ERROR_INTERNAL if an error occured + */ + CHIP_ERROR Init(); + + inline void HandleCommissioningSessionStarted() + { + mIsCommissioningInProgress = true; + + // TODO: Remove High Performance Req during commissioning when sleep issues are resolved + // WifiSleepManager::GetInstance().RequestHighPerformance(); + } + + inline void HandleCommissioningSessionStopped() + { + mIsCommissioningInProgress = false; + + // TODO: Remove High Performance Req during commissioning when sleep issues are resolved + WifiSleepManager::GetInstance().RemoveHighPerformanceRequest(); + } + + /** + * @brief Public API to request the Wi-Fi chip to transition to High Performance. + * Function increases the HighPerformance request counter to prevent the chip from going to sleep + * while the Matter SDK is in a state that requires High Performance + * + * It is not necessary to call VerifyAndTransitionToLowPowerMode after calling this function. + * The API does the call after incrementing the HighPerformance request counter. + * + * @return CHIP_ERROR CHIP_NO_ERROR if the chip was set to high performance or already in high performance + * CHIP_ERROR_INTERNAL, if the high performance configuration failed + */ + CHIP_ERROR RequestHighPerformance(); + + /** + * @brief Public API to remove request to keep the Wi-Fi chip in High Performance. + * If calling this function removes the last High performance request, + * The chip will transition to sleep based on its lowest sleep level allowed + * + * + * It is not necessary to call VerifyAndTransitionToLowPowerMode after calling this function. + * The API does the call after decreasing the HighPerformance request counter. + * + * @return CHIP_ERROR CHIP_NO_ERROR if the req removal and sleep transition succeed + * CHIP_ERROR_INTERNAL, if the req removal or the transition to sleep failed + */ + CHIP_ERROR RemoveHighPerformanceRequest(); + + /** + * @brief Public API to validate what is the lowest power mode the device can got to and transitions the device to the + * determined low power state. + * + * State machine logic: + * 1. If there are high performance requests, configure high performance mode. + * 2. If commissioning is in progress, configure DTIM based sleep. + * 3. If no commissioning is in progress and the device is unprovisioned, configure deep sleep. + * + * @param event PowerEvent triggering the Verify and transition to low power mode processing + * + * @return CHIP_ERROR CHIP_NO_ERROR if the device was transitionned to low power + * CHIP_ERROR_INTERNAL if an error occured + */ + CHIP_ERROR VerifyAndTransitionToLowPowerMode(PowerEvent event); + +private: + WifiSleepManager() = default; + ~WifiSleepManager() = default; + + /** + * @brief Function to handle the power events before transitionning the device to the appropriate low power mode. + * + * @param event PowerEvent to handle + * @return CHIP_ERROR CHIP_NO_ERROR if the event was handled successfully + * CHIP_ERROR_INVALID_ARGUMENT if the event is not supported + */ + CHIP_ERROR HandlePowerEvent(PowerEvent event); + + static WifiSleepManager mInstance; + + bool mIsCommissioningInProgress = false; + uint8_t mHighPerformanceRequestCounter = 0; +}; + +} // namespace Silabs +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/silabs/wifi/rs911x/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/rs911x/WifiInterfaceImpl.cpp index 94e5f2ee020c2c..3e386a829c0330 100644 --- a/src/platform/silabs/wifi/rs911x/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/rs911x/WifiInterfaceImpl.cpp @@ -139,6 +139,30 @@ CHIP_ERROR ResetCounters() return CHIP_NO_ERROR; } +#if CHIP_CONFIG_ENABLE_ICD_SERVER +CHIP_ERROR ConfigurePowerSave() +{ + int32_t status = RSI_SUCCESS; +#ifdef RSI_BLE_ENABLE + status = rsi_bt_power_save_profile(RSI_SLEEP_MODE_2, RSI_MAX_PSP); + VerifyOrReturnError(status == RSI_SUCCESS, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "BT Powersave Config Failed, Error Code : 0x%lX", status)); +#endif /* RSI_BLE_ENABLE */ + + status = rsi_wlan_power_save_profile(RSI_SLEEP_MODE_2, RSI_MAX_PSP); + VerifyOrReturnError(status == RSI_SUCCESS, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "WLAN Powersave Config Failed, Error Code : 0x%lX", status)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConfigureBroadcastFilter(bool enableBroadcastFilter) +{ + // TODO: Implement Broadcast filtering. We do a silent failure to avoid causing problems in higher layers. + return CHIP_NO_ERROR; +} +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + /****************************************************************** * @fn void rsi_wireless_driver_task_wrapper(void * argument) * @brief @@ -780,36 +804,3 @@ int32_t wfx_rsi_send_data(void * p, uint16_t len) return status; } - -#if SL_ICD_ENABLED -/********************************************************************* - * @fn sl_status_t wfx_power_save(void) - * @brief - * Implements the power save in sleepy application - * @param[in] None - * @return SL_STATUS_OK if successful, - * SL_STATUS_FAIL otherwise - ***********************************************************************/ -sl_status_t wfx_power_save(void) -{ - int32_t status; -#ifdef RSI_BLE_ENABLE - status = rsi_bt_power_save_profile(RSI_SLEEP_MODE_2, RSI_MAX_PSP); - if (status != RSI_SUCCESS) - { - ChipLogError(DeviceLayer, "BT Powersave Config Failed, Error Code : 0x%lX", status); - return SL_STATUS_FAIL; - } -#endif /* RSI_BLE_ENABLE */ - - status = rsi_wlan_power_save_profile(RSI_SLEEP_MODE_2, RSI_MAX_PSP); - if (status != RSI_SUCCESS) - { - ChipLogError(DeviceLayer, "Powersave Config Failed, Error Code : 0x%lX", status); - return SL_STATUS_FAIL; - } - - ChipLogDetail(DeviceLayer, "Powersave Config Success"); - return SL_STATUS_OK; -} -#endif /* SL_ICD_ENABLED */ diff --git a/src/platform/silabs/wifi/wf200/WifiInterfaceImpl.cpp b/src/platform/silabs/wifi/wf200/WifiInterfaceImpl.cpp index 11ce99b088e72d..5edeaa9359fd9c 100644 --- a/src/platform/silabs/wifi/wf200/WifiInterfaceImpl.cpp +++ b/src/platform/silabs/wifi/wf200/WifiInterfaceImpl.cpp @@ -432,6 +432,20 @@ CHIP_ERROR GetAccessPointExtendedInfo(wfx_wifi_scan_ext_t & info) return CHIP_NO_ERROR; } +#if CHIP_CONFIG_ENABLE_ICD_SERVER +CHIP_ERROR ConfigurePowerSave() +{ + // TODO: Implement Power save configuration. We do a silent failure to avoid causing problems in higher layers. + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConfigureBroadcastFilter(bool enableBroadcastFilter) +{ + // TODO: Implement Broadcast filtering. We do a silent failure to avoid causing problems in higher layers. + return CHIP_NO_ERROR; +} +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + /*************************************************************************** * @brief * Creates WFX events processing task. diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 819d2614ce349d..6752b8bc63811e 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -46,7 +46,13 @@ #include extern "C" { +#if defined(CONFIG_BT_B9X) +extern __attribute__((noinline)) int b9x_bt_blc_mac_init(uint8_t * bt_mac); +#elif defined(CONFIG_BT_TLX) +extern __attribute__((noinline)) int tlx_bt_blc_mac_init(uint8_t * bt_mac); +#elif defined(CONFIG_BT_W91) extern __attribute__((noinline)) void telink_bt_blc_mac_init(uint8_t * bt_mac); +#endif } #if defined(CONFIG_PM) && !defined(CONFIG_CHIP_ENABLE_PM_DURING_BLE) @@ -117,7 +123,13 @@ CHIP_ERROR InitBLEMACAddress() int error = 0; bt_addr_le_t addr; +#if defined(CONFIG_BT_B9X) + b9x_bt_blc_mac_init(addr.a.val); +#elif defined(CONFIG_BT_TLX) + tlx_bt_blc_mac_init(addr.a.val); +#elif defined(CONFIG_BT_W91) telink_bt_blc_mac_init(addr.a.val); +#endif if (BT_ADDR_IS_STATIC(&addr.a)) // in case of Random static address, create a new id { diff --git a/src/platform/telink/CHIPDevicePlatformConfig.h b/src/platform/telink/CHIPDevicePlatformConfig.h index 655ac128953bee..8229b781a22a94 100644 --- a/src/platform/telink/CHIPDevicePlatformConfig.h +++ b/src/platform/telink/CHIPDevicePlatformConfig.h @@ -145,6 +145,8 @@ #if !defined(CONFIG_CHIP_MALLOC_SYS_HEAP) && defined(CONFIG_NEWLIB_LIBC) /// Use mallinfo() to obtain the heap usage statistics exposed by SoftwareDiagnostics cluster attributes. #define CHIP_DEVICE_CONFIG_HEAP_STATISTICS_MALLINFO 1 +#else +#define CHIP_DEVICE_CONFIG_HEAP_STATISTICS_MALLINFO 0 #endif // !defined(CONFIG_CHIP_MALLOC_SYS_HEAP) && defined(CONFIG_NEWLIB_LIBC) #endif // CHIP_DEVICE_CONFIG_HEAP_STATISTICS_MALLINFO diff --git a/src/platform/telink/tl3218x_2m_flash.overlay b/src/platform/telink/tl3218x_2m_flash.overlay index 53114e6ac6054d..bff368eea1578a 100644 --- a/src/platform/telink/tl3218x_2m_flash.overlay +++ b/src/platform/telink/tl3218x_2m_flash.overlay @@ -9,27 +9,27 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x13000>; + reg = <0x00000000 0xf000>; }; - slot0_partition: partition@13000 { + slot0_partition: partition@f000 { label = "image-0"; - reg = <0x13000 0xef000>; + reg = <0xf000 0xf1000>; }; - factory_partition: partition@102000 { + factory_partition: partition@100000 { label = "factory-data"; - reg = <0x102000 0x800>; + reg = <0x100000 0x800>; }; - factory_rfu_partition: partition@102800 { + factory_rfu_partition: partition@100800 { label = "factory-data-rfu"; - reg = <0x102800 0x800>; + reg = <0x100800 0x800>; }; - storage_partition: partition@103000 { + storage_partition: partition@101000 { label = "storage"; - reg = <0x103000 0xc000>; + reg = <0x101000 0xc000>; }; - slot1_partition: partition@10f000 { + slot1_partition: partition@10d000 { label = "image-1"; - reg = <0x10f000 0xef000>; + reg = <0x10d000 0xf1000>; }; vendor_partition: partition@1fe000 { label = "vendor-data"; diff --git a/src/platform/telink/tl7218x_2m_flash.overlay b/src/platform/telink/tl7218x_2m_flash.overlay index 53114e6ac6054d..d08d0e4ff4a6ba 100644 --- a/src/platform/telink/tl7218x_2m_flash.overlay +++ b/src/platform/telink/tl7218x_2m_flash.overlay @@ -9,27 +9,23 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x13000>; + reg = <0x00000000 0xf000>; }; - slot0_partition: partition@13000 { + slot0_partition: partition@f000 { label = "image-0"; - reg = <0x13000 0xef000>; + reg = <0xf000 0xf1000>; }; - factory_partition: partition@102000 { + factory_partition: partition@100000 { label = "factory-data"; - reg = <0x102000 0x800>; + reg = <0x100000 0x1000>; }; - factory_rfu_partition: partition@102800 { - label = "factory-data-rfu"; - reg = <0x102800 0x800>; - }; - storage_partition: partition@103000 { + storage_partition: partition@101000 { label = "storage"; - reg = <0x103000 0xc000>; + reg = <0x101000 0xc000>; }; - slot1_partition: partition@10f000 { + slot1_partition: partition@10d000 { label = "image-1"; - reg = <0x10f000 0xef000>; + reg = <0x10d000 0xf1000>; }; vendor_partition: partition@1fe000 { label = "vendor-data"; diff --git a/src/platform/telink/tlsr9518adk80d_1m_flash.overlay b/src/platform/telink/tlsr9518adk80d_1m_flash.overlay index ba55da341398f5..1a49a150cf3206 100644 --- a/src/platform/telink/tlsr9518adk80d_1m_flash.overlay +++ b/src/platform/telink/tlsr9518adk80d_1m_flash.overlay @@ -9,11 +9,11 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x19000>; + reg = <0x00000000 0xf000>; }; - slot0_partition: partition@19000 { + slot0_partition: partition@f000 { label = "image-0"; - reg = <0x19000 0xd9000>; + reg = <0xf000 0xe3000>; }; factory_partition: partition@f2000 { label = "factory-data"; diff --git a/src/platform/telink/tlsr9518adk80d_2m_flash.overlay b/src/platform/telink/tlsr9518adk80d_2m_flash.overlay index 4fd5fd13086046..62c17e96bd0031 100644 --- a/src/platform/telink/tlsr9518adk80d_2m_flash.overlay +++ b/src/platform/telink/tlsr9518adk80d_2m_flash.overlay @@ -9,23 +9,23 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x19000>; + reg = <0x00000000 0xd000>; }; - slot0_partition: partition@19000 { + slot0_partition: partition@d000 { label = "image-0"; - reg = <0x19000 0xec000>; + reg = <0xd000 0xf2000>; }; - factory_partition: partition@105000 { + factory_partition: partition@ff000 { label = "factory-data"; - reg = <0x105000 0x1000>; + reg = <0xff000 0x1000>; }; - storage_partition: partition@106000 { + storage_partition: partition@100000 { label = "storage"; - reg = <0x106000 0xc000>; + reg = <0x100000 0xc000>; }; - slot1_partition: partition@112000 { + slot1_partition: partition@10c000 { label = "image-1"; - reg = <0x112000 0xec000>; + reg = <0x10c000 0xf2000>; }; vendor_partition: partition@1fe000 { label = "vendor-data"; diff --git a/src/platform/telink/tlsr9518adk80d_mars.conf b/src/platform/telink/tlsr9518adk80d_mars.conf index 1b7b4a47378f6c..268a64d1d03c91 100644 --- a/src/platform/telink/tlsr9518adk80d_mars.conf +++ b/src/platform/telink/tlsr9518adk80d_mars.conf @@ -8,7 +8,6 @@ CONFIG_SENSOR=y # WS2812 CONFIG_LED_STRIP=y CONFIG_LED_STRIP_LOG_LEVEL_DBG=y -CONFIG_WS2812_STRIP=y CONFIG_WS2812_STRIP_GPIO_TELINK=y # DFU via USB diff --git a/src/platform/telink/tlsr9528a_2m_flash.overlay b/src/platform/telink/tlsr9528a_2m_flash.overlay index 35d72affa95023..d08d0e4ff4a6ba 100644 --- a/src/platform/telink/tlsr9528a_2m_flash.overlay +++ b/src/platform/telink/tlsr9528a_2m_flash.overlay @@ -9,31 +9,23 @@ boot_partition: partition@0 { label = "mcuboot"; - reg = <0x00000000 0x13000>; + reg = <0x00000000 0xf000>; }; - slot0_partition: partition@13000 { + slot0_partition: partition@f000 { label = "image-0"; - reg = <0x13000 0xec000>; + reg = <0xf000 0xf1000>; }; - factory_partition: partition@ff000 { + factory_partition: partition@100000 { label = "factory-data"; - reg = <0xff000 0x1000>; + reg = <0x100000 0x1000>; }; - dac_keypair_partition: partition@100000 { - label = "dac-keypair"; - reg = <0x100000 0x1000>; //store dac and key pair. - }; - descriptor_partition: partition@101000 { - label = "sboot-descriptor"; - reg = <0x101000 0x2000>; - }; - storage_partition: partition@103000 { + storage_partition: partition@101000 { label = "storage"; - reg = <0x103000 0xf000>; + reg = <0x101000 0xc000>; }; - slot1_partition: partition@112000 { + slot1_partition: partition@10d000 { label = "image-1"; - reg = <0x112000 0xec000>; + reg = <0x10d000 0xf1000>; }; vendor_partition: partition@1fe000 { label = "vendor-data"; diff --git a/src/platform/webos/ThreadStackManagerImpl.h b/src/platform/webos/ThreadStackManagerImpl.h index 64c3b8f6200bb8..5a70e882e595ee 100644 --- a/src/platform/webos/ThreadStackManagerImpl.h +++ b/src/platform/webos/ThreadStackManagerImpl.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include namespace chip { namespace DeviceLayer { diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index 65e2dfbb185274..d423dc466191db 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -48,6 +48,55 @@ #include #include +namespace { + +enum class PBKDFParamRequestTags : uint8_t +{ + kInitiatorRandom = 1, + kInitiatorSessionId = 2, + kPasscodeId = 3, + kHasPBKDFParameters = 4, + kInitiatorSessionParams = 5, +}; + +enum class PBKDFParamResponseTags : uint8_t +{ + kInitiatorRandom = 1, + kResponderRandom = 2, + kResponderSessionId = 3, + kPbkdfParameters = 4, + kResponderSessionParams = 5, +}; + +enum class PBKDFParameterSetTags : uint8_t +{ + kIterations = 1, + kSalt = 2, +}; + +enum class Pake1Tags : uint8_t +{ + kPa = 1, +}; + +enum class Pake2Tags : uint8_t +{ + kPb = 1, + kCb = 2, +}; +enum class Pake3Tags : uint8_t +{ + kCa = 1, +}; + +// Utility to extract the underlying value of TLV Tag enum classes, used in TLV encoding and parsing. +template +constexpr chip::TLV::Tag AsTlvContextTag(Enum e) +{ + return chip::TLV::ContextTag(chip::to_underlying(e)); +} + +} // namespace namespace chip { using namespace Crypto; @@ -275,6 +324,23 @@ CHIP_ERROR PASESession::DeriveSecureSession(CryptoContext & session) return CHIP_NO_ERROR; } +CHIP_ERROR PASESession::ReadSessionParamsIfPresent(const TLV::Tag & expectedSessionParamsTag, + System::PacketBufferTLVReader & tlvReader) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + err = tlvReader.Next(); + if (err == CHIP_NO_ERROR && tlvReader.GetTag() == expectedSessionParamsTag) + { + ReturnErrorOnFailure(DecodeSessionParametersIfPresent(expectedSessionParamsTag, tlvReader, mRemoteSessionParams)); + mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters( + GetRemoteSessionParameters()); + + err = tlvReader.Next(); + } + return err; +} + CHIP_ERROR PASESession::SendPBKDFParamRequest() { MATTER_TRACE_SCOPE("SendPBKDFParamRequest", "PASESession"); @@ -298,13 +364,16 @@ CHIP_ERROR PASESession::SendPBKDFParamRequest() TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); - ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(1), mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(2), GetLocalSessionId().Value())); - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), kDefaultCommissioningPasscodeId)); - ReturnErrorOnFailure(tlvWriter.PutBoolean(TLV::ContextTag(4), mHavePBKDFParameters)); + ReturnErrorOnFailure(tlvWriter.PutBytes(AsTlvContextTag(PBKDFParamRequestTags::kInitiatorRandom), mPBKDFLocalRandomData, + sizeof(mPBKDFLocalRandomData))); + ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(PBKDFParamRequestTags::kInitiatorSessionId), GetLocalSessionId().Value())); + ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(PBKDFParamRequestTags::kPasscodeId), kDefaultCommissioningPasscodeId)); + ReturnErrorOnFailure(tlvWriter.PutBoolean(AsTlvContextTag(PBKDFParamRequestTags::kHasPBKDFParameters), mHavePBKDFParameters)); VerifyOrReturnError(mLocalMRPConfig.HasValue(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorOnFailure(EncodeSessionParameters(TLV::ContextTag(5), mLocalMRPConfig.Value(), tlvWriter)); + + ReturnErrorOnFailure(EncodeSessionParameters(AsTlvContextTag(PBKDFParamRequestTags::kInitiatorSessionParams), + mLocalMRPConfig.Value(), tlvWriter)); ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize(&req)); @@ -338,7 +407,6 @@ CHIP_ERROR PASESession::HandlePBKDFParamRequest(System::PacketBufferHandle && ms uint16_t initiatorSessionId; uint8_t initiatorRandom[kPBKDFParamRandomNumberSize]; - uint32_t decodeTagIdSeq = 0; PasscodeId passcodeId = kDefaultCommissioningPasscodeId; bool hasPBKDFParameters = false; @@ -350,32 +418,34 @@ CHIP_ERROR PASESession::HandlePBKDFParamRequest(System::PacketBufferHandle && ms SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag())); SuccessOrExit(err = tlvReader.EnterContainer(containerType)); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParamRequestTags::kInitiatorRandom))); + VerifyOrExit(tlvReader.GetLength() == kPBKDFParamRandomNumberSize, err = CHIP_ERROR_INVALID_TLV_ELEMENT); SuccessOrExit(err = tlvReader.GetBytes(initiatorRandom, sizeof(initiatorRandom))); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParamRequestTags::kInitiatorSessionId))); SuccessOrExit(err = tlvReader.Get(initiatorSessionId)); ChipLogDetail(SecureChannel, "Peer assigned session ID %d", initiatorSessionId); SetPeerSessionId(initiatorSessionId); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParamRequestTags::kPasscodeId))); SuccessOrExit(err = tlvReader.Get(passcodeId)); VerifyOrExit(passcodeId == kDefaultCommissioningPasscodeId, err = CHIP_ERROR_INVALID_PASE_PARAMETER); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParamRequestTags::kHasPBKDFParameters))); SuccessOrExit(err = tlvReader.Get(hasPBKDFParameters)); - if (tlvReader.Next() != CHIP_END_OF_TLV) - { - SuccessOrExit(err = DecodeSessionParametersIfPresent(TLV::ContextTag(5), tlvReader, mRemoteSessionParams)); - mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters( - GetRemoteSessionParameters()); - } + err = ReadSessionParamsIfPresent(AsTlvContextTag(PBKDFParamRequestTags::kInitiatorSessionParams), tlvReader); + + // Future-proofing: CHIP_NO_ERROR will be returned by Next() within ReadSessionParamsIfPresent() if we have additional + // non-parsed TLV Elements, which could happen in the future if additional elements are added to the specification. + VerifyOrExit(err == CHIP_END_OF_TLV || err == CHIP_NO_ERROR, /* No Action */); + + // ExitContainer() acts as a safeguard to ensure that the received encoded message is properly terminated with an EndOfContainer + // TLV element. It is called as an extra validation step to enforce input data structure integrity. Without it, the message may + // still parse correctly, but malformed or incomplete data might go undetected. + // ExitContainer() will return CHIP_END_OF_TLV if the EndOfContainer TLV element terminator is missing. + SuccessOrExit(err = tlvReader.ExitContainer(containerType)); err = SendPBKDFParamResponse(ByteSpan(initiatorRandom), hasPBKDFParameters); SuccessOrExit(err); @@ -416,21 +486,24 @@ CHIP_ERROR PASESession::SendPBKDFParamResponse(ByteSpan initiatorRandom, bool in TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); // The initiator random value is being sent back in the response as required by the specifications - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(1), initiatorRandom)); - ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(2), mPBKDFLocalRandomData, sizeof(mPBKDFLocalRandomData))); - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(3), GetLocalSessionId().Value())); + ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(PBKDFParamResponseTags::kInitiatorRandom), initiatorRandom)); + ReturnErrorOnFailure(tlvWriter.PutBytes(AsTlvContextTag(PBKDFParamResponseTags::kResponderRandom), mPBKDFLocalRandomData, + sizeof(mPBKDFLocalRandomData))); + ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(PBKDFParamResponseTags::kResponderSessionId), GetLocalSessionId().Value())); if (!initiatorHasPBKDFParams) { TLV::TLVType pbkdfParamContainer; - ReturnErrorOnFailure(tlvWriter.StartContainer(TLV::ContextTag(4), TLV::kTLVType_Structure, pbkdfParamContainer)); - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(1), mIterationCount)); - ReturnErrorOnFailure(tlvWriter.PutBytes(TLV::ContextTag(2), mSalt, mSaltLength)); + ReturnErrorOnFailure(tlvWriter.StartContainer(AsTlvContextTag(PBKDFParamResponseTags::kPbkdfParameters), + TLV::kTLVType_Structure, pbkdfParamContainer)); + ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(PBKDFParameterSetTags::kIterations), mIterationCount)); + ReturnErrorOnFailure(tlvWriter.PutBytes(AsTlvContextTag(PBKDFParameterSetTags::kSalt), mSalt, mSaltLength)); ReturnErrorOnFailure(tlvWriter.EndContainer(pbkdfParamContainer)); } VerifyOrReturnError(mLocalMRPConfig.HasValue(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorOnFailure(EncodeSessionParameters(TLV::ContextTag(5), mLocalMRPConfig.Value(), tlvWriter)); + ReturnErrorOnFailure(EncodeSessionParameters(AsTlvContextTag(PBKDFParamResponseTags::kResponderSessionParams), + mLocalMRPConfig.Value(), tlvWriter)); ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize(&resp)); @@ -459,7 +532,6 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m uint16_t responderSessionId; uint8_t random[kPBKDFParamRandomNumberSize]; - uint32_t decodeTagIdSeq = 0; ByteSpan salt; uint8_t serializedWS[kSpake2p_WS_Length * 2] = { 0 }; @@ -471,19 +543,17 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag())); SuccessOrExit(err = tlvReader.EnterContainer(containerType)); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); // Initiator's random value + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParamResponseTags::kInitiatorRandom))); SuccessOrExit(err = tlvReader.GetBytes(random, sizeof(random))); VerifyOrExit(ByteSpan(random).data_equal(ByteSpan(mPBKDFLocalRandomData)), err = CHIP_ERROR_INVALID_PASE_PARAMETER); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); // Responder's random value + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParamResponseTags::kResponderRandom))); + VerifyOrExit(tlvReader.GetLength() == kPBKDFParamRandomNumberSize, err = CHIP_ERROR_INVALID_TLV_ELEMENT); SuccessOrExit(err = tlvReader.GetBytes(random, sizeof(random))); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParamResponseTags::kResponderSessionId))); SuccessOrExit(err = tlvReader.Get(responderSessionId)); ChipLogDetail(SecureChannel, "Peer assigned session ID %d", responderSessionId); @@ -491,40 +561,44 @@ CHIP_ERROR PASESession::HandlePBKDFParamResponse(System::PacketBufferHandle && m if (mHavePBKDFParameters) { - if (tlvReader.Next() != CHIP_END_OF_TLV) - { - SuccessOrExit(err = DecodeSessionParametersIfPresent(TLV::ContextTag(5), tlvReader, mRemoteSessionParams)); - mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters( - GetRemoteSessionParameters()); - } + err = ReadSessionParamsIfPresent(AsTlvContextTag(PBKDFParamResponseTags::kResponderSessionParams), tlvReader); + + // Future-proofing: CHIP_NO_ERROR will be returned by Next() within ReadSessionParamsIfPresent() if we have additional + // non-parsed TLV Elements, which could happen in the future if additional elements are added to the specification. + VerifyOrExit(err == CHIP_END_OF_TLV || err == CHIP_NO_ERROR, /* No Action */); // TODO - Add a unit test that exercises mHavePBKDFParameters path salt = ByteSpan(mSalt, mSaltLength); } else { - SuccessOrExit(err = tlvReader.Next()); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParamResponseTags::kPbkdfParameters))); SuccessOrExit(err = tlvReader.EnterContainer(containerType)); - decodeTagIdSeq = 0; - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParameterSetTags::kIterations))); SuccessOrExit(err = tlvReader.Get(mIterationCount)); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(PBKDFParameterSetTags::kSalt))); + VerifyOrExit(tlvReader.GetLength() >= kSpake2p_Min_PBKDF_Salt_Length && + tlvReader.GetLength() <= kSpake2p_Max_PBKDF_Salt_Length, + err = CHIP_ERROR_INVALID_TLV_ELEMENT); SuccessOrExit(err = tlvReader.Get(salt)); SuccessOrExit(err = tlvReader.ExitContainer(containerType)); - if (tlvReader.Next() != CHIP_END_OF_TLV) - { - SuccessOrExit(err = DecodeSessionParametersIfPresent(TLV::ContextTag(5), tlvReader, mRemoteSessionParams)); - mExchangeCtxt.Value()->GetSessionHandle()->AsUnauthenticatedSession()->SetRemoteSessionParameters( - GetRemoteSessionParameters()); - } + err = ReadSessionParamsIfPresent(AsTlvContextTag(PBKDFParamResponseTags::kResponderSessionParams), tlvReader); + + // Future-proofing: CHIP_NO_ERROR will be returned by Next() within ReadSessionParamsIfPresent() if we have additional + // non-parsed TLV Elements, which could happen in the future if additional elements are added to the specification. + VerifyOrExit(err == CHIP_END_OF_TLV || err == CHIP_NO_ERROR, /* No Action */); } + // ExitContainer() acts as a safeguard to ensure that the received encoded message is properly terminated with an EndOfContainer + // TLV element. It is called as an extra validation step to enforce input data structure integrity. Without it, the message may + // still parse correctly, but malformed or incomplete data might go undetected. + // ExitContainer() will return CHIP_END_OF_TLV if the EndOfContainer TLV element terminator is missing. + SuccessOrExit(err = tlvReader.ExitContainer(containerType)); + err = SetupSpake2p(); SuccessOrExit(err); @@ -562,11 +636,9 @@ CHIP_ERROR PASESession::SendMsg1() uint8_t X[kMAX_Point_Length]; size_t X_len = sizeof(X); - constexpr uint8_t kPake1_pA = 1; - ReturnErrorOnFailure(mSpake2p.ComputeRoundOne(nullptr, 0, X, &X_len)); VerifyOrReturnError(X_len == sizeof(X), CHIP_ERROR_INTERNAL); - ReturnErrorOnFailure(tlvWriter.Put(TLV::ContextTag(kPake1_pA), ByteSpan(X))); + ReturnErrorOnFailure(tlvWriter.Put(AsTlvContextTag(Pake1Tags::kPa), ByteSpan(X))); ReturnErrorOnFailure(tlvWriter.EndContainer(outerContainerType)); ReturnErrorOnFailure(tlvWriter.Finalize(&msg)); @@ -603,10 +675,13 @@ CHIP_ERROR PASESession::HandleMsg1_and_SendMsg2(System::PacketBufferHandle && ms SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag())); SuccessOrExit(err = tlvReader.EnterContainer(containerType)); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == 1, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(Pake1Tags::kPa))); X_len = tlvReader.GetLength(); + VerifyOrExit(X_len == kMAX_Point_Length, err = CHIP_ERROR_INVALID_TLV_ELEMENT); SuccessOrExit(err = tlvReader.GetDataPtr(X)); + + SuccessOrExit(err = tlvReader.ExitContainer(containerType)); + SuccessOrExit(err = mSpake2p.BeginVerifier(nullptr, 0, nullptr, 0, mPASEVerifier.mW0, kP256_FE_Length, mPASEVerifier.mL, kP256_Point_Length)); @@ -616,9 +691,7 @@ CHIP_ERROR PASESession::HandleMsg1_and_SendMsg2(System::PacketBufferHandle && ms msg1 = nullptr; { - const size_t max_msg_len = TLV::EstimateStructOverhead(Y_len, verifier_len); - constexpr uint8_t kPake2_pB = 1; - constexpr uint8_t kPake2_cB = 2; + const size_t max_msg_len = TLV::EstimateStructOverhead(Y_len, verifier_len); System::PacketBufferHandle msg2 = System::PacketBufferHandle::New(max_msg_len); VerifyOrExit(!msg2.IsNull(), err = CHIP_ERROR_NO_MEMORY); @@ -628,8 +701,8 @@ CHIP_ERROR PASESession::HandleMsg1_and_SendMsg2(System::PacketBufferHandle && ms TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); - SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kPake2_pB), ByteSpan(Y))); - SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kPake2_cB), ByteSpan(verifier, verifier_len))); + SuccessOrExit(err = tlvWriter.Put(AsTlvContextTag(Pake2Tags::kPb), ByteSpan(Y))); + SuccessOrExit(err = tlvWriter.Put(AsTlvContextTag(Pake2Tags::kCb), ByteSpan(verifier, verifier_len))); SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType)); SuccessOrExit(err = tlvWriter.Finalize(&msg2)); @@ -673,30 +746,33 @@ CHIP_ERROR PASESession::HandleMsg2_and_SendMsg3(System::PacketBufferHandle && ms const uint8_t * peer_verifier; size_t peer_verifier_len = 0; - uint32_t decodeTagIdSeq = 0; - tlvReader.Init(std::move(msg2)); SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag())); SuccessOrExit(err = tlvReader.EnterContainer(containerType)); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(Pake2Tags::kPb))); Y_len = tlvReader.GetLength(); + VerifyOrExit(Y_len == kMAX_Point_Length, err = CHIP_ERROR_INVALID_TLV_ELEMENT); SuccessOrExit(err = tlvReader.GetDataPtr(Y)); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == ++decodeTagIdSeq, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(Pake2Tags::kCb))); peer_verifier_len = tlvReader.GetLength(); + VerifyOrExit(peer_verifier_len == kMAX_Hash_Length, err = CHIP_ERROR_INVALID_TLV_ELEMENT); SuccessOrExit(err = tlvReader.GetDataPtr(peer_verifier)); + // ExitContainer() acts as a safeguard to ensure that the received encoded message is properly terminated with an EndOfContainer + // TLV element. It is called as an extra validation step to enforce input data structure integrity. Without it, the message may + // still parse correctly, but malformed or incomplete data might go undetected. + // ExitContainer() will return CHIP_END_OF_TLV if the EndOfContainer TLV element terminator is missing. + SuccessOrExit(err = tlvReader.ExitContainer(containerType)); + SuccessOrExit(err = mSpake2p.ComputeRoundTwo(Y, Y_len, verifier, &verifier_len)); SuccessOrExit(err = mSpake2p.KeyConfirm(peer_verifier, peer_verifier_len)); msg2 = nullptr; { - const size_t max_msg_len = TLV::EstimateStructOverhead(verifier_len); - constexpr uint8_t kPake3_cB = 1; + const size_t max_msg_len = TLV::EstimateStructOverhead(verifier_len); System::PacketBufferHandle msg3 = System::PacketBufferHandle::New(max_msg_len); VerifyOrExit(!msg3.IsNull(), err = CHIP_ERROR_NO_MEMORY); @@ -706,7 +782,7 @@ CHIP_ERROR PASESession::HandleMsg2_and_SendMsg3(System::PacketBufferHandle && ms TLV::TLVType outerContainerType = TLV::kTLVType_NotSpecified; SuccessOrExit(err = tlvWriter.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outerContainerType)); - SuccessOrExit(err = tlvWriter.Put(TLV::ContextTag(kPake3_cB), ByteSpan(verifier, verifier_len))); + SuccessOrExit(err = tlvWriter.Put(AsTlvContextTag(Pake3Tags::kCa), ByteSpan(verifier, verifier_len))); SuccessOrExit(err = tlvWriter.EndContainer(outerContainerType)); SuccessOrExit(err = tlvWriter.Finalize(&msg3)); @@ -747,12 +823,16 @@ CHIP_ERROR PASESession::HandleMsg3(System::PacketBufferHandle && msg) SuccessOrExit(err = tlvReader.Next(containerType, TLV::AnonymousTag())); SuccessOrExit(err = tlvReader.EnterContainer(containerType)); - SuccessOrExit(err = tlvReader.Next()); - VerifyOrExit(TLV::TagNumFromTag(tlvReader.GetTag()) == 1, err = CHIP_ERROR_INVALID_TLV_TAG); + SuccessOrExit(err = tlvReader.Next(AsTlvContextTag(Pake3Tags::kCa))); peer_verifier_len = tlvReader.GetLength(); + VerifyOrExit(peer_verifier_len == kMAX_Hash_Length, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); SuccessOrExit(err = tlvReader.GetDataPtr(peer_verifier)); - VerifyOrExit(peer_verifier_len == kMAX_Hash_Length, err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + // ExitContainer() acts as a safeguard to ensure that the received encoded message is properly terminated with an EndOfContainer + // TLV element. It is called as an extra validation step to enforce input data structure integrity. Without it, the message may + // still parse correctly, but malformed or incomplete data might go undetected. + // ExitContainer() will return CHIP_END_OF_TLV if the EndOfContainer TLV element terminator is missing. + SuccessOrExit(err = tlvReader.ExitContainer(containerType)); SuccessOrExit(err = mSpake2p.KeyConfirm(peer_verifier, peer_verifier_len)); diff --git a/src/protocols/secure_channel/PASESession.h b/src/protocols/secure_channel/PASESession.h index a24539eaf508e7..d2db297296ae9e 100644 --- a/src/protocols/secure_channel/PASESession.h +++ b/src/protocols/secure_channel/PASESession.h @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -201,6 +202,14 @@ class DLL_EXPORT PASESession : public Messaging::UnsolicitedMessageHandler, CHIP_ERROR OnFailureStatusReport(Protocols::SecureChannel::GeneralStatusCode generalCode, uint16_t protocolCode, Optional protocolData) override; + /** This function returns the CHIP_ERROR from a call to TLVReader::Next() method. + * + * @retval #CHIP_END_OF_TLV If the end of the TLV encoding is reached. + * @retval #CHIP_NO_ERROR If there are additional non-parsed TLV Elements. + * @retval other See return values of TLVReader::Next() + **/ + CHIP_ERROR ReadSessionParamsIfPresent(const TLV::Tag & SessionParamsTag, System::PacketBufferTLVReader & tlvReader); + void Finish(); // mNextExpectedMsg is set when we are expecting a message. diff --git a/src/python_testing/TC_CGEN_2_10.py b/src/python_testing/TC_CGEN_2_10.py index 4e094148e3d0d1..6bc7e1be8217ca 100644 --- a/src/python_testing/TC_CGEN_2_10.py +++ b/src/python_testing/TC_CGEN_2_10.py @@ -52,8 +52,7 @@ def pics_TC_CGEN_2_10(self) -> list[str]: def steps_TC_CGEN_2_10(self) -> list[TestStep]: return [ - TestStep(0, description="", expectation="", is_commissioning=False), - TestStep(1, "TH reads from the DUT the attribute TCAcceptedVersion. Store the value as acceptedVersion."), + TestStep(1, "TH reads from the DUT the attribute TCAcceptedVersion. Store the value as acceptedVersion.", is_commissioning=False), TestStep(2, "TH reads from the DUT the attribute TCAcknowledgements. Store the value as userAcknowledgements."), TestStep(3, "TH Sends the SetTCAcknowledgements command to the DUT with the fields set as follows:\n* TCVersion: 0\n* TCUserResponse: 65535"), TestStep(4, "TH reads from the DUT the attribute TCAcceptedVersion."), @@ -67,7 +66,6 @@ def steps_TC_CGEN_2_10(self) -> list[TestStep]: async def test_TC_CGEN_2_10(self): commissioner: ChipDeviceCtrl.ChipDeviceController = self.default_controller - self.step(0) if not self.check_pics("CGEN.S.F00"): asserts.skip('Root endpoint does not support the [commissioning] feature under test') return diff --git a/src/python_testing/TC_CGEN_2_11.py b/src/python_testing/TC_CGEN_2_11.py index dc600135fad1ef..f5c32cf581199f 100644 --- a/src/python_testing/TC_CGEN_2_11.py +++ b/src/python_testing/TC_CGEN_2_11.py @@ -53,8 +53,7 @@ def pics_TC_CGEN_2_11(self) -> list[str]: def steps_TC_CGEN_2_11(self) -> list[TestStep]: return [ - TestStep(0, description="", expectation="", is_commissioning=False), - TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc."), + TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc.", is_commissioning=False), TestStep(2, "TH sends SetTCAcknowledgements to DUT with the following values:\n* TCVersion: PIXIT.CGEN.TCRevision\n* TCUserResponse: PIXIT.CGEN.RequiredTCAcknowledgements"), TestStep(3, "TH sends CommissioningComplete to DUT."), TestStep(4, "TH Sends the SetTCAcknowledgements command to the DUT with the fields set as follows:\n* TCVersion: PIXIT.CGEN.TCRevision + 1\n* TCUserResponse: PIXIT.CGEN.RequiredTCAcknowledgements"), @@ -70,7 +69,6 @@ async def test_TC_CGEN_2_11(self): tc_version_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.TCRevision'] tc_user_response_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.RequiredTCAcknowledgements'] - self.step(0) if not self.check_pics("CGEN.S.F00"): asserts.skip('Root endpoint does not support the [commissioning] feature under test') return diff --git a/src/python_testing/TC_CGEN_2_5.py b/src/python_testing/TC_CGEN_2_5.py index f6d6043958b005..e5b8fc57d5638f 100644 --- a/src/python_testing/TC_CGEN_2_5.py +++ b/src/python_testing/TC_CGEN_2_5.py @@ -55,8 +55,7 @@ def pics_TC_CGEN_2_5(self) -> list[str]: def steps_TC_CGEN_2_5(self) -> list[TestStep]: return [ - TestStep(0, description="", expectation="", is_commissioning=False), - TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc."), + TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc.", is_commissioning=False), TestStep(2, "TH reads TCAcknowledgementsRequired attribute from the DUT"), TestStep(3, "TH reads TCUpdateDeadline attribute from the DUT"), TestStep(4, "TH reads the FeatureMap from the General Commissioning Cluster."), @@ -78,7 +77,6 @@ async def test_TC_CGEN_2_5(self): tc_version_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.TCRevision'] tc_user_response_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.RequiredTCAcknowledgements'] - self.step(0) if not self.check_pics("CGEN.S.F00"): asserts.skip('Root endpoint does not support the [commissioning] feature under test') return diff --git a/src/python_testing/TC_CGEN_2_6.py b/src/python_testing/TC_CGEN_2_6.py index 07017842d59df1..b9e4c3da67dfc2 100644 --- a/src/python_testing/TC_CGEN_2_6.py +++ b/src/python_testing/TC_CGEN_2_6.py @@ -50,8 +50,7 @@ def pics_TC_CGEN_2_6(self) -> list[str]: def steps_TC_CGEN_2_6(self) -> list[TestStep]: return [ - TestStep(0, description="", expectation="", is_commissioning=False), - TestStep(1, "TH starts commissioning the DUT. It performs all commissioning steps from 'Device discovery and establish commissioning channel' to 'Security setup using CASE', except for TC configuration with SetTCAcknowledgements."), + TestStep(1, "TH starts commissioning the DUT. It performs all commissioning steps from 'Device discovery and establish commissioning channel' to 'Security setup using CASE', except for TC configuration with SetTCAcknowledgements.", is_commissioning=False), TestStep(2, "TH sends CommissioningComplete to DUT."), ] @@ -59,7 +58,6 @@ def steps_TC_CGEN_2_6(self) -> list[TestStep]: async def test_TC_CGEN_2_6(self): commissioner: ChipDeviceCtrl.ChipDeviceController = self.default_controller - self.step(0) if not self.check_pics("CGEN.S.F00"): asserts.skip('Root endpoint does not support the [commissioning] feature under test') return diff --git a/src/python_testing/TC_CGEN_2_7.py b/src/python_testing/TC_CGEN_2_7.py index 95a15b8cbd8229..dbc8aa309cf443 100644 --- a/src/python_testing/TC_CGEN_2_7.py +++ b/src/python_testing/TC_CGEN_2_7.py @@ -53,8 +53,7 @@ def pics_TC_CGEN_2_7(self) -> list[str]: def steps_TC_CGEN_2_7(self) -> list[TestStep]: return [ - TestStep(0, description="", expectation="", is_commissioning=False), - TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc."), + TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc.", is_commissioning=False), TestStep(2, "TH reads from the DUT the attribute TCMinRequiredVersion. Store the value as minVersion."), TestStep(3, "TH sends SetTCAcknowledgements to DUT with the following values:\n* TCVersion: minVersion\n* TCUserResponse: 0"), TestStep(4, "TH continues commissioning with the DUT and performs the steps from 'Operation CSR exchange' through 'Security setup using CASE'"), @@ -70,7 +69,6 @@ async def test_TC_CGEN_2_7(self): tc_version_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.TCRevision'] tc_user_response_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.RequiredTCAcknowledgements'] - self.step(0) if not self.check_pics("CGEN.S.F00"): asserts.skip('Root endpoint does not support the [commissioning] feature under test') return diff --git a/src/python_testing/TC_CGEN_2_8.py b/src/python_testing/TC_CGEN_2_8.py index abef5a3fc67dda..5e154cd15ee719 100644 --- a/src/python_testing/TC_CGEN_2_8.py +++ b/src/python_testing/TC_CGEN_2_8.py @@ -53,8 +53,7 @@ def pics_TC_CGEN_2_8(self) -> list[str]: def steps_TC_CGEN_2_8(self) -> list[TestStep]: return [ - TestStep(0, description="", expectation="", is_commissioning=False), - TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc."), + TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc.", is_commissioning=False), TestStep(2, "TH sends SetTCAcknowledgements to DUT with the following values:\n* TCVersion: PIXIT.CGEN.TCRevision\n* TCUserResponse: PIXIT.CGEN.RequiredTCAcknowledgements"), TestStep(3, "TH continues commissioning steps with the DUT and performs steps 'Operation CSR exchange' through 'Security setup using CASE'"), TestStep(4, "TH sends CommissioningComplete to DUT."), @@ -74,7 +73,6 @@ async def test_TC_CGEN_2_8(self): tc_version_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.TCRevision'] tc_user_response_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.RequiredTCAcknowledgements'] - self.step(0) if not self.check_pics("CGEN.S.F00"): asserts.skip('Root endpoint does not support the [commissioning] feature under test') return @@ -131,6 +129,9 @@ async def test_TC_CGEN_2_8(self): "First CommissioningComplete failed", ) + # Close the commissioner session with the device to clean up resources + commissioner.CloseSession(nodeid=self.dut_node_id) + # Step 5: Factory reset is handled by test operator self.step(5) if not self.check_pics('PICS_USER_PROMPT'): diff --git a/src/python_testing/TC_CGEN_2_9.py b/src/python_testing/TC_CGEN_2_9.py index 03521e5dd89b38..fce3b5a2a9b4e3 100644 --- a/src/python_testing/TC_CGEN_2_9.py +++ b/src/python_testing/TC_CGEN_2_9.py @@ -76,8 +76,7 @@ def pics_TC_CGEN_2_9(self) -> list[str]: def steps_TC_CGEN_2_9(self) -> list[TestStep]: return [ - TestStep(0, description="", expectation="", is_commissioning=False), - TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc."), + TestStep(1, "TH begins commissioning the DUT and performs the following steps in order:\n* Security setup using PASE\n* Setup fail-safe timer, with ExpiryLengthSeconds field set to PIXIT.CGEN.FailsafeExpiryLengthSeconds and the Breadcrumb value as 1\n* Configure information- UTC time, regulatory, etc.", is_commissioning=False), TestStep(2, "TH sends SetTCAcknowledgements to DUT with the following values:\n* TCVersion: PIXIT.CGEN.TCRevision\n* TCUserResponse: PIXIT.CGEN.RequiredTCAcknowledgements"), TestStep(3, "TH continues commissioning with the DUT and performs the steps from 'Operation CSR exchange' through 'Security setup using CASE'"), TestStep(4, "TH sends CommissioningComplete to DUT."), @@ -94,7 +93,6 @@ async def test_TC_CGEN_2_9(self): tc_version_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.TCRevision'] tc_user_response_to_simulate = self.matter_test_config.global_test_params['PIXIT.CGEN.RequiredTCAcknowledgements'] - self.step(0) if not self.check_pics("CGEN.S.F00"): asserts.skip('Root endpoint does not support the [commissioning] feature under test') return @@ -159,6 +157,9 @@ async def test_TC_CGEN_2_9(self): self.step(5) await self.remove_commissioner_fabric() + # Close the commissioner session with the device to clean up resources + commissioner.CloseSession(nodeid=self.dut_node_id) + # Step 6: Put device in commissioning mode (requiring user input, so skip in CI) self.step(6) if not self.check_pics('PICS_USER_PROMPT'): diff --git a/src/python_testing/TC_DA_1_2.py b/src/python_testing/TC_DA_1_2.py index 5c0b6dbf154d7c..dde370293eb514 100644 --- a/src/python_testing/TC_DA_1_2.py +++ b/src/python_testing/TC_DA_1_2.py @@ -43,8 +43,8 @@ import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status from chip.testing.basic_composition import BasicCompositionTests -from chip.testing.matter_testing import (MatterBaseTest, TestStep, async_test_body, default_matter_test_main, hex_from_bytes, - type_matches) +from chip.testing.conversions import hex_from_bytes +from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main, type_matches from chip.tlv import TLVReader from cryptography import x509 from cryptography.exceptions import InvalidSignature diff --git a/src/python_testing/TC_DA_1_5.py b/src/python_testing/TC_DA_1_5.py index e8e6ce773c6fec..6ee3c81ac370ad 100644 --- a/src/python_testing/TC_DA_1_5.py +++ b/src/python_testing/TC_DA_1_5.py @@ -40,7 +40,8 @@ import chip.clusters as Clusters from chip import ChipDeviceCtrl from chip.interaction_model import InteractionModelError, Status -from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, hex_from_bytes, type_matches +from chip.testing.conversions import hex_from_bytes +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, type_matches from chip.tlv import TLVReader from cryptography import x509 from cryptography.hazmat.primitives import hashes diff --git a/src/python_testing/TC_DA_1_7.py b/src/python_testing/TC_DA_1_7.py index 6678080a600d6b..ce9399d8b7896c 100644 --- a/src/python_testing/TC_DA_1_7.py +++ b/src/python_testing/TC_DA_1_7.py @@ -41,8 +41,8 @@ from typing import List, Optional import chip.clusters as Clusters -from chip.testing.matter_testing import (MatterBaseTest, TestStep, async_test_body, bytes_from_hex, default_matter_test_main, - hex_from_bytes) +from chip.testing.conversions import bytes_from_hex, hex_from_bytes +from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ec diff --git a/src/python_testing/TC_DEMTestBase.py b/src/python_testing/TC_DEMTestBase.py index 49c8c6a6375a3e..64c27916b420c4 100644 --- a/src/python_testing/TC_DEMTestBase.py +++ b/src/python_testing/TC_DEMTestBase.py @@ -19,7 +19,7 @@ import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status -from chip.testing.matter_testing import utc_time_in_matter_epoch +from chip.testing.timeoperations import utc_time_in_matter_epoch from mobly import asserts logger = logging.getLogger(__name__) diff --git a/src/python_testing/TC_DGETH_2_1.py b/src/python_testing/TC_DGETH_2_1.py deleted file mode 100644 index 0068a0e338fefe..00000000000000 --- a/src/python_testing/TC_DGETH_2_1.py +++ /dev/null @@ -1,157 +0,0 @@ -# -# Copyright (c) 2025 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# script-args: > -# --PICS src/app/tests/suites/certification/ci-pics-values -# --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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.clusters.Types import NullValue -from chip.testing import matter_asserts -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from mobly import asserts - - -class TC_DGETH_2_1(MatterBaseTest): - """ - [TC-DGETH-2.1] Ethernet Diagnostics Cluster - Attribute Read Verification - - This test case verifies the behavior of the attributes of the Ethernet Diagnostics cluster server. - See the test plan steps for details on each attribute read and expected outcome. - - Requirements: - - The Test Harness and DUT must be running on different physical devices. - - Communication between the Test Harness and DUT should occur via Ethernet. - """ - - async def read_dgeth_attribute_expect_success(self, endpoint, attribute): - cluster = Clusters.Objects.EthernetNetworkDiagnostics - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - - def desc_TC_DGETH_2_1(self) -> str: - """Returns a description of this test""" - return "[TC-DGETH-2.1] Attributes with Server as DUT" - - def pics_TC_DGETH_2_1(self) -> list[str]: - return ["DGETH.S"] - - def steps_TC_DGETH_2_1(self) -> list[TestStep]: - steps = [ - TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Read PHYRate attribute"), - TestStep(3, "Read FullDuplex attribute"), - TestStep(4, "Read PacketRxCount attribute"), - TestStep(5, "Read PacketTxCount attribute"), - TestStep(6, "Read TxErrCount attribute"), - TestStep(7, "Read CollisionCount attribute"), - TestStep(8, "Read OverrunCount attribute"), - TestStep(9, "Read CarrierDetect attribute"), - TestStep(10, "Read TimeSinceReset attribute"), - ] - return steps - - @async_test_body - async def test_TC_DGETH_2_1(self): - - endpoint = self.get_endpoint(0) - - # STEP 1: Commission DUT (already done) - self.step(1) - - attributes = Clusters.EthernetNetworkDiagnostics.Attributes - - # STEP 2: TH reads from the DUT the PHYRate attribute - self.step(2) - phy_rate_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.PHYRate) - if phy_rate_attr is not None: - if phy_rate_attr is not NullValue: - matter_asserts.assert_valid_enum(phy_rate_attr, "PHYRate", Clusters.EthernetNetworkDiagnostics.Enums.PHYRateEnum) - - # STEP 3: TH reads from the DUT the FullDuplex attribute - self.step(3) - full_duplex_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.FullDuplex) - if full_duplex_attr is not None: - if full_duplex_attr is not NullValue: - matter_asserts.assert_valid_bool(full_duplex_attr, "FullDuplex") - - # STEP 4: TH reads from the DUT the PacketRxCount attribute - self.step(4) - packet_rx_count_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.PacketRxCount) - if packet_rx_count_attr is not None: - matter_asserts.assert_valid_uint64(packet_rx_count_attr, "PacketRxCount") - if not self.is_pics_sdk_ci_only: - asserts.assert_true(packet_rx_count_attr > 0, f"PacketRxCount ({packet_rx_count_attr}) should be > 0)") - - # STEP 5: TH reads from the DUT the PacketTxCount attribute - self.step(5) - packet_tx_count_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.PacketTxCount) - if packet_tx_count_attr is not None: - matter_asserts.assert_valid_uint64(packet_tx_count_attr, "PacketTxCount") - if not self.is_pics_sdk_ci_only: - asserts.assert_true(packet_tx_count_attr > 0, f"PacketTxCount ({packet_tx_count_attr}) should be > 0)") - - # STEP 6: TH reads from the DUT the TxErrCount attribute - self.step(6) - tx_err_count_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.TxErrCount) - if tx_err_count_attr is not None: - matter_asserts.assert_valid_uint64(tx_err_count_attr, "TxErrCount") - - # STEP 7: TH reads from the DUT the CollisionCount attribute - self.step(7) - collision_count_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.CollisionCount) - if collision_count_attr is not None: - matter_asserts.assert_valid_uint64(collision_count_attr, "CollisionCount") - - # STEP 8: TH reads from the DUT the OverrunCount attribute - self.step(8) - overrun_count_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.OverrunCount) - if overrun_count_attr is not None: - matter_asserts.assert_valid_uint64(overrun_count_attr, "OverrunCount") - - # STEP 9: TH reads from the DUT the CarrierDetect attribute - self.step(9) - carrier_detect_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.CarrierDetect) - if carrier_detect_attr is not None: - if carrier_detect_attr is not NullValue: - matter_asserts.assert_valid_bool(carrier_detect_attr, "CarrierDetect") - - # STEP 10: TH reads from the DUT the TimeSinceReset attribute - self.step(10) - time_since_reset_attr = await self.read_dgeth_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeSinceReset) - if time_since_reset_attr is not None: - matter_asserts.assert_valid_uint32(time_since_reset_attr, "TimeSinceReset") - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGGEN_2_4.py b/src/python_testing/TC_DGGEN_2_4.py index 17b068452cdae6..12a7f01a55c0c4 100644 --- a/src/python_testing/TC_DGGEN_2_4.py +++ b/src/python_testing/TC_DGGEN_2_4.py @@ -40,9 +40,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import (MatterBaseTest, async_test_body, default_matter_test_main, - matter_epoch_us_from_utc_datetime, utc_datetime_from_matter_epoch_us, - utc_datetime_from_posix_time_ms) +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main +from chip.testing.timeoperations import utc_datetime_from_matter_epoch_us, utc_datetime_from_posix_time_ms, utc_time_in_matter_epoch from mobly import asserts logger = logging.getLogger(__name__) @@ -104,7 +103,7 @@ async def test_TC_DGGEN_2_4(self): self.print_step("1b", "Write current time to DUT") # Get current time in the correct format to set via command. - th_utc = matter_epoch_us_from_utc_datetime(desired_datetime=None) + th_utc = utc_time_in_matter_epoch(desired_datetime=None) await self.set_time_in_timesync(th_utc) diff --git a/src/python_testing/TC_DGSW_2_1.py b/src/python_testing/TC_DGSW_2_1.py deleted file mode 100644 index 86022bef0fd193..00000000000000 --- a/src/python_testing/TC_DGSW_2_1.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# Copyright (c) 2024 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# 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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.testing import matter_asserts -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main - - -class TC_DGSW_2_1(MatterBaseTest): - - async def read_dgsw_attribute_expect_success(self, endpoint, attribute): - cluster = Clusters.Objects.SoftwareDiagnostics - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - - def desc_TC_DGSW_2_1(self) -> str: - """Returns a description of this test""" - return "[TC-DGSW-2.1] Attributes with Server as DUT" - - def pics_TC_DGSW_2_1(self) -> list[str]: - return ["DGSW.S"] - - def steps_TC_DGSW_2_1(self) -> list[TestStep]: - steps = [ - TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Read the ThreadMetrics attribute"), - TestStep(3, "Read the CurrentHeapFree attribute"), - TestStep(4, "Read the CurrentHeapUsed attribute"), - TestStep(5, "Read the CurrentHeapHighWatermark attribute"), - ] - return steps - - @async_test_body - async def test_TC_DGSW_2_1(self): - - endpoint = self.get_endpoint(default=0) - - # STEP 1: Commission DUT (already done) - self.step(1) - - attributes = Clusters.SoftwareDiagnostics.Attributes - attribute_list = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) - - # STEP 2: TH reads from the DUT the ThreadMetrics attribute - self.step(2) - if self.pics_guard(attributes.ThreadMetrics.attribute_id in attribute_list): - thread_metrics_list = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.ThreadMetrics) - - # Validate each element in the thread_metrics_list - for metric in thread_metrics_list: - # The Id field is mandatory - matter_asserts.assert_valid_uint64(metric.id, "Id") - - # Validate the optional Name field - if metric.name is not None: - matter_asserts.assert_is_string(metric.name, "Name") - - # Validate the optional StackFreeCurrent field - if metric.stackFreeCurrent is not None: - matter_asserts.assert_valid_uint32(metric.stackFreeCurrent, "StackFreeCurrent") - - # Validate the optional StackFreeMinimum field - if metric.stackFreeMinimum is not None: - matter_asserts.assert_valid_uint32(metric.stackFreeMinimum, "StackFreeMinimum") - - # Validate the optional StackSize field - if metric.stackSize is not None: - matter_asserts.assert_valid_uint32(metric.stackSize, "StackSize") - - # STEP 3: TH reads from the DUT the CurrentHeapFree attribute - self.step(3) - if self.pics_guard(attributes.CurrentHeapFree.attribute_id in attribute_list): - current_heap_free_attr = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentHeapFree) - matter_asserts.assert_valid_uint64(current_heap_free_attr, "CurrentHeapFree") - - # STEP 4: TH reads from the DUT the CurrentHeapUsed attribute - self.step(4) - if self.pics_guard(attributes.CurrentHeapUsed.attribute_id in attribute_list): - current_heap_used_attr = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentHeapUsed) - matter_asserts.assert_valid_uint64(current_heap_used_attr, "CurrentHeapUsed") - - # STEP 5: TH reads from the DUT the CurrentHeapHighWatermark attribute - self.step(5) - if self.pics_guard(attributes.CurrentHeapHighWatermark.attribute_id in attribute_list): - current_heap_high_watermark_attr = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentHeapHighWatermark) - matter_asserts.assert_valid_uint64(current_heap_high_watermark_attr, "CurrentHeapHighWatermark") - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGSW_2_2.py b/src/python_testing/TC_DGSW_2_2.py deleted file mode 100644 index 1d93c9da8ab942..00000000000000 --- a/src/python_testing/TC_DGSW_2_2.py +++ /dev/null @@ -1,123 +0,0 @@ -# -# Copyright (c) 2024 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: > -# --discriminator 1234 -# --KVS kvs1 -# --trace-to json:${TRACE_APP}.json -# --enable-key 000102030405060708090a0b0c0d0e0f -# script-args: > -# --storage-path admin_storage.json -# --commissioning-method on-network -# --discriminator 1234 -# --passcode 20202021 -# --hex-arg enableKey:000102030405060708090a0b0c0d0e0f -# --trace-to json:${TRACE_TEST_JSON}.json -# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto -# --enable-key 000102030405060708090a0b0c0d0e0f -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.testing import matter_asserts -from chip.testing.matter_testing import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main - - -class TC_DGSW_2_2(MatterBaseTest): - - @staticmethod - def is_valid_octet_string(value): - return isinstance(value, (bytes, bytearray)) - - async def send_software_fault_test_event_trigger(self): - await self.send_test_event_triggers(eventTrigger=0x0034000000000000) - - def validate_soft_fault_event_data(self, event_data): - """ - Validates the SoftFault event data according to the test plan and specification. - - This method checks: - - `Id` field: Must be of type uint64 - - `Name` field: Vendor-specific string - - `FaultRecording` field: Vendor-specific payload in octet string format (bytes/bytearray) - """ - - # Validate 'Id' field: Ensure it is a uint64 type - matter_asserts.assert_valid_uint64(event_data.id, "Id") - - # Validate 'Name' field: Ensure it is a string - matter_asserts.assert_is_string(event_data.name, "Name") - - # Validate 'FaultRecording' field: Ensure it is an octet string (bytes or bytearray) - matter_asserts.assert_is_octstr(event_data.faultRecording, "FaultRecording") - - def desc_TC_DGSW_2_2(self) -> str: - """Returns a description of this test""" - return "[TC-DGSW-2.2] Attributes with Server as DUT" - - def pics_TC_DGSW_2_2(self) -> list[str]: - return ["DGSW.S"] - - def steps_TC_DGSW_2_2(self) -> list[TestStep]: - steps = [ - TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Read the SoftwareFault event(s) from the DUT"), - ] - return steps - - @async_test_body - async def test_TC_DGSW_2_2(self): - - endpoint = self.get_endpoint(default=0) - - # STEP 1: Commission DUT (already done) - self.step(1) - - # Create and start an EventChangeCallback to subscribe for events - events_callback = EventChangeCallback(Clusters.SoftwareDiagnostics) - await events_callback.start( - self.default_controller, # The controller - self.dut_node_id, # DUT's node id - endpoint # The endpoint on which we expect Wi-Fi events - ) - - # STEP 2: DUT sends an event report to TH. TH reads a list of SoftwareFault structs from DUT. - self.step(2) - - # Trigger a SoftwareFault event on the DUT - await self.send_software_fault_test_event_trigger() - - # Wait (block) for the SoftwareFault event to arrive - event_data = events_callback.wait_for_event_report( - Clusters.SoftwareDiagnostics.Events.SoftwareFault - ) - - # Validate the SoftwareFault event fields - self.validate_soft_fault_event_data(event_data) - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGSW_2_3.py b/src/python_testing/TC_DGSW_2_3.py deleted file mode 100644 index 1daec5e2db6b24..00000000000000 --- a/src/python_testing/TC_DGSW_2_3.py +++ /dev/null @@ -1,191 +0,0 @@ -# -# Copyright (c) 2024 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# 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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import logging - -import chip.clusters as Clusters -from chip.testing import matter_asserts -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from mobly import asserts - - -class TC_DGSW_2_3(MatterBaseTest): - - async def read_dgsw_attribute_expect_success(self, endpoint, attribute): - cluster = Clusters.Objects.SoftwareDiagnostics - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - - async def send_reset_watermarks_command(self): - endpoint = 0 - diags_cluster = Clusters.Objects.SoftwareDiagnostics - return await self.send_single_cmd(cmd=diags_cluster.Commands.ResetWatermarks(), endpoint=endpoint) - - def desc_TC_DGSW_2_3(self) -> str: - """Returns a description of this test""" - return "[TC-DGSW-2.3] Attributes with Server as DUT" - - def pics_TC_DGSW_2_3(self) -> list[str]: - return ["DGSW.S"] - - def steps_TC_DGSW_2_3(self) -> list[TestStep]: - steps = [ - TestStep(1, "Commissioning, already done", is_commissioning=True), - TestStep(2, "Read the AttributeList attribute"), - TestStep(3, "Read the ThreadMetrics attribute"), - TestStep(4, "Read the CurrentHeapHighWatermark attribute"), - TestStep(5, "Read the CurrentHeapUsed attribute"), - TestStep(6, "Send ResetWatermarks command"), - TestStep(7, "Read the CurrentHeapHighWatermark attribute"), - TestStep(8, "Read the ThreadMetrics attribute"), - ] - return steps - - @async_test_body - async def test_TC_DGSW_2_3(self): - - endpoint = self.get_endpoint(default=0) - - # STEP 1: Commission DUT (already done) - self.step(1) - - # STEP 2: TH reads from the DUT the AttributeList attribute - self.step(2) - attributes = Clusters.SoftwareDiagnostics.Attributes - attribute_list = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) - - # STEP 3: TH reads from the DUT the ThreadMetrics attribute - self.step(3) - if self.pics_guard(attributes.ThreadMetrics.attribute_id in attribute_list): - thread_metrics_original = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.ThreadMetrics) - - # Iterate over all items in the list and validate each one - for metric in thread_metrics_original: - # The Id field is mandatory - matter_asserts.assert_valid_uint64(metric.id, "Id") - - if metric.name is not None: - matter_asserts.assert_is_string(metric.name, "Name") - - if metric.stackFreeCurrent is not None: - matter_asserts.assert_valid_uint32(metric.stackFreeCurrent, "StackFreeCurrent") - - if metric.stackFreeMinimum is not None: - matter_asserts.assert_valid_uint32(metric.stackFreeMinimum, "StackFreeMinimum") - - if metric.stackSize is not None: - matter_asserts.assert_valid_uint32(metric.stackSize, "StackSize") - - # STEP 4: TH reads from the DUT the CurrentHeapHighWatermark attribute - self.step(4) - if self.pics_guard(attributes.CurrentHeapHighWatermark.attribute_id in attribute_list): - high_watermark_original = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentHeapHighWatermark) - matter_asserts.assert_valid_uint64(high_watermark_original, "CurrentHeapHighWatermark") - - # STEP 5: TH reads from the DUT the CurrentHeapUsed attribute - self.step(5) - if self.pics_guard(attributes.CurrentHeapUsed.attribute_id in attribute_list): - current_heap_used_original = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentHeapUsed) - matter_asserts.assert_valid_uint64(current_heap_used_original, "CurrentHeapUsed") - - if high_watermark_original is not None: - asserts.assert_true(current_heap_used_original <= high_watermark_original, - "CurrentHeapUsed should be less than or equal to CurrentHeapHighWatermark") - - # STEP 6: TH sends to the DUT the command - self.step(6) - response = await self.send_reset_watermarks_command() - logging.info(f"ResetWatermarks response: {response}") - - # STEP 7: TH reads from the DUT the CurrentHeapHighWatermark attribute - self.step(7) - if self.pics_guard(attributes.CurrentHeapHighWatermark.attribute_id in attribute_list): - current_heap_high_watermark = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentHeapHighWatermark) - matter_asserts.assert_valid_uint64(current_heap_high_watermark, "CurrentHeapHighWatermark") - - # Verify that the returned value is <= high_watermark_original - asserts.assert_true(current_heap_high_watermark <= high_watermark_original, - f"CurrentHeapHighWatermark ({current_heap_high_watermark}) should be <= high_watermark_original ({high_watermark_original})") - - # If CurrentHeapUsed is supported - if current_heap_used_original is not None and current_heap_used_original < high_watermark_original: - # Verify that the returned value is < high_watermark_original - asserts.assert_true(current_heap_high_watermark < high_watermark_original, - f"CurrentHeapHighWatermark ({current_heap_high_watermark}) should be < high_watermark_original ({high_watermark_original}) when CurrentHeapUsed ({current_heap_used_original}) is less than high_watermark_original") - - # STEP 8: TH reads from the DUT the ThreadMetrics attribute - self.step(8) - if self.pics_guard(attributes.ThreadMetrics.attribute_id in attribute_list): - thread_metrics_reset = await self.read_dgsw_attribute_expect_success(endpoint=endpoint, attribute=attributes.ThreadMetrics) - - # Validate all elements in the list - for metric in thread_metrics_reset: - matter_asserts.assert_valid_uint64(metric.id, "Id") - - if metric.name is not None: - matter_asserts.assert_is_string(metric.name, "Name") - - if metric.stackFreeCurrent is not None: - matter_asserts.assert_valid_uint32(metric.stackFreeCurrent, "StackFreeCurrent") - - if metric.stackFreeMinimum is not None: - matter_asserts.assert_valid_uint32(metric.stackFreeMinimum, "StackFreeMinimum") - - if metric.stackSize is not None: - matter_asserts.assert_valid_uint32(metric.stackSize, "StackSize") - - # Ensure the list length matches thread_metrics_original to simplify matching - asserts.assert_equal(len(thread_metrics_reset), len(thread_metrics_original), - "Mismatch in the number of items between thread_metrics_reset and thread_metrics_original") - - # Compare each item in the list - for reset_metric in thread_metrics_reset: - # Find the corresponding item in thread_metrics_original by ID - original_metric = next((m for m in thread_metrics_original if m.id == reset_metric.id), None) - asserts.assert_is_not_none(original_metric, - f"No matching ThreadMetrics entry found in thread_metrics_original for ID {reset_metric.id}") - - # Compare StackFreeMinimum if present in both - if original_metric.stackFreeMinimum is not None and reset_metric.stackFreeMinimum is not None: - asserts.assert_true( - reset_metric.stackFreeMinimum >= original_metric.stackFreeMinimum, - f"StackFreeMinimum for ID {reset_metric.id} in thread_metrics_reset ({reset_metric.stackFreeMinimum}) " - f"should be >= corresponding value in thread_metrics_original ({original_metric.stackFreeMinimum})" - ) - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGTHREAD_2_1.py b/src/python_testing/TC_DGTHREAD_2_1.py deleted file mode 100644 index 4082c71ceed3c5..00000000000000 --- a/src/python_testing/TC_DGTHREAD_2_1.py +++ /dev/null @@ -1,477 +0,0 @@ -# -# Copyright (c) 2025 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# 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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.clusters.Types import NullValue -from chip.testing import matter_asserts -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from mobly import asserts - - -class TC_THREADND_2_1(MatterBaseTest): - """ - [TC-THREADND-2.1] Thread Network Diagnostics Cluster - Attribute Read Verification - - This test case verifies the behavior of the attributes of the Thread Network Diagnostics - cluster server (Server as DUT). The test case steps are derived from the provided - test plan specification. - """ - - async def read_thread_diagnostics_attribute_expect_success(self, endpoint, attribute): - """ - Convenience method to read a single ThreadNetworkDiagnostics attribute, - ensuring success. - """ - cluster = Clusters.Objects.ThreadNetworkDiagnostics - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - - # - # --- Test Description, PICS, and Steps --- - # - def desc_TC_THREADND_2_1(self) -> str: - return "[TC-THREADND-2.1] Thread Network Diagnostics Attributes with Server as DUT" - - def pics_TC_THREADND_2_1(self) -> list[str]: - return ["THREADND.S"] # Or whatever your PICS identifiers are - - def steps_TC_THREADND_2_1(self) -> list[TestStep]: - """ - Lists the test steps from the specification in an easy-to-read format. - """ - return [ - TestStep(1, "Commission DUT to TH (already done)", is_commissioning=True), - TestStep(2, "Read Channel attribute"), - TestStep(3, "Read RoutingRole attribute"), - TestStep(4, "Read NetworkName attribute"), - TestStep(5, "Read PanId attribute"), - TestStep(6, "Read ExtendedPanId attribute"), - TestStep(7, "Read MeshLocalPrefix attribute"), - TestStep(8, "Read OverrunCount attribute"), - TestStep(9, "Read NeighborTable attribute"), - TestStep(10, "Read RouteTable attribute"), - TestStep(11, "Read PartitionId attribute"), - TestStep(12, "Read Weighting attribute"), - TestStep(13, "Read DataVersion attribute"), - TestStep(14, "Read StableDataVersion attribute"), - TestStep(15, "Read LeaderRouterId attribute"), - TestStep(16, "Read DetachedRoleCount attribute"), - TestStep(17, "Read ChildRoleCount attribute"), - TestStep(18, "Read RouterRoleCount attribute"), - TestStep(19, "Read LeaderRoleCount attribute"), - TestStep(20, "Read AttachAttemptCount attribute"), - TestStep(21, "Read PartitionIdChangeCount attribute"), - TestStep(22, "Read BetterPartitionAttachAttemptCount attribute"), - TestStep(23, "Read ParentChangeCount attribute"), - TestStep(24, "Read ActiveTimestamp attribute"), - TestStep(25, "Read PendingTimestamp attribute"), - TestStep(26, "Read Delay attribute"), - TestStep(27, "Read SecurityPolicy attribute"), - TestStep(28, "Read ChannelPage0Mask attribute"), - TestStep(29, "Read OperationalDatasetComponents attribute"), - TestStep(30, "Read ActiveNetworkFaults attribute"), - ] - - # - # --- Main Test Routine --- - # - @async_test_body - async def test_TC_THREADND_2_1(self): - endpoint = self.get_endpoint(default=0) - attributes = Clusters.ThreadNetworkDiagnostics.Attributes - - # Keep a copy of routing_role if needed for cross-check logic - routing_role = None - - # - # STEP 1: Commissioning (assumed done) - # - self.step(1) - # Normally performed by harness; no explicit code needed if already commissioned. - - # - # STEP 2: Read Channel - # - self.step(2) - channel = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.Channel) - - # Thread devices operate in the 2.4GHz band using IEEE802.15.4 channels 11 through 26. - if channel is not NullValue: - matter_asserts.assert_valid_uint16(channel, "Channel") - asserts.assert_true(11 <= channel <= 26, "Channel out of expected range") - - # - # STEP 3: Read RoutingRole - # - self.step(3) - routing_role = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RoutingRole) - if routing_role is not NullValue: - matter_asserts.assert_valid_enum(routing_role, "RoutingRole", Clusters.ThreadNetworkDiagnostics.Enums.RoutingRoleEnum) - - # - # STEP 4: Read NetworkName - # - self.step(4) - network_name = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.NetworkName) - if network_name is not NullValue: - # Must be a string up to 16 bytes - matter_asserts.assert_is_string(network_name, "NetworkName") - asserts.assert_true(len(network_name.encode("utf-8")) <= 16, f"{network_name} length exceeds 16 bytes.") - - # - # STEP 5: Read PanId - # - self.step(5) - pan_id = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.PanId) - if pan_id is not NullValue: - matter_asserts.assert_valid_uint16(pan_id, "PanId") - - # - # STEP 6: Read ExtendedPanId - # - self.step(6) - extended_pan_id = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.ExtendedPanId) - if extended_pan_id is not NullValue: - matter_asserts.assert_valid_uint64(extended_pan_id, "ExtendedPanId") - - # - # STEP 7: Read MeshLocalPrefix - # - self.step(7) - mesh_local_prefix = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.MeshLocalPrefix) - if mesh_local_prefix is not NullValue: - matter_asserts.assert_is_octstr(mesh_local_prefix, "MeshLocalPrefix") - # Verify that MeshLocalPrefix is IPv6 address and is exactly 8 bytes long. - asserts.assert_equal( - len(mesh_local_prefix), - 8, - "MeshLocalPrefix must be 8 bytes (64 bits)." - ) - - # - # STEP 8: Read OverrunCount - # - self.step(8) - overrun_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.OverrunCount) - if overrun_count is not None: - matter_asserts.assert_valid_uint64(overrun_count, "OverrunCount") - - # - # STEP 9: Read NeighborTable - # - self.step(9) - neighbor_table = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.NeighborTable) - asserts.assert_true(isinstance(neighbor_table, list), - "NeighborTable attribute should be a list.") - - # neighbor_table is typically a list of neighbor table entries. Each entry has fields like: - # ExtAddress (uint64), - # Age (uint32), - # Rloc16 (uint16), - # LinkFrameCounter (uint32), - # MleFrameCounter (uint32), - # LQI (uint8), - # AverageRssi (int8), - # LastRssi (int8), - # FrameErrorRate (uint8), - # MessageErrorRate (uint8), - # RxOnWhenIdle (bool), - # FullThreadDevice (bool), - # FullNetworkData (bool), - # IsChild (bool) - # - # Verify the list type: - for entry in neighbor_table: - # Each entry is typically a cluster object with the fields below: - matter_asserts.assert_valid_uint64(entry.extAddress, "NeighborTable.ExtAddress") - matter_asserts.assert_valid_uint32(entry.age, "NeighborTable.Age") - matter_asserts.assert_valid_uint16(entry.rloc16, "NeighborTable.Rloc16") - matter_asserts.assert_valid_uint32(entry.linkFrameCounter, "NeighborTable.LinkFrameCounter") - matter_asserts.assert_valid_uint32(entry.mleFrameCounter, "NeighborTable.MleFrameCounter") - - matter_asserts.assert_valid_uint8(entry.lqi, "NeighborTable.LQI") - asserts.assert_true(0 <= entry.lqi <= 255, "NeighborTable.LQI must be 0..255") - - matter_asserts.assert_valid_int8(entry.averageRssi, "NeighborTable.AverageRssi") - asserts.assert_true(-128 <= entry.averageRssi <= 0, "AverageRssi must be -128..0 dBm") - - matter_asserts.assert_valid_int8(entry.lastRssi, "NeighborTable.LastRssi") - asserts.assert_true(-128 <= entry.lastRssi <= 0, "LastRssi must be -128..0 dBm") - - matter_asserts.assert_valid_uint8(entry.frameErrorRate, "NeighborTable.FrameErrorRate") - asserts.assert_true(0 <= entry.frameErrorRate <= 100, "FrameErrorRate must be 0..100") - - matter_asserts.assert_valid_uint8(entry.messageErrorRate, "NeighborTable.MessageErrorRate") - asserts.assert_true(0 <= entry.messageErrorRate <= 100, "MessageErrorRate must be 0..100") - - matter_asserts.assert_valid_bool(entry.rxOnWhenIdle, "NeighborTable.RxOnWhenIdle") - matter_asserts.assert_valid_bool(entry.fullThreadDevice, "NeighborTable.FullThreadDevice") - matter_asserts.assert_valid_bool(entry.fullNetworkData, "NeighborTable.FullNetworkData") - matter_asserts.assert_valid_bool(entry.isChild, "NeighborTable.IsChild") - - # - # STEP 10: Read RouteTable - # - self.step(10) - route_table = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RouteTable) - asserts.assert_true(isinstance(route_table, list), - "RouteTable attribute should be a list.") - for entry in route_table: - # Each entry typically has fields: - # ExtAddress (uint64), - # Rloc16 (uint16), - # RouterId (uint8), - # NextHop (uint8), - # PathCost (uint8), - # LQIIn (uint8), - # LQIOut (uint8), - # Age (uint8), - # Allocated (bool), - # LinkEstablished (bool) - matter_asserts.assert_valid_uint64(entry.extAddress, "RouteTable.ExtAddress") - matter_asserts.assert_valid_uint16(entry.rloc16, "RouteTable.Rloc16") - matter_asserts.assert_valid_uint8(entry.routerId, "RouteTable.RouterId") - matter_asserts.assert_valid_uint8(entry.nextHop, "RouteTable.NextHop") - matter_asserts.assert_valid_uint8(entry.pathCost, "RouteTable.PathCost") - - matter_asserts.assert_valid_uint8(entry.lqiIn, "RouteTable.LQIIn") - asserts.assert_true(0 <= entry.lqiIn <= 255, "RouteTable.LQIIn must be 0..255") - - matter_asserts.assert_valid_uint8(entry.lqiOut, "RouteTable.LQIOut") - asserts.assert_true(0 <= entry.lqiOut <= 255, "RouteTable.LQIOut must be 0..255") - - matter_asserts.assert_valid_uint8(entry.age, "RouteTable.Age") - matter_asserts.assert_valid_bool(entry.allocated, "RouteTable.Allocated") - matter_asserts.assert_valid_bool(entry.linkEstablished, "RouteTable.LinkEstablished") - - # - # STEP 11: Read PartitionId - # - self.step(11) - partition_id = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.PartitionId) - if partition_id is not NullValue: - matter_asserts.assert_valid_uint32(partition_id, "PartitionId") - - # - # STEP 12: Read Weighting - # - self.step(12) - weighting = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.Weighting) - if weighting is not NullValue: - matter_asserts.assert_valid_uint8(weighting, "Weighting") - - # - # STEP 13: Read DataVersion - # - self.step(13) - data_version = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.DataVersion) - if data_version is not NullValue: - matter_asserts.assert_valid_uint8(data_version, "DataVersion") - - # - # STEP 14: Read StableDataVersion - # - self.step(14) - stable_data_version = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.StableDataVersion) - if stable_data_version is not NullValue: - matter_asserts.assert_valid_uint8(stable_data_version, "StableDataVersion") - - # - # STEP 15: Read LeaderRouterId - # - self.step(15) - leader_router_id = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.LeaderRouterId) - if leader_router_id is not NullValue: - matter_asserts.assert_valid_uint8(leader_router_id, "LeaderRouterId") - - # - # STEP 16: Read DetachedRoleCount - # - self.step(16) - detached_role_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.DetachedRoleCount) - if detached_role_count is not None: - matter_asserts.assert_valid_uint16(detached_role_count, "DetachedRoleCount") - - # - # STEP 17: Read ChildRoleCount - # - self.step(17) - child_role_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.ChildRoleCount) - if child_role_count is not None: - matter_asserts.assert_valid_uint16(child_role_count, "ChildRoleCount") - - # - # STEP 18: Read RouterRoleCount - # - self.step(18) - router_role_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RouterRoleCount) - if router_role_count is not None: - matter_asserts.assert_valid_uint16(router_role_count, "RouterRoleCount") - - # - # STEP 19: Read LeaderRoleCount - # - self.step(19) - leader_role_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.LeaderRoleCount) - if leader_role_count is not None: - matter_asserts.assert_valid_uint16(leader_role_count, "LeaderRoleCount") - - # - # STEP 20: Read AttachAttemptCount - # - self.step(20) - attach_attempt_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.AttachAttemptCount) - if attach_attempt_count is not None: - matter_asserts.assert_valid_uint16(attach_attempt_count, "AttachAttemptCount") - - # - # STEP 21: Read PartitionIdChangeCount - # - self.step(21) - partition_id_change_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.PartitionIdChangeCount) - if partition_id_change_count is not None: - matter_asserts.assert_valid_uint16(partition_id_change_count, "PartitionIdChangeCount") - - # - # STEP 22: Read BetterPartitionAttachAttemptCount - # - self.step(22) - better_partition_attach_attempt_count = await self.read_thread_diagnostics_attribute_expect_success( - endpoint, attributes.BetterPartitionAttachAttemptCount) - if better_partition_attach_attempt_count is not None: - matter_asserts.assert_valid_uint16(better_partition_attach_attempt_count, "BetterPartitionAttachAttemptCount") - - # - # STEP 23: Read ParentChangeCount - # - self.step(23) - parent_change_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.ParentChangeCount) - if parent_change_count is not None: - matter_asserts.assert_valid_uint16(parent_change_count, "ParentChangeCount") - - # - # STEP 24: Read ActiveTimestamp - # - self.step(24) - active_timestamp = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.ActiveTimestamp) - if active_timestamp is not None: - if active_timestamp is not NullValue: - matter_asserts.assert_valid_uint64(active_timestamp, "ActiveTimestamp") - - # - # STEP 25: Read PendingTimestamp - # - self.step(25) - pending_timestamp = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.PendingTimestamp) - if pending_timestamp is not None: - if pending_timestamp is not NullValue: - matter_asserts.assert_valid_uint64(pending_timestamp, "PendingTimestamp") - - # - # STEP 26: Read Delay - # - self.step(26) - delay = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.Delay) - if delay is not None: - if delay is not NullValue: - matter_asserts.assert_valid_uint64(delay, "Delay") - - # - # STEP 27: Read SecurityPolicy - # - self.step(27) - security_policy = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.SecurityPolicy) - if security_policy is not NullValue: - # Verify that the SecurityPolicy attribute has the following fields: - # . RotationTime is of the type uint16 - # . Flags is of the type uint16 - asserts.assert_true(hasattr(security_policy, "rotationTime"), "SecurityPolicy missing rotationTime field.") - asserts.assert_true(hasattr(security_policy, "flags"), "SecurityPolicy missing flags field.") - - matter_asserts.assert_valid_uint16(security_policy.rotationTime, "SecurityPolicy.RotationTime") - matter_asserts.assert_valid_uint16(security_policy.flags, "SecurityPolicy.Flags") - - # - # STEP 28: Read ChannelPage0Mask - # - self.step(28) - channel_page0_mask = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.ChannelPage0Mask) - if channel_page0_mask is not NullValue: - matter_asserts.assert_is_octstr(channel_page0_mask, "ChannelPage0Mask") - - # - # STEP 29: Read OperationalDatasetComponents - # - self.step(29) - dataset_components = await self.read_thread_diagnostics_attribute_expect_success( - endpoint, attributes.OperationalDatasetComponents - ) - if dataset_components is not NullValue: - for field_name in [ - "activeTimestampPresent", "pendingTimestampPresent", "masterKeyPresent", - "networkNamePresent", "extendedPanIdPresent", "meshLocalPrefixPresent", - "delayPresent", "panIdPresent", "channelPresent", "pskcPresent", - "securityPolicyPresent", "channelMaskPresent" - ]: - asserts.assert_true( - hasattr(dataset_components, field_name), - f"OperationalDatasetComponents missing '{field_name}' field." - ) - matter_asserts.assert_valid_bool(getattr(dataset_components, field_name), - f"OperationalDatasetComponents.{field_name}") - - # - # STEP 30: Read ActiveNetworkFaults - # - self.step(30) - active_network_faults = await self.read_thread_diagnostics_attribute_expect_success( - endpoint, attributes.ActiveNetworkFaultsList - ) - - asserts.assert_true(isinstance(active_network_faults, list), - "ActiveNetworkFaults attribute should be a list of NetworkFault enums.") - # The spec says the list can have 0..4 entries, each an enum of [0..3]. - asserts.assert_true(len(active_network_faults) <= 4, - "ActiveNetworkFaults can have at most 4 entries per the spec.") - - seen_faults = set() - for fault in active_network_faults: - # fault is typically an enum, e.g. 0=Unspecified, 1=LinkDown, 2=HardwareFailure, 3=NetworkJammed - asserts.assert_true(0 <= fault <= 3, "NetworkFault enum must be in [0..3].") - # Check single-instance occurrence - asserts.assert_false(fault in seen_faults, "Each NetworkFault must appear at most once.") - seen_faults.add(fault) - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGTHREAD_2_2.py b/src/python_testing/TC_DGTHREAD_2_2.py deleted file mode 100644 index 61e520e29c2ea1..00000000000000 --- a/src/python_testing/TC_DGTHREAD_2_2.py +++ /dev/null @@ -1,243 +0,0 @@ -# -# Copyright (c) 2025 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# 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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.testing import matter_asserts -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main - - -class TC_THREADND_2_2(MatterBaseTest): - """ - [TC-THREADND-2.2] Thread Network Diagnostics Cluster - Attribute Read Verification for Tx Attributes - - This test case verifies the behavior of the Tx-related attributes of the Thread Network Diagnostics - cluster server (Server as DUT). The test case steps are derived from the provided - test plan specification. - """ - - async def read_thread_diagnostics_attribute_expect_success(self, endpoint, attribute): - """ - Convenience method to read a single ThreadNetworkDiagnostics attribute, - ensuring success. - """ - cluster = Clusters.Objects.ThreadNetworkDiagnostics - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - - # - # --- Test Description, PICS, and Steps --- - # - def desc_TC_THREADND_2_2(self) -> str: - return "[TC-THREADND-2.2] Thread Network Diagnostics Tx Attributes with Server as DUT" - - def pics_TC_THREADND_2_2(self) -> list[str]: - return ["THREADND.S", "THREADND.SF.MACCNT"] # PICS identifiers for the test case - - def steps_TC_THREADND_2_2(self) -> list[TestStep]: - """ - Lists the test steps from the specification in an easy-to-read format. - """ - return [ - TestStep(1, "Commission DUT to TH (already done)", is_commissioning=True), - TestStep(2, "Read TxTotalCount attribute"), - TestStep(3, "Read TxUnicastCount attribute"), - TestStep(4, "Read TxBroadcastCount attribute"), - TestStep(5, "Read TxAckRequestedCount attribute"), - TestStep(6, "Read TxAckedCount attribute"), - TestStep(7, "Read TxNoAckRequestedCount attribute"), - TestStep(8, "Read TxDataCount attribute"), - TestStep(9, "Read TxDataPollCount attribute"), - TestStep(10, "Read TxBeaconCount attribute"), - TestStep(11, "Read TxBeaconRequestCount attribute"), - TestStep(12, "Read TxOtherCount attribute"), - TestStep(13, "Read TxRetryCount attribute"), - TestStep(14, "Read TxDirectMaxRetryExpiryCount attribute"), - TestStep(15, "Read TxIndirectMaxRetryExpiryCount attribute"), - TestStep(16, "Read TxErrCcaCount attribute"), - TestStep(17, "Read TxErrAbortCount attribute"), - TestStep(18, "Read TxErrBusyChannelCount attribute"), - ] - - # - # --- Main Test Routine --- - # - @async_test_body - async def test_TC_THREADND_2_2(self): - endpoint = self.get_endpoint(default=0) - attributes = Clusters.ThreadNetworkDiagnostics.Attributes - - # - # STEP 1: Commissioning (assumed done) - # - self.step(1) - # Normally performed by harness; no explicit code needed if already commissioned. - - # - # STEP 2: Read TxTotalCount - # - self.step(2) - tx_total_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxTotalCount) - if tx_total_count is not None: - matter_asserts.assert_valid_uint32(tx_total_count, "TxTotalCount") - - # - # STEP 3: Read TxUnicastCount - # - self.step(3) - tx_unicast_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxUnicastCount) - if tx_unicast_count is not None: - matter_asserts.assert_valid_uint32(tx_unicast_count, "TxUnicastCount") - - # - # STEP 4: Read TxBroadcastCount - # - self.step(4) - tx_broadcast_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxBroadcastCount) - if tx_broadcast_count is not None: - matter_asserts.assert_valid_uint32(tx_broadcast_count, "TxBroadcastCount") - - # - # STEP 5: Read TxAckRequestedCount - # - self.step(5) - tx_ack_requested_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxAckRequestedCount) - if tx_ack_requested_count is not None: - matter_asserts.assert_valid_uint32(tx_ack_requested_count, "TxAckRequestedCount") - - # - # STEP 6: Read TxAckedCount - # - self.step(6) - tx_acked_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxAckedCount) - if tx_acked_count is not None: - matter_asserts.assert_valid_uint32(tx_acked_count, "TxAckedCount") - - # - # STEP 7: Read TxNoAckRequestedCount - # - self.step(7) - tx_no_ack_requested_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxNoAckRequestedCount) - if tx_no_ack_requested_count is not None: - matter_asserts.assert_valid_uint32(tx_no_ack_requested_count, "TxNoAckRequestedCount") - - # - # STEP 8: Read TxDataCount - # - self.step(8) - tx_data_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxDataCount) - if tx_data_count is not None: - matter_asserts.assert_valid_uint32(tx_data_count, "TxDataCount") - - # - # STEP 9: Read TxDataPollCount - # - self.step(9) - tx_data_poll_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxDataPollCount) - if tx_data_poll_count is not None: - matter_asserts.assert_valid_uint32(tx_data_poll_count, "TxDataPollCount") - - # - # STEP 10: Read TxBeaconCount - # - self.step(10) - tx_beacon_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxBeaconCount) - if tx_beacon_count is not None: - matter_asserts.assert_valid_uint32(tx_beacon_count, "TxBeaconCount") - - # - # STEP 11: Read TxBeaconRequestCount - # - self.step(11) - tx_beacon_request_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxBeaconRequestCount) - if tx_beacon_request_count is not None: - matter_asserts.assert_valid_uint32(tx_beacon_request_count, "TxBeaconRequestCount") - - # - # STEP 12: Read TxOtherCount - # - self.step(12) - tx_other_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxOtherCount) - if tx_other_count is not None: - matter_asserts.assert_valid_uint32(tx_other_count, "TxOtherCount") - - # - # STEP 13: Read TxRetryCount - # - self.step(13) - tx_retry_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxRetryCount) - if tx_retry_count is not None: - matter_asserts.assert_valid_uint32(tx_retry_count, "TxRetryCount") - - # - # STEP 14: Read TxDirectMaxRetryExpiryCount - # - self.step(14) - tx_direct_max_retry_expiry_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxDirectMaxRetryExpiryCount) - if tx_direct_max_retry_expiry_count is not None: - matter_asserts.assert_valid_uint32(tx_direct_max_retry_expiry_count, "TxDirectMaxRetryExpiryCount") - - # - # STEP 15: Read TxIndirectMaxRetryExpiryCount - # - self.step(15) - tx_indirect_max_retry_expiry_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxIndirectMaxRetryExpiryCount) - if tx_indirect_max_retry_expiry_count is not None: - matter_asserts.assert_valid_uint32(tx_indirect_max_retry_expiry_count, "TxIndirectMaxRetryExpiryCount") - - # - # STEP 16: Read TxErrCcaCount - # - self.step(16) - tx_err_cca_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxErrCcaCount) - if tx_err_cca_count is not None: - matter_asserts.assert_valid_uint32(tx_err_cca_count, "TxErrCcaCount") - - # - # STEP 17: Read TxErrAbortCount - # - self.step(17) - tx_err_abort_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxErrAbortCount) - if tx_err_abort_count is not None: - matter_asserts.assert_valid_uint32(tx_err_abort_count, "TxErrAbortCount") - - # - # STEP 18: Read TxErrBusyChannelCount - # - self.step(18) - tx_err_busy_channel_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.TxErrBusyChannelCount) - if tx_err_busy_channel_count is not None: - matter_asserts.assert_valid_uint32(tx_err_busy_channel_count, "TxErrBusyChannelCount") - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGTHREAD_2_3.py b/src/python_testing/TC_DGTHREAD_2_3.py deleted file mode 100644 index e370a1576d3ad6..00000000000000 --- a/src/python_testing/TC_DGTHREAD_2_3.py +++ /dev/null @@ -1,243 +0,0 @@ -# -# Copyright (c) 2025 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# 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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.testing import matter_asserts -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main - - -class TC_THREADND_2_3(MatterBaseTest): - """ - [TC-THREADND-2.3] Thread Network Diagnostics Cluster - Rx Attribute Read Verification - - This test case verifies the behavior of the Rx-related attributes of the Thread Network Diagnostics - cluster server (Server as DUT). The test case steps are derived from the provided - test plan specification. - """ - - async def read_thread_diagnostics_attribute_expect_success(self, endpoint, attribute): - """ - Convenience method to read a single ThreadNetworkDiagnostics attribute, - ensuring success. - """ - cluster = Clusters.Objects.ThreadNetworkDiagnostics - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - - # - # --- Test Description, PICS, and Steps --- - # - def desc_TC_THREADND_2_3(self) -> str: - return "[TC-THREADND-2.3] Thread Network Diagnostics Rx Attributes with Server as DUT" - - def pics_TC_THREADND_2_3(self) -> list[str]: - return ["THREADND.S", "THREADND.SF.MACCNT"] # PICS identifiers for the test case - - def steps_TC_THREADND_2_3(self) -> list[TestStep]: - """ - Lists the test steps from the specification in an easy-to-read format. - """ - return [ - TestStep(1, "Commission DUT to TH (already done)", is_commissioning=True), - TestStep(2, "Read RxTotalCount attribute"), - TestStep(3, "Read RxUnicastCount attribute"), - TestStep(4, "Read RxBroadcastCount attribute"), - TestStep(5, "Read RxDataCount attribute"), - TestStep(6, "Read RxDataPollCount attribute"), - TestStep(7, "Read RxBeaconCount attribute"), - TestStep(8, "Read RxBeaconRequestCount attribute"), - TestStep(9, "Read RxOtherCount attribute"), - TestStep(10, "Read RxAddressFilteredCount attribute"), - TestStep(11, "Read RxDestAddrFilteredCount attribute"), - TestStep(12, "Read RxDuplicatedCount attribute"), - TestStep(13, "Read RxErrNoFrameCount attribute"), - TestStep(14, "Read RxErrUnknownNeighborCount attribute"), - TestStep(15, "Read RxErrInvalidSrcAddrCount attribute"), - TestStep(16, "Read RxErrSecCount attribute"), - TestStep(17, "Read RxErrFcsCount attribute"), - TestStep(18, "Read RxErrOtherCount attribute"), - ] - - # - # --- Main Test Routine --- - # - @async_test_body - async def test_TC_THREADND_2_3(self): - endpoint = self.get_endpoint(default=0) - attributes = Clusters.ThreadNetworkDiagnostics.Attributes - - # - # STEP 1: Commissioning (assumed done) - # - self.step(1) - # Normally performed by harness; no explicit code needed if already commissioned. - - # - # STEP 2: Read RxTotalCount - # - self.step(2) - rx_total_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxTotalCount) - if rx_total_count is not None: - matter_asserts.assert_valid_uint32(rx_total_count, "RxTotalCount") - - # - # STEP 3: Read RxUnicastCount - # - self.step(3) - rx_unicast_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxUnicastCount) - if rx_unicast_count is not None: - matter_asserts.assert_valid_uint32(rx_unicast_count, "RxUnicastCount") - - # - # STEP 4: Read RxBroadcastCount - # - self.step(4) - rx_broadcast_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxBroadcastCount) - if rx_broadcast_count is not None: - matter_asserts.assert_valid_uint32(rx_broadcast_count, "RxBroadcastCount") - - # - # STEP 5: Read RxDataCount - # - self.step(5) - rx_data_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxDataCount) - if rx_data_count is not None: - matter_asserts.assert_valid_uint32(rx_data_count, "RxDataCount") - - # - # STEP 6: Read RxDataPollCount - # - self.step(6) - rx_data_poll_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxDataPollCount) - if rx_data_poll_count is not None: - matter_asserts.assert_valid_uint32(rx_data_poll_count, "RxDataPollCount") - - # - # STEP 7: Read RxBeaconCount - # - self.step(7) - rx_beacon_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxBeaconCount) - if rx_beacon_count is not None: - matter_asserts.assert_valid_uint32(rx_beacon_count, "RxBeaconCount") - - # - # STEP 8: Read RxBeaconRequestCount - # - self.step(8) - rx_beacon_request_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxBeaconRequestCount) - if rx_beacon_request_count is not None: - matter_asserts.assert_valid_uint32(rx_beacon_request_count, "RxBeaconRequestCount") - - # - # STEP 9: Read RxOtherCount - # - self.step(9) - rx_other_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxOtherCount) - if rx_other_count is not None: - matter_asserts.assert_valid_uint32(rx_other_count, "RxOtherCount") - - # - # STEP 10: Read RxAddressFilteredCount - # - self.step(10) - rx_address_filtered_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxAddressFilteredCount) - if rx_address_filtered_count is not None: - matter_asserts.assert_valid_uint32(rx_address_filtered_count, "RxAddressFilteredCount") - - # - # STEP 11: Read RxDestAddrFilteredCount - # - self.step(11) - rx_dest_addr_filtered_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxDestAddrFilteredCount) - if rx_dest_addr_filtered_count is not None: - matter_asserts.assert_valid_uint32(rx_dest_addr_filtered_count, "RxDestAddrFilteredCount") - - # - # STEP 12: Read RxDuplicatedCount - # - self.step(12) - rx_duplicated_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxDuplicatedCount) - if rx_duplicated_count is not None: - matter_asserts.assert_valid_uint32(rx_duplicated_count, "RxDuplicatedCount") - - # - # STEP 13: Read RxErrNoFrameCount - # - self.step(13) - rx_err_no_frame_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxErrNoFrameCount) - if rx_err_no_frame_count is not None: - matter_asserts.assert_valid_uint32(rx_err_no_frame_count, "RxErrNoFrameCount") - - # - # STEP 14: Read RxErrUnknownNeighborCount - # - self.step(14) - rx_err_unknown_neighbor_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxErrUnknownNeighborCount) - if rx_err_unknown_neighbor_count is not None: - matter_asserts.assert_valid_uint32(rx_err_unknown_neighbor_count, "RxErrUnknownNeighborCount") - - # - # STEP 15: Read RxErrInvalidSrcAddrCount - # - self.step(15) - rx_err_invalid_src_addr_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxErrInvalidSrcAddrCount) - if rx_err_invalid_src_addr_count is not None: - matter_asserts.assert_valid_uint32(rx_err_invalid_src_addr_count, "RxErrInvalidSrcAddrCount") - - # - # STEP 16: Read RxErrSecCount - # - self.step(16) - rx_err_sec_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxErrSecCount) - if rx_err_sec_count is not None: - matter_asserts.assert_valid_uint32(rx_err_sec_count, "RxErrSecCount") - - # - # STEP 17: Read RxErrFcsCount - # - self.step(17) - rx_err_fcs_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxErrFcsCount) - if rx_err_fcs_count is not None: - matter_asserts.assert_valid_uint32(rx_err_fcs_count, "RxErrFcsCount") - - # - # STEP 18: Read RxErrOtherCount - # - self.step(18) - rx_err_other_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.RxErrOtherCount) - if rx_err_other_count is not None: - matter_asserts.assert_valid_uint32(rx_err_other_count, "RxErrOtherCount") - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGTHREAD_2_4.py b/src/python_testing/TC_DGTHREAD_2_4.py deleted file mode 100644 index 4fe9bd2558b6e3..00000000000000 --- a/src/python_testing/TC_DGTHREAD_2_4.py +++ /dev/null @@ -1,97 +0,0 @@ -# -# Copyright (c) 2025 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# 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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from mobly import asserts - - -class TC_THREADND_2_4(MatterBaseTest): - """ - [TC-DGTHREAD-2.4] ResetCounts Command Verification with Server as DUT - - This test case verifies the ResetCounts command and subsequent OverrunCount attribute behavior. - """ - - async def send_reset_counts_command(self, endpoint): - """Sends the ResetCounts command to the DUT.""" - cluster = Clusters.Objects.ThreadNetworkDiagnostics - await self.send_single_cmd(cluster.Commands.ResetCounts(), endpoint=endpoint) - - async def read_thread_diagnostics_attribute_expect_success(self, endpoint, attribute): - """ - Convenience method to read a single ThreadNetworkDiagnostics attribute, - ensuring success. - """ - cluster = Clusters.Objects.ThreadNetworkDiagnostics - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - - def desc_TC_THREADND_2_4(self) -> str: - """Returns a description of this test.""" - return "[TC-DGWIFI-2.4] ResetCounts Command Verification with Server as DUT" - - def pics_TC_THREADND_2_4(self) -> list[str]: - return ["DGWIFI.S", "DGWIFI.S.F.ERRCNT"] - - def steps_TC_THREADND_2_4(self) -> list[TestStep]: - steps = [ - TestStep("1", "Commission DUT to TH (already done)", is_commissioning=True), - TestStep("2", "TH sends ResetCounts Command to DUT"), - TestStep("3", "TH reads OverrunCount attribute from DUT"), - ] - return steps - - @async_test_body - async def test_TC_THREADND_2_4(self): - endpoint = self.get_endpoint(default=0) - - # STEP 1: Commission DUT (already done) - self.step("1") - # Typically, we assume commissioning was performed by harness scripts. - attributes = Clusters.ThreadNetworkDiagnostics.Attributes - - # STEP 2: Send ResetCounts command - self.step("2") - await self.send_reset_counts_command(endpoint) - - # STEP 3: Verify OverrunCount attribute - self.step("3") - overrun_count = await self.read_thread_diagnostics_attribute_expect_success(endpoint, attributes.OverrunCount) - if overrun_count is not None: - # Verify that the OverrunCount is set to Zero - asserts.assert_true(overrun_count == 0, "OverrunCount should be set to Zero") - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGWIFI_2_1.py b/src/python_testing/TC_DGWIFI_2_1.py deleted file mode 100644 index a1dd0b8e1eeaf1..00000000000000 --- a/src/python_testing/TC_DGWIFI_2_1.py +++ /dev/null @@ -1,263 +0,0 @@ -# -# Copyright (c) 2024 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# === BEGIN CI TEST ARGUMENTS === -# test-runner-runs: -# run1: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# 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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.clusters.Types import Nullable, NullValue -from chip.testing import matter_asserts -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from mobly import asserts - - -class TC_DGWIFI_2_1(MatterBaseTest): - """ - [TC-DGWIFI-2.1] Wi-Fi Network Diagnostics Cluster - Attribute Read Verification - - This test case verifies the behavior of the attributes of the Wi-Fi Diagnostics cluster server. - See the test plan steps for details on each attribute read and expected outcome. - """ - - @staticmethod - def is_valid_bssid(bssid) -> bool: - """ - Checks whether the BSSID is valid or None. - - In Matter, the BSSID attribute might return: - - None (if no Wi-Fi is connected or attribute is NULL), - - 6 bytes (raw MAC address), - - Returns True if it is valid, False otherwise. - """ - if isinstance(bssid, bytes): - # For raw bytes, we expect exactly 6 bytes for a MAC address - return len(bssid) == 6 - - return False - - def assert_valid_bssid(self, value, field_name): - """Asserts that the value is a valid BSSID (MAC address), or NullValue.""" - if value is not NullValue: - asserts.assert_true(self.is_valid_bssid(value), - f"{field_name} should be a valid BSSID string (e.g., '00:11:22:33:44:55') or NullValue.") - - async def read_dgwifi_attribute_expect_success(self, endpoint, attribute): - cluster = Clusters.Objects.WiFiNetworkDiagnostics - return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - - def desc_TC_DGWIFI_2_1(self) -> str: - """Returns a description of this test.""" - return "[TC-DGWIFI-2.1] Wi-Fi Network Diagnostics Attributes with Server as DUT" - - def pics_TC_DGWIFI_2_1(self) -> list[str]: - return ["DGWIFI.S"] - - def steps_TC_DGWIFI_2_1(self) -> list[TestStep]: - steps = [ - TestStep(1, "Commission DUT to TH (already done)", is_commissioning=True), - TestStep(2, "Read BSSID attribute"), - TestStep(3, "Read SecurityType attribute"), - TestStep(4, "Read WiFiVersion attribute"), - TestStep(5, "Read ChannelNumber attribute"), - TestStep(6, "Read RSSI attribute"), - TestStep(7, "Read BeaconLostCount attribute"), - TestStep(8, "Read BeaconRxCount attribute"), - TestStep(9, "Read PacketMulticastRxCount attribute"), - TestStep(10, "Read PacketMulticastTxCount attribute"), - TestStep(11, "Read PacketUnicastRxCount attribute"), - TestStep(12, "Read PacketUnicastTxCount attribute"), - TestStep(13, "Read CurrentMaxRate attribute"), - TestStep(14, "Read OverrunCount attribute"), - ] - return steps - - # --------------------------- - # Main Test Routine - # --------------------------- - @async_test_body - async def test_TC_DGWIFI_2_1(self): - endpoint = self.get_endpoint(default=0) - - # - # STEP 1: Commissioning (already done) - # - self.step(1) - # Typically, we assume commissioning was performed by harness scripts. - attributes = Clusters.WiFiNetworkDiagnostics.Attributes - - # - # STEP 2: TH reads Bssid attribute - # - self.step(2) - bssid = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.Bssid) - # If the interface is not configured or not operational, a None might be returned - self.assert_valid_bssid(bssid, "BSSID") - - # - # STEP 3: TH reads SecurityType attribute - # - self.step(3) - security_type = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.SecurityType) - # SecurityType is an enum. If the interface is not operational, it could be NULL. - # If not NULL, we expect an integer in the SecurityType enum range. - # Just do a minimal check here; you can refine or extend based on the spec. - if security_type is not NullValue: - matter_asserts.assert_valid_uint8(security_type, "SecurityType") - - # Check if the security_type is a valid SecurityTypeEnum member - matter_asserts.assert_valid_enum(security_type, "SecurityType", - Clusters.Objects.WiFiNetworkDiagnostics.Enums.SecurityTypeEnum) - - # Additional check that it's not kUnknownEnumValue: - asserts.assert_true( - security_type != Clusters.Objects.WiFiNetworkDiagnostics.Enums.SecurityTypeEnum.kUnknownEnumValue, - f"SecurityType should not be kUnknownEnumValue " - f"({Clusters.Objects.WiFiNetworkDiagnostics.Enums.SecurityTypeEnum.kUnknownEnumValue})" - ) - - # - # STEP 4: TH reads WiFiVersion attribute - # - self.step(4) - wifi_version = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.WiFiVersion) - # WiFiVersion is an enum. If not configured or operational, might be NULL. - if wifi_version is not NullValue: - matter_asserts.assert_valid_uint8(wifi_version, "WiFiVersion") - - # Check if the wifi_version is a valid WiFiVersionEnum member - matter_asserts.assert_valid_enum(wifi_version, "WiFiVersion", - Clusters.Objects.WiFiNetworkDiagnostics.Enums.WiFiVersionEnum) - - # Additional check that it's not kUnknownEnumValue: - asserts.assert_true(wifi_version != Clusters.Objects.WiFiNetworkDiagnostics.Enums.WiFiVersionEnum.kUnknownEnumValue, - f"WiFiVersion should not be kUnknownEnumValue ({Clusters.Objects.WiFiNetworkDiagnostics.Enums.WiFiVersionEnum.kUnknownEnumValue})") - - # - # STEP 5: TH reads ChannelNumber attribute - # - self.step(5) - channel_number = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.ChannelNumber) - # If not operational, might be NULL. Else we expect an unsigned integer channel. - if channel_number is not NullValue: - matter_asserts.assert_valid_uint16(channel_number, "ChannelNumber") - - # - # STEP 6: TH reads RSSI attribute - # - self.step(6) - rssi = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.Rssi) - # RSSI is typically a signed integer (dB). If not operational, might be NULL. - if rssi is not NullValue: - asserts.assert_true(isinstance(rssi, int) and -120 <= rssi <= 0, - "rssi_value is not within valid range.") - - # - # STEP 7: TH reads BeaconLostCount attribute - # - self.step(7) - beacon_lost_count = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.BeaconLostCount) - # Expect unsigned int. Not to be subscribed. - if beacon_lost_count is not None: - asserts.assert_true(isinstance(beacon_lost_count, Nullable), - "BeaconLostCount must be of type 'Nullable' when not None.") - - if beacon_lost_count is not NullValue: - matter_asserts.assert_valid_uint32(beacon_lost_count, "BeaconLostCount") - - # - # STEP 8: TH reads BeaconRxCount attribute - # - self.step(8) - beacon_rx_count = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.BeaconRxCount) - if beacon_rx_count is not None: - if beacon_rx_count is not NullValue: - matter_asserts.assert_valid_uint32(beacon_rx_count, "BeaconRxCount") - - # - # STEP 9: TH reads PacketMulticastRxCount attribute - # - self.step(9) - pkt_multi_rx = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.PacketMulticastRxCount) - if pkt_multi_rx is not None: - if pkt_multi_rx is not NullValue: - matter_asserts.assert_valid_uint32(pkt_multi_rx, "PacketMulticastRxCount") - - # - # STEP 10: TH reads PacketMulticastTxCount attribute - # - self.step(10) - pkt_multi_tx = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.PacketMulticastTxCount) - if pkt_multi_tx is not None: - if pkt_multi_tx is not NullValue: - matter_asserts.assert_valid_uint32(pkt_multi_tx, "PacketMulticastTxCount") - - # - # STEP 11: TH reads PacketUnicastRxCount attribute - # - self.step(11) - pkt_uni_rx = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.PacketUnicastRxCount) - if pkt_uni_rx is not None: - if pkt_uni_rx is not NullValue: - matter_asserts.assert_valid_uint32(pkt_uni_rx, "PacketUnicastRxCount") - - # - # STEP 12: TH reads PacketUnicastTxCount attribute - # - self.step(12) - pkt_uni_tx = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.PacketUnicastTxCount) - if pkt_uni_tx is not None: - if pkt_uni_tx is not NullValue: - matter_asserts.assert_valid_uint32(pkt_uni_tx, "PacketUnicastTxCount") - - # - # STEP 13: TH reads CurrentMaxRate attribute - # - self.step(13) - current_max_rate = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentMaxRate) - # According to the spec, this is bytes per second (uint). - if current_max_rate is not None: - if current_max_rate is not NullValue: - matter_asserts.assert_valid_uint64(current_max_rate, "CurrentMaxRate") - - # - # STEP 14: TH reads OverrunCount attribute - # - self.step(14) - overrun_count = await self.read_dgwifi_attribute_expect_success(endpoint=endpoint, attribute=attributes.OverrunCount) - # This is a uint and may reset to 0 after node reboot. - if overrun_count is not None: - if overrun_count is not NullValue: - matter_asserts.assert_valid_uint64(overrun_count, "OverrunCount") - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGWIFI_2_2.py b/src/python_testing/TC_DGWIFI_2_2.py deleted file mode 100644 index 6cb4c22a90fa8b..00000000000000 --- a/src/python_testing/TC_DGWIFI_2_2.py +++ /dev/null @@ -1,192 +0,0 @@ -# -# Copyright (c) 2024 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# 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: -# app: ${ALL_CLUSTERS_APP} -# app-args: > -# --discriminator 1234 -# --KVS kvs1 -# --trace-to json:${TRACE_APP}.json -# --enable-key 000102030405060708090a0b0c0d0e0f -# script-args: > -# --storage-path admin_storage.json -# --commissioning-method on-network -# --discriminator 1234 -# --passcode 20202021 -# --hex-arg enableKey:000102030405060708090a0b0c0d0e0f -# --trace-to json:${TRACE_TEST_JSON}.json -# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto -# --enable-key 000102030405060708090a0b0c0d0e0f -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.testing.matter_testing import EventChangeCallback, MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from mobly import asserts - - -class TC_DGWIFI_2_2(MatterBaseTest): - - @staticmethod - def is_valid_disconnection_event_data(event_data): - """ - Check for Disconnection event data. Verify 'reasonCode' field is int16u. - """ - return hasattr(event_data, "reasonCode") and (0 <= event_data.reasonCode <= 0xFFFF) - - @staticmethod - def is_valid_association_failure_data(event_data): - # Check for the `associationFailureCause` attribute and if its value - # is within the range of the defined enum (0..3). - cause_valid = ( - hasattr(event_data, "associationFailureCause") - and event_data.associationFailureCause in Clusters.Objects.WiFiNetworkDiagnostics.Enums.AssociationFailureCauseEnum._value2member_map_ - ) - - # Check for the `status` attribute and validate it's within the typical 802.11 range (0..65535). - # In practice, you'd compare it against known 802.11 status codes (Table 9‑50). - status_valid = ( - hasattr(event_data, "status") - and 0 <= event_data.status <= 0xFFFF - ) - - return cause_valid and status_valid - - @staticmethod - def is_valid_connection_status_data(event_data): - # Check if the `connectionStatus` attribute is present - # and if it's within the range of the defined enum. - return ( - hasattr(event_data, "connectionStatus") - and event_data.connectionStatus in Clusters.Objects.WiFiNetworkDiagnostics.Enums.ConnectionStatusEnum._value2member_map_ - ) - - # - # Methods to cause/triggers in your environment - # - async def send_wifi_disconnection_test_event_trigger(self): - # Send test event trigger to programmatically cause a Wi-Fi disconnection in the DUT. - await self.send_test_event_triggers(eventTrigger=0x0036000000000000) - - async def send_wifi_association_failure_test_event_trigger(self): - # Send test event trigger to programmatically cause repeated association failures on the DUT. - await self.send_test_event_triggers(eventTrigger=0x0036000000000001) - - async def send_wifi_reconnection_test_event_trigger(self): - # Send test event trigger to programmatically reconnect the DUT to Wi-Fi. - await self.send_test_event_triggers(eventTrigger=0x0036000000000002) - - # - # Test description & PICS - # - def desc_TC_DGWIFI_2_2(self) -> str: - """Returns a description of this test""" - return "[TC-DGWIFI-2.2] Wi-Fi Diagnostics Event Tests (Server as DUT)" - - def pics_TC_DGWIFI_2_2(self) -> list[str]: - return ["DGWIFI.S"] - - def steps_TC_DGWIFI_2_2(self) -> list[TestStep]: - steps = [ - TestStep(1, "Commissioning (already done)", is_commissioning=True), - TestStep(2, "Trigger Wi-Fi disconnection -> verify Disconnection event"), - TestStep(3, "Trigger repeated association failures -> verify AssociationFailure event"), - TestStep(4, "Reconnect Wi-Fi -> verify ConnectionStatus event"), - ] - return steps - - # --------------------------- - # Main Test Routine - # --------------------------- - @async_test_body - async def test_TC_DGWIFI_2_2(self): - endpoint = self.get_endpoint(default=0) - - # - # STEP 1: Commission DUT (already done) - # - self.step(1) - - # - # Create and start an EventChangeCallback to subscribe for events - # - events_callback = EventChangeCallback(Clusters.WiFiNetworkDiagnostics) - await events_callback.start( - self.default_controller, # The controller - self.dut_node_id, # DUT's node id - endpoint # The endpoint on which we expect Wi-Fi events - ) - - # - # STEP 2: Cause a Wi-Fi Disconnection -> wait for Disconnection event - # - self.step(2) - await self.send_wifi_disconnection_test_event_trigger() - - # Wait (block) for the Disconnection event to arrive - event_data = events_callback.wait_for_event_report( - Clusters.WiFiNetworkDiagnostics.Events.Disconnection - ) - - # Validate the Disconnection event fields - asserts.assert_true( - self.is_valid_disconnection_event_data(event_data), - f"Invalid Disconnection event data: {event_data}" - ) - - # - # STEP 3: Cause repeated association failures -> wait for AssociationFailure event - # - self.step(3) - await self.send_wifi_association_failure_test_event_trigger() - - event_data = events_callback.wait_for_event_report( - Clusters.WiFiNetworkDiagnostics.Events.AssociationFailure - ) - - # Validate the AssociationFailure event fields - asserts.assert_true( - self.is_valid_association_failure_data(event_data), - f"Invalid AssociationFailure event data: {event_data}" - ) - - # - # STEP 4: Reconnect Wi-Fi -> wait for ConnectionStatus event - # - self.step(4) - await self.send_wifi_reconnection_test_event_trigger() - - event_data = events_callback.wait_for_event_report( - Clusters.WiFiNetworkDiagnostics.Events.ConnectionStatus - ) - - # Validate the ConnectionStatus event fields - asserts.assert_true( - self.is_valid_connection_status_data(event_data), - f"Invalid ConnectionStatus event data: {event_data}" - ) - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_DGWIFI_2_3.py b/src/python_testing/TC_DGWIFI_2_3.py deleted file mode 100644 index 06502e158ca9bd..00000000000000 --- a/src/python_testing/TC_DGWIFI_2_3.py +++ /dev/null @@ -1,156 +0,0 @@ -# -# Copyright (c) 2024 Project CHIP Authors -# All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# === BEGIN CI TEST ARGUMENTS === -# test-runner-runs: -# run1: -# app: ${ALL_CLUSTERS_APP} -# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json -# 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 -# factory-reset: true -# quiet: true -# === END CI TEST ARGUMENTS === -# - -import chip.clusters as Clusters -from chip.clusters.Types import NullValue -from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main -from mobly import asserts - - -class TC_DGWIFI_2_3(MatterBaseTest): - """ - [TC-DGWIFI-2.3] Wi-Fi Network Diagnostics Cluster - Command Verification - - This test case verifies the ResetCounts command and subsequent behavior. - """ - - @staticmethod - def is_valid_uint32(value): - """Validates a uint32 value.""" - return isinstance(value, int) and 0 <= value <= 0xFFFFFFFF - - async def send_reset_counts_command(self, endpoint): - """Sends the ResetCounts command to the DUT.""" - cluster = Clusters.Objects.WiFiNetworkDiagnostics - await self.send_single_cmd(cluster.Commands.ResetCounts(), endpoint=endpoint) - - async def read_attribute_and_validate(self, endpoint, attribute, validation_func, field_name): - """Reads an attribute and validates it using the provided function.""" - value = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=Clusters.Objects.WiFiNetworkDiagnostics, attribute=attribute) - if value is None: - return - if value == NullValue: - return - asserts.assert_true(validation_func(value), f"{field_name} has an invalid value: {value}") - - def desc_TC_DGWIFI_2_3(self) -> str: - """Returns a description of this test.""" - return "[TC-DGWIFI-2.3] Wi-Fi Diagnostics Command Verification with Server as DUT" - - def pics_TC_DGWIFI_2_3(self) -> list[str]: - return ["DGWIFI.S"] - - def steps_TC_DGWIFI_2_3(self) -> list[TestStep]: - steps = [ - TestStep("1", "Commission DUT to TH (already done)", is_commissioning=True), - TestStep("2", "Send ResetCounts command to DUT"), - TestStep("2a", "Verify BeaconLostCount attribute after reset"), - TestStep("2b", "Verify BeaconRxCount attribute after reset"), - TestStep("2c", "Verify PacketMulticastRxCount attribute after reset"), - TestStep("2d", "Verify PacketMulticastTxCount attribute after reset"), - TestStep("2e", "Verify PacketUnicastRxCount attribute after reset"), - TestStep("2f", "Verify PacketUnicastTxCount attribute after reset"), - ] - return steps - - @async_test_body - async def test_TC_DGWIFI_2_3(self): - endpoint = self.get_endpoint(default=0) - - # STEP 1: Commission DUT (already done) - self.step("1") - # Typically, we assume commissioning was performed by harness scripts. - attributes = Clusters.WiFiNetworkDiagnostics.Attributes - - # STEP 2: Send ResetCounts command - self.step("2") - await self.send_reset_counts_command(endpoint) - - # STEP 2a: Verify BeaconLostCount attribute - self.step("2a") - await self.read_attribute_and_validate( - endpoint, - attributes.BeaconLostCount, - self.is_valid_uint32, - "BeaconLostCount" - ) - - # STEP 2b: Verify BeaconRxCount attribute - self.step("2b") - await self.read_attribute_and_validate( - endpoint, - attributes.BeaconRxCount, - self.is_valid_uint32, - "BeaconRxCount" - ) - - # STEP 2c: Verify PacketMulticastRxCount attribute - self.step("2c") - await self.read_attribute_and_validate( - endpoint, - attributes.PacketMulticastRxCount, - self.is_valid_uint32, - "PacketMulticastRxCount" - ) - - # STEP 2d: Verify PacketMulticastTxCount attribute - self.step("2d") - await self.read_attribute_and_validate( - endpoint, - attributes.PacketMulticastTxCount, - self.is_valid_uint32, - "PacketMulticastTxCount" - ) - - # STEP 2e: Verify PacketUnicastRxCount attribute - self.step("2e") - await self.read_attribute_and_validate( - endpoint, - attributes.PacketUnicastRxCount, - self.is_valid_uint32, - "PacketUnicastRxCount" - ) - - # STEP 2f: Verify PacketUnicastTxCount attribute - self.step("2f") - await self.read_attribute_and_validate( - endpoint, - attributes.PacketUnicastTxCount, - self.is_valid_uint32, - "PacketUnicastTxCount" - ) - - -if __name__ == "__main__": - default_matter_test_main() diff --git a/src/python_testing/TC_SC_4_3.py b/src/python_testing/TC_SC_4_3.py index 42082e875fcf29..a4265b3d611edf 100644 --- a/src/python_testing/TC_SC_4_3.py +++ b/src/python_testing/TC_SC_4_3.py @@ -57,7 +57,7 @@ class TC_SC_4_3(MatterBaseTest): def steps_TC_SC_4_3(self): - return [TestStep(1, "DUT is commissioned on the same fabric as TH."), + return [TestStep(1, "DUT is commissioned on the same fabric as TH.", is_commissioning=True), TestStep(2, "TH reads ServerList attribute from the Descriptor cluster on EP0. ", "If the ICD Management cluster ID (70,0x46) is present in the list, set supports_icd to true, otherwise set supports_icd to false."), TestStep(3, diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index cb2df9d66a87e3..e272d2c0a592cd 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -42,7 +42,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.testing.matter_testing import (MatterBaseTest, default_matter_test_main, has_attribute, has_cluster, - run_if_endpoint_matches, utc_time_in_matter_epoch) + run_if_endpoint_matches) +from chip.testing.timeoperations import utc_time_in_matter_epoch from mobly import asserts diff --git a/src/python_testing/TC_TIMESYNC_2_10.py b/src/python_testing/TC_TIMESYNC_2_10.py index 99ca9f3ac0194b..ee815b33a57fed 100644 --- a/src/python_testing/TC_TIMESYNC_2_10.py +++ b/src/python_testing/TC_TIMESYNC_2_10.py @@ -43,17 +43,12 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import (MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main, - utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main +from chip.testing.timeoperations import get_wait_seconds_from_set_time, utc_time_in_matter_epoch from chip.tlv import uint from mobly import asserts -def get_wait_seconds_from_set_time(set_time_matter_us: int, wait_seconds: int): - seconds_passed = int((utc_time_in_matter_epoch() - set_time_matter_us)/1000000) - return wait_seconds - seconds_passed - - class TC_TIMESYNC_2_10(MatterBaseTest): async def send_set_time_zone_cmd(self, tz: typing.List[Clusters.Objects.TimeSynchronization.Structs.TimeZoneStruct]) -> Clusters.Objects.TimeSynchronization.Commands.SetTimeZoneResponse: ret = await self.send_single_cmd(cmd=Clusters.Objects.TimeSynchronization.Commands.SetTimeZone(timeZone=tz), endpoint=self.endpoint) diff --git a/src/python_testing/TC_TIMESYNC_2_11.py b/src/python_testing/TC_TIMESYNC_2_11.py index 0865bc87f4d1cc..e0b8f4dc2eabed 100644 --- a/src/python_testing/TC_TIMESYNC_2_11.py +++ b/src/python_testing/TC_TIMESYNC_2_11.py @@ -43,8 +43,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import (MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main, - get_wait_seconds_from_set_time, type_matches, utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main, type_matches +from chip.testing.timeoperations import get_wait_seconds_from_set_time, utc_time_in_matter_epoch from chip.tlv import uint from mobly import asserts diff --git a/src/python_testing/TC_TIMESYNC_2_12.py b/src/python_testing/TC_TIMESYNC_2_12.py index 7677dcf184c0b2..7a1ff03e72cb3f 100644 --- a/src/python_testing/TC_TIMESYNC_2_12.py +++ b/src/python_testing/TC_TIMESYNC_2_12.py @@ -43,8 +43,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import (MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main, - get_wait_seconds_from_set_time, type_matches, utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main, type_matches +from chip.testing.timeoperations import get_wait_seconds_from_set_time, utc_time_in_matter_epoch from chip.tlv import uint from mobly import asserts diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index 74f935aac9714e..2053bf0e24e98c 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -40,8 +40,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, - utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main +from chip.testing.timeoperations import compare_time, utc_time_in_matter_epoch from mobly import asserts diff --git a/src/python_testing/TC_TIMESYNC_2_4.py b/src/python_testing/TC_TIMESYNC_2_4.py index 76fe9074bec56f..a3b6bac020d54e 100644 --- a/src/python_testing/TC_TIMESYNC_2_4.py +++ b/src/python_testing/TC_TIMESYNC_2_4.py @@ -40,8 +40,8 @@ import chip.clusters as Clusters from chip.interaction_model import InteractionModelError, Status -from chip.testing.matter_testing import (MatterBaseTest, async_test_body, default_matter_test_main, type_matches, - utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from chip.testing.timeoperations import utc_time_in_matter_epoch from mobly import asserts diff --git a/src/python_testing/TC_TIMESYNC_2_5.py b/src/python_testing/TC_TIMESYNC_2_5.py index f363f03ba688d8..9705511236d781 100644 --- a/src/python_testing/TC_TIMESYNC_2_5.py +++ b/src/python_testing/TC_TIMESYNC_2_5.py @@ -40,7 +40,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, utc_time_in_matter_epoch +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main +from chip.testing.timeoperations import utc_time_in_matter_epoch from mobly import asserts diff --git a/src/python_testing/TC_TIMESYNC_2_7.py b/src/python_testing/TC_TIMESYNC_2_7.py index 1c6cea2023d4de..a164cd64809f05 100644 --- a/src/python_testing/TC_TIMESYNC_2_7.py +++ b/src/python_testing/TC_TIMESYNC_2_7.py @@ -42,8 +42,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, type_matches, - utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from chip.testing.timeoperations import compare_time, utc_time_in_matter_epoch from chip.tlv import uint from mobly import asserts diff --git a/src/python_testing/TC_TIMESYNC_2_8.py b/src/python_testing/TC_TIMESYNC_2_8.py index 82a77c4c886d17..1a227b579547ef 100644 --- a/src/python_testing/TC_TIMESYNC_2_8.py +++ b/src/python_testing/TC_TIMESYNC_2_8.py @@ -42,8 +42,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, type_matches, - utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from chip.testing.timeoperations import compare_time, utc_time_in_matter_epoch from chip.tlv import uint from mobly import asserts diff --git a/src/python_testing/TC_TIMESYNC_2_9.py b/src/python_testing/TC_TIMESYNC_2_9.py index 4ce83f81ddbd4b..703e3b9d58e664 100644 --- a/src/python_testing/TC_TIMESYNC_2_9.py +++ b/src/python_testing/TC_TIMESYNC_2_9.py @@ -41,8 +41,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError -from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, type_matches, - utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, type_matches +from chip.testing.timeoperations import compare_time, utc_time_in_matter_epoch from chip.tlv import uint from mobly import asserts diff --git a/src/python_testing/TC_TSTAT_2_2.py b/src/python_testing/TC_TSTAT_2_2.py new file mode 100644 index 00000000000000..f4e1dfbc2b70d3 --- /dev/null +++ b/src/python_testing/TC_TSTAT_2_2.py @@ -0,0 +1,796 @@ +# +# 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: +# app: ${ALL_CLUSTERS_APP} +# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# 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 +# factory-reset: true +# quiet: true +# === END CI TEST ARGUMENTS === + +import logging + +import chip.clusters as Clusters +from chip.interaction_model import Status +from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from mobly import asserts + +logger = logging.getLogger(__name__) + +cluster = Clusters.Thermostat + + +class TC_TSTAT_2_2(MatterBaseTest): + + def desc_TC_TSTAT_2_2(self) -> str: + """Returns a description of this test""" + return "42.2.2. [TC-TSTAT-2.2] Setpoint Test Cases with server as DUT" + + def pics_TC_TSTAT_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 [self.check_pics("TSTAT.S")] + + def steps_TC_TSTAT_2_2(self) -> list[TestStep]: + steps = [ + TestStep("1", "Commissioning, already done", is_commissioning=True), + TestStep("2a", "Test Harness Client reads attribute OccupiedCoolingSetpoint from the DUT"), + TestStep("2b", "Test Harness Client then attempts Writes OccupiedCoolingSetpoint to a value below the MinCoolSetpointLimit"), + TestStep("2c", "Test Harness Writes the limit of MaxCoolSetpointLimit to OccupiedCoolingSetpoint attribute"), + TestStep("3a", "Test Harness Reads OccupiedHeatingSetpoint attribute from Server DUT and verifies that the value is within range"), + TestStep("3b", "Test Harness Writes OccupiedHeatingSetpoint to value below the MinHeatSetpointLimit"), + TestStep("3c", "Test Harness Writes the limit of MaxHeatSetpointLimit to OccupiedHeatingSetpoint attribute"), + TestStep("4a", "Test Harness Reads UnoccupiedCoolingSetpoint attribute from Server DUT and verifies that the value is within range"), + TestStep("4b", "Test Harness Writes UnoccupiedCoolingSetpoint to value below the MinCoolSetpointLimit"), + TestStep("4c", "Test Harness Writes the limit of MaxCoolSetpointLimit to UnoccupiedCoolingSetpoint attribute"), + TestStep("5a", "Test Harness Reads UnoccupiedHeatingSetpoint attribute from Server DUT and verifies that the value is within range"), + TestStep("5b", "Test Harness Writes UnoccupiedHeatingSetpoint to value below the MinHeatSetpointLimit"), + TestStep("5c", "Test Harness Writes the limit of MaxHeatSetpointLimit to UnoccupiedHeatingSetpoint attribute"), + TestStep("6a", "Test Harness Reads MinHeatSetpointLimit attribute from Server DUT and verifies that the value is within range"), + TestStep("6b", "Test Harness Writes a value back that is different but violates the deadband"), + TestStep("6c", "Test Harness Writes the limit of MaxHeatSetpointLimit to MinHeatSetpointLimit attribute"), + TestStep("7a", "Test Harness Reads MaxHeatSetpointLimit attribute from Server DUT and verifies that the value is within range"), + TestStep("7b", "Test Harness Writes the limit of AbsMinHeatSetpointLimit to MinHeatSetpointLimit attribute"), + TestStep("7c", "Test Harness Writes the limit of AbsMaxHeatSetpointLimit to MaxHeatSetpointLimit attribute"), + TestStep("8a", "Test Harness Reads MinCoolSetpointLimit attribute from Server DUT and verifies that the value is within range"), + TestStep("8b", "Test Harness Writes MinCoolSetpointLimit to value below the AbsMinCoolSetpointLimit "), + TestStep("8c", "Test Harness Writes the limit of MaxCoolSetpointLimit to MinCoolSetpointLimit attribute"), + TestStep("9a", "Test Harness Reads MaxCoolSetpointLimit attribute from Server DUT and verifies that the value is within range"), + TestStep("9b", "Test Harness Writes MaxCoolSetpointLimit to value below the AbsMinCoolSetpointLimit "), + TestStep("9c", "Test Harness Writes the limit of AbsMaxCoolSetpointLimit to MaxCoolSetpointLimit attribute"), + TestStep("10a", "Test Harness Writes (sets back) default value of MinHeatSetpointLimit"), + TestStep("10b", "Test Harness Writes (sets back) default value of MinCoolSetpointLimit"), + TestStep("11a", "Test Harness Reads MinSetpointDeadBand attribute from Server DUT and verifies that the value is within range"), + TestStep("11b", "Test Harness Writes the value below MinSetpointDeadBand"), + TestStep("11c", "Test Harness Writes the min limit of MinSetpointDeadBand"), + TestStep("12", "Test Harness Reads ControlSequenceOfOperation from Server DUT, if TSTAT.S.F01 is true"), + TestStep("13", "Sets OccupiedCoolingSetpoint to default value"), + TestStep("14", "Sets OccupiedHeatingSetpoint to default value"), + TestStep("15", "Test Harness Sends SetpointRaise Command Cool Only"), + TestStep("16", "Sets OccupiedCoolingSetpoint to default value"), + TestStep("17", "Sets OccupiedCoolingSetpoint to default value"), + TestStep("18", "Sets OccupiedCoolingSetpoint to default value"), + ] + + return steps + + @ async_test_body + async def test_TC_TSTAT_2_2(self): + endpoint = self.get_endpoint() + + # Default values for various optional attributes + AbsMaxCoolSetpointLimitValue = 3200 + AbsMaxHeatSetpointLimitValue = 3000 + AbsMinCoolSetpointLimitValue = 1600 + AbsMinHeatSetpointLimitValue = 700 + MinSetpointDeadBandValue = 250 + MaxCoolSetpointLimitValue = AbsMaxCoolSetpointLimitValue + MaxHeatSetpointLimitValue = AbsMaxHeatSetpointLimitValue + MinCoolSetpointLimitValue = AbsMinCoolSetpointLimitValue + MinHeatSetpointLimitValue = AbsMinHeatSetpointLimitValue + + # Supports a System Mode of Auto + hasAutoModeFeature = self.check_pics("TSTAT.S.F05") + # Thermostat is capable of managing a cooling device + hasCoolingFeature = self.check_pics("TSTAT.S.F01") + # Thermostat is capable of managing a heating device + hasHeatingFeature = self.check_pics("TSTAT.S.F00") + # Supports Occupied and Unoccupied setpoints + hasOccupancyFeature = self.check_pics("TSTAT.S.F02") + + # Does the device implement the AbsMaxCoolSetpointLimit attribute? + hasAbsMaxCoolSetpointLimitAttribute = self.check_pics("TSTAT.S.A0006") + # Does the device implement the AbsMaxHeatSetpointLimit attribute? + hasAbsMaxHeatSetpointLimitAttribute = self.check_pics("TSTAT.S.A0004") + # Does the device implement the AbsMinCoolSetpointLimit attribute? + hasAbsMinCoolSetpointLimitAttribute = self.check_pics("TSTAT.S.A0005") + # Does the device implement the AbsMinHeatSetpointLimit attribute? + hasAbsMinHeatSetpointLimitAttribute = self.check_pics("TSTAT.S.A0003") + # Does the device implement the MaxCoolSetpointLimit attribute? + hasMaxCoolSetpointLimitAttribute = self.check_pics("TSTAT.S.A0018") + # Does the device implement the MaxHeatSetpointLimit attribute? + hasMaxHeatSetpointLimitAttribute = self.check_pics("TSTAT.S.A0016") + # Does the device implement the MinCoolSetpointLimit attribute? + hasMinCoolSetpointLimitAttribute = self.check_pics("TSTAT.S.A0017") + # Does the device implement the MinHeatSetpointLimit attribute? + hasMinHeatSetpointLimitAttribute = self.check_pics("TSTAT.S.A0015") + # Does the device implement the MinSetpointDeadBand attribute? + hasMinSetpointDeadBandAttribute = self.check_pics("TSTAT.S.A0019") + # Does the device implement the OccupiedCoolingSetpoint attribute? + hasOccupiedCoolingSetpointAttribute = self.check_pics("TSTAT.S.A0011") + # Does the device implement the OccupiedHeatingSetpoint attribute? + hasOccupiedHeatingSetpointAttribute = self.check_pics("TSTAT.S.A0012") + # Does the device implement the UnoccupiedCoolingSetpoint attribute? + hasUnoccupiedCoolingSetpointAttribute = self.check_pics("TSTAT.S.A0013") + # Does the device implement the UnoccupiedHeatingSetpoint attribute? + hasUnoccupiedHeatingSetpointAttribute = self.check_pics("TSTAT.S.A0014") + + self.step("1") + + OccupiedHeatingSetpointValue = None + OccupiedCoolingSetpointValue = None + UnoccupiedHeatingSetpointValue = None + UnoccupiedCoolingSetpointValue = None + + ControlSequenceOfOperation = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + + if self.pics_guard(hasMinCoolSetpointLimitAttribute): + # Saving value for comparision in step 2a read MinCoolSetpointLimit + MinCoolSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinCoolSetpointLimit) + + if self.pics_guard(hasMaxCoolSetpointLimitAttribute): + # Saving value for comparision in step 2a read MaxCoolSetpointLimit + MaxCoolSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxCoolSetpointLimit) + + if self.pics_guard(hasMinSetpointDeadBandAttribute): + # Saving value for comparision in step 2c read attribute MinSetpointDeadBand + MinSetpointDeadBandValue = (await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinSetpointDeadBand)) * 10 + + if self.pics_guard(hasMinHeatSetpointLimitAttribute): + # Saving value for comparision in step 3a read MinHeatSetpointLimit + MinHeatSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinHeatSetpointLimit) + + if self.pics_guard(hasMaxHeatSetpointLimitAttribute): + # Saving value for comparision in step 3a read MaxHeatSetpointLimit + MaxHeatSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxHeatSetpointLimit) + + if self.pics_guard(hasOccupiedHeatingSetpointAttribute): + # Saving value for comparision in step3c read attribute OccupiedHeatingSetpoint + OccupiedHeatingSetpointValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + + if self.pics_guard(hasOccupiedCoolingSetpointAttribute): + # Saving value for comparision in step3c read attribute OccupiedCoolingSetpoint + OccupiedCoolingSetpointValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + + if self.pics_guard(hasUnoccupiedHeatingSetpointAttribute): + # Saving value for comparision in step3c read attribute OccupiedHeatingSetpoint + UnoccupiedHeatingSetpointValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedHeatingSetpoint) + + if self.pics_guard(hasUnoccupiedCoolingSetpointAttribute): + # Saving value for comparision in step3c read attribute OccupiedCoolingSetpoint + UnoccupiedCoolingSetpointValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedCoolingSetpoint) + + if self.pics_guard(hasAbsMinHeatSetpointLimitAttribute): + # Saving value for comparision in step 6a read attribute AbsMinHeatSetpointLimit + AbsMinHeatSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.AbsMinHeatSetpointLimit) + + if self.pics_guard(hasAbsMaxHeatSetpointLimitAttribute): + # Saving value for comparision in step 7a read attribute AbsMaxHeatSetpointLimit + AbsMaxHeatSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.AbsMaxHeatSetpointLimit) + + if self.pics_guard(hasAbsMinCoolSetpointLimitAttribute): + # Saving value for comparision in step 8a read attribute AbsMinCoolSetpointLimit + AbsMinCoolSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.AbsMinCoolSetpointLimit) + + if self.pics_guard(hasAbsMaxCoolSetpointLimitAttribute): + # Saving value for comparision in step9a read attribute AbsMaxCoolSetpointLimit + AbsMaxCoolSetpointLimitValue = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.AbsMaxCoolSetpointLimit) + + self.step("2a") + + if self.pics_guard(hasCoolingFeature): + # Test Harness Client reads attribute OccupiedCoolingSetpoint from the DUT + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_greater_equal(val, MinCoolSetpointLimitValue) + asserts.assert_less_equal(val, MaxCoolSetpointLimitValue) + + # Test Harness Client then attempts Writes a value back that is different but valid for OccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MinCoolSetpointLimitValue + ((MaxCoolSetpointLimitValue - MinCoolSetpointLimitValue) // 2)), endpoint_id=endpoint) + + # Test Harness Client reads it back again to confirm the successful write of OccupiedCoolingSetpoint attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, MinCoolSetpointLimitValue + ((MaxCoolSetpointLimitValue - MinCoolSetpointLimitValue) // 2)) + + self.step("2b") + + if self.pics_guard(hasCoolingFeature): + # Test Harness Client then attempts Writes OccupiedCoolingSetpoint to value below the MinCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MinCoolSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes OccupiedCoolingSetpoint to value above the MaxCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MaxCoolSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("2c") + + if self.pics_guard(hasCoolingFeature): + # Test Harness Writes the limit of MaxCoolSetpointLimit to OccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MaxCoolSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = Max(MinCoolSetpointLimit, (OccupiedHeatingSetpoint + MinSetpointDeadBand)) to OccupiedCoolingSetpoint attribute when Auto is enabled + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(max(MinCoolSetpointLimitValue, (OccupiedHeatingSetpointValue + (MinSetpointDeadBandValue)))), endpoint_id=endpoint) + + else: + # Test Harness Writes the limit of MinCoolSetpointLimit to OccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(MinCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("3a") + + if self.pics_guard(hasHeatingFeature): + # Test Harness Reads OccupiedHeatingSetpoint attribute from Server DUT and verifies that the value is within range + # Using saved values when optional attributes are available + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_greater_equal(val, MinHeatSetpointLimitValue) + asserts.assert_less_equal(val, MaxHeatSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for OccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MinHeatSetpointLimitValue + ((MaxHeatSetpointLimitValue - MinHeatSetpointLimitValue) // 2)), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of OccupiedHeatingSetpoint attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, MinHeatSetpointLimitValue + ((MaxHeatSetpointLimitValue - MinHeatSetpointLimitValue) // 2)) + + self.step("3b") + + if self.pics_guard(hasHeatingFeature): + # Test Harness Writes OccupiedHeatingSetpoint to value below the MinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes OccupiedHeatingSetpoint to value above the MaxHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MaxHeatSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("3c") + + if self.pics_guard(hasHeatingFeature): + # Test Harness Writes the limit of MinHeatSetpointLimit to OccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MinHeatSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes the limit of MaxHeatSetpointLimit to OccupiedHeatingSetpoint attribute + upper_limit = min(MaxHeatSetpointLimitValue, (OccupiedCoolingSetpointValue - MinSetpointDeadBandValue)) + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(upper_limit), endpoint_id=endpoint) + + else: + # Test Harness Writes the limit of MaxHeatSetpointLimit to OccupiedHeatingSetpoint attribute If TSTAT.S.F05 is true + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(MaxHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("4a") + + if self.pics_guard(hasOccupancyFeature and hasCoolingFeature): + # Test Harness Reads UnoccupiedCoolingSetpoint attribute from Server DUT and verifies that the value is within range + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedCoolingSetpoint) + asserts.assert_greater_equal(val, MinCoolSetpointLimitValue) + asserts.assert_less_equal(val, MaxCoolSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for UnoccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MinCoolSetpointLimitValue + ((MaxCoolSetpointLimitValue - MinCoolSetpointLimitValue) // 2)), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of UnoccupiedCoolingSetpoint attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedCoolingSetpoint) + asserts.assert_equal(val, MinCoolSetpointLimitValue + ((MaxCoolSetpointLimitValue - MinCoolSetpointLimitValue) // 2)) + + self.step("4b") + + if self.pics_guard(hasOccupancyFeature and hasCoolingFeature): + # Test Harness Writes UnoccupiedCoolingSetpoint to value below the MinCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MinCoolSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes UnoccupiedCoolingSetpoint to value above the MaxCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MaxCoolSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("4c") + + if self.pics_guard(hasOccupancyFeature and hasCoolingFeature): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = Max(MinCoolSetpointLimit, (UnoccupiedCoolingSetpoint + MinSetpointDeadBand)) to UnoccupiedCoolingSetpoint attribute + LowerLimit = max(MinCoolSetpointLimitValue, (UnoccupiedCoolingSetpointValue + MinSetpointDeadBandValue)) + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(LowerLimit), endpoint_id=endpoint) + + else: + # Test Harness Writes the limit of MinCoolSetpointLimit to UnoccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MinCoolSetpointLimitValue), endpoint_id=endpoint) + # Test Harness Writes the limit of MaxCoolSetpointLimit to UnoccupiedCoolingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(MaxCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("5a") + + if self.pics_guard(hasOccupancyFeature and hasHeatingFeature): + # Test Harness Reads UnoccupiedHeatingSetpoint attribute from Server DUT and verifies that the value is within range + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedHeatingSetpoint) + asserts.assert_greater_equal(val, MinHeatSetpointLimitValue) + asserts.assert_less_equal(val, MaxHeatSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for UnoccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MinHeatSetpointLimitValue + ((MaxHeatSetpointLimitValue - MinHeatSetpointLimitValue) // 2)), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of UnoccupiedHeatingSetpoint attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.UnoccupiedHeatingSetpoint) + asserts.assert_equal(val, MinHeatSetpointLimitValue + ((MaxHeatSetpointLimitValue - MinHeatSetpointLimitValue) // 2)) + + self.step("5b") + + if self.pics_guard(hasOccupancyFeature and hasHeatingFeature): + # Test Harness Writes UnoccupiedHeatingSetpoint to value below the MinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes UnoccupiedHeatingSetpoint to value above the MaxHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MaxHeatSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("5c") + + if self.pics_guard(hasOccupancyFeature and hasHeatingFeature): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes the limit of MaxHeatSetpointLimit to UnoccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(max(MaxHeatSetpointLimitValue, (UnoccupiedCoolingSetpointValue + MinSetpointDeadBandValue))), endpoint_id=endpoint) + + else: + # Test Harness Writes the limit of MaxHeatSetpointLimit to UnoccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MaxHeatSetpointLimitValue), endpoint_id=endpoint) + + # Test Harness Writes the limit of MinHeatSetpointLimit to UnoccupiedHeatingSetpoint attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(MinHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("6a") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + # Test Harness Reads MinHeatSetpointLimit attribute from Server DUT and verifies that the value is within range + # Using saved values when optional attributes are available + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinHeatSetpointLimit) + asserts.assert_greater_equal(val, AbsMinHeatSetpointLimitValue) + asserts.assert_less_equal(val, MaxHeatSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for MinHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMinHeatSetpointLimitValue + 1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MinHeatSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinHeatSetpointLimit) + asserts.assert_equal(val, AbsMinHeatSetpointLimitValue + 1) + + self.step("6b") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes a value back that is different but violates the deadband + existingCoolMinSetpoint = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinCoolSetpointLimit) + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit((existingCoolMinSetpoint - MinSetpointDeadBandValue) + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MinHeatSetpointLimit to value below the AbsMinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MinHeatSetpointLimit to value above the AbsMaxHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMaxHeatSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("6c") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = Min(MaxHeatSetpointLimit, (MinCoolSetpointLimit - MinSetpointDeadBand)) to MinHeatSetpointLimit attribute when Auto is enabled + # UpperLimit = Min(MaxHeatSetpointLimit,(MinCoolSetpointLimit - MinSetpointDeadBand)) not possible in YAML + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(min(MaxHeatSetpointLimitValue, (MinCoolSetpointLimitValue - MinSetpointDeadBandValue))), endpoint_id=endpoint) + else: + # Test Harness Writes the limit of MaxHeatSetpointLimit to MinHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(MaxHeatSetpointLimitValue), endpoint_id=endpoint) + + # Test Harness Writes the limit of AbsMinHeatSetpointLimit to MinHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMinHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("7a") + + # Test Harness Reads MaxHeatSetpointLimit attribute from Server DUT and verifies that the value is within range + if self.pics_guard(hasHeatingFeature and hasMaxHeatSetpointLimitAttribute): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxHeatSetpointLimit) + asserts.assert_greater_equal(val, MinHeatSetpointLimitValue) + asserts.assert_less_equal(val, AbsMaxHeatSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for MaxHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MinHeatSetpointLimitValue + 1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MaxHeatSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxHeatSetpointLimit) + asserts.assert_equal(val, MinHeatSetpointLimitValue + 1) + + self.step("7b") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes the limit of AbsMaxHeatSetpointLimit to MinHeatSetpointLimit attribute + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMaxHeatSetpointLimitValue), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + else: + # Test Harness Writes the limit of AbsMinHeatSetpointLimit to MinHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(AbsMinHeatSetpointLimitValue), endpoint_id=endpoint) + + # Test Harness Writes a value back that is different but valid for MaxHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(AbsMaxHeatSetpointLimitValue-1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MaxHeatSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxHeatSetpointLimit) + asserts.assert_equal(val, AbsMaxHeatSetpointLimitValue-1) + + if self.pics_guard(hasHeatingFeature and hasMaxHeatSetpointLimitAttribute): + # Test Harness Writes MaxHeatSetpointLimit to value below the AbsMinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(AbsMinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MaxHeatSetpointLimit to value below the MinHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MinHeatSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MaxHeatSetpointLimit to value above the AbsMaxHeatSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(AbsMaxHeatSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("7c") + + if self.pics_guard(hasHeatingFeature and hasMaxHeatSetpointLimitAttribute): + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) UpperLimit = Min(AbsMaxHeatSetpointLimit, (MaxCoolSetpointLimit - MinSetpointDeadBand)) to MaxHeatSetpointLimit attribute + # UpperLimit = Min(AbsMaxHeatSetpointLimit,(MaxCoolSetpointLimit - MinSetpointDeadBand)) + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(min(AbsMaxHeatSetpointLimitValue, MaxCoolSetpointLimitValue - MinSetpointDeadBandValue)), endpoint_id=endpoint) + else: + # Test Harness Writes the limit of AbsMaxHeatSetpointLimit to MaxHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(AbsMaxHeatSetpointLimitValue), endpoint_id=endpoint) + + # Test Harness Writes the limit of MinHeatSetpointLimit to MaxHeatSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MinHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("8a") + + if self.pics_guard(hasCoolingFeature and hasMinCoolSetpointLimitAttribute): + # Test Harness Reads MinCoolSetpointLimit attribute from Server DUT and verifies that the value is within range + # Using saved values when optional attributes are available + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinCoolSetpointLimit) + asserts.assert_greater_equal(val, AbsMinCoolSetpointLimitValue) + asserts.assert_less_equal(val, MaxCoolSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for MinCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(AbsMinCoolSetpointLimitValue + 1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MinCoolSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinCoolSetpointLimit) + asserts.assert_equal(val, AbsMinCoolSetpointLimitValue + 1) + + self.step("8b") + + if self.pics_guard(hasCoolingFeature and hasMinCoolSetpointLimitAttribute): + # Test Harness Writes MinCoolSetpointLimit to value below the AbsMinCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(AbsMinCoolSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MinCoolSetpointLimit to value above the MaxCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(MaxCoolSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("8c") + + if self.pics_guard(hasCoolingFeature and hasMinCoolSetpointLimitAttribute): + # Test Harness Writes the limit of MaxCoolSetpointLimit to MinCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(MaxCoolSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = Max(AbsMinCoolSetpointLimit, (MinHeatSetpointLimit + MinSetpointDeadBand)) to MinCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(max(AbsMinCoolSetpointLimitValue, MinHeatSetpointLimitValue + MinSetpointDeadBandValue)), endpoint_id=endpoint) + else: + # Test Harness Writes the limit of AbsMinCoolSetpointLimit to MinCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(AbsMinCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("9a") + + if self.pics_guard(hasCoolingFeature and hasMaxCoolSetpointLimitAttribute): + # Test Harness Reads MaxCoolSetpointLimit attribute from Server DUT and verifies that the value is within range + # Using saved values when optional attributes are available + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxCoolSetpointLimit) + asserts.assert_greater_equal(val, MinCoolSetpointLimitValue) + asserts.assert_less_equal(val, AbsMaxCoolSetpointLimitValue) + + # Test Harness Writes a value back that is different but valid for MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(AbsMaxCoolSetpointLimitValue - 1), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MaxCoolSetpointLimit attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MaxCoolSetpointLimit) + asserts.assert_equal(val, AbsMaxCoolSetpointLimitValue - 1) + + self.step("9b") + + if self.pics_guard(hasCoolingFeature and hasMaxCoolSetpointLimitAttribute): + # Test Harness Writes MaxCoolSetpointLimit to value below the AbsMinCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(MinCoolSetpointLimitValue - 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes MaxCoolSetpointLimit to value above the AbsMaxCoolSetpointLimit + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(AbsMaxCoolSetpointLimitValue + 1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("9c") + + if self.pics_guard(hasCoolingFeature and hasMaxCoolSetpointLimitAttribute): + # Test Harness Writes the limit of AbsMaxCoolSetpointLimit to MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(AbsMaxCoolSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes the limit of MinCoolSetpointLimit to MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(MinCoolSetpointLimitValue), endpoint_id=endpoint, expect_success=False) + + # Test Harness Writes If TSTAT.S.F05(AUTO) LowerLimit = Max(MinCoolSetpointLimit, (MaxHeatSetpointLimit + MinSetpointDeadBand)) to MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(max(MinCoolSetpointLimitValue, min(AbsMaxCoolSetpointLimitValue, (MaxHeatSetpointLimitValue + MinSetpointDeadBandValue)))), endpoint_id=endpoint) + else: + # Test Harness Writes the limit of MinCoolSetpointLimit to MaxCoolSetpointLimit attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(MinCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("10a") + + if self.pics_guard(hasHeatingFeature and hasMinHeatSetpointLimitAttribute): + # Test Harness Writes (sets back) default value of MinHeatSetpointLimit + await self.write_single_attribute(attribute_value=cluster.Attributes.MinHeatSetpointLimit(MinHeatSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasAutoModeFeature): + # Test Harness Writes MaxHeatSetpointLimit That meets the deadband of 2.5C + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MaxCoolSetpointLimitValue - MinSetpointDeadBandValue), endpoint_id=endpoint) + else: + # Test Harness Writes (sets back)default value of MaxHeatSetpointLimit + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxHeatSetpointLimit(MaxHeatSetpointLimitValue), endpoint_id=endpoint) + + self.step("10b") + + if self.pics_guard(hasCoolingFeature and hasMinCoolSetpointLimitAttribute): + if self.pics_guard(hasMinCoolSetpointLimitAttribute): + # Test Harness Writes (sets back) default value of MinCoolSetpointLimit + await self.write_single_attribute(attribute_value=cluster.Attributes.MinCoolSetpointLimit(AbsMinCoolSetpointLimitValue), endpoint_id=endpoint) + + if self.pics_guard(hasMaxCoolSetpointLimitAttribute): + # Test Harness Writes (sets back) default value of MaxCoolSetpointLimit + await self.write_single_attribute(attribute_value=cluster.Attributes.MaxCoolSetpointLimit(AbsMaxCoolSetpointLimitValue), endpoint_id=endpoint) + + self.step("11a") + + # Test Harness Reads MinSetpointDeadBand attribute from Server DUT and verifies that the value is within range + if self.pics_guard(hasAutoModeFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinSetpointDeadBand) + asserts.assert_less_equal(val, 25) + + if self.pics_guard(self.check_pics("TSTAT.S.M.MinSetpointDeadBandWritable")): + # Test Harness Writes a value back that is different but valid for MinSetpointDeadBand attribute + await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(5), endpoint_id=endpoint) + + # Test Harness Reads it back again to confirm the successful write of MinSetpointDeadBand attribute + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.MinSetpointDeadBand) + asserts.assert_equal(val, 5) + + self.step("11b") + + if self.pics_guard(hasAutoModeFeature and self.check_pics("TSTAT.S.M.MinSetpointDeadBandWritable")): + # Test Harness Writes the value below MinSetpointDeadBand + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(-1), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + # Test Harness Writes the value above MinSetpointDeadBand + status = await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(30), endpoint_id=endpoint, expect_success=False) + asserts.assert_equal(status, Status.ConstraintError) + + self.step("11c") + + if self.pics_guard(hasAutoModeFeature and self.check_pics("TSTAT.S.M.MinSetpointDeadBandWritable")): + # Test Harness Writes the min limit of MinSetpointDeadBand + await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(0), endpoint_id=endpoint) + + # Test Harness Writes the max limit of MinSetpointDeadBand + await self.write_single_attribute(attribute_value=cluster.Attributes.MinSetpointDeadBand(25), endpoint_id=endpoint) + + self.step("12") + + # Test Harness Reads ControlSequenceOfOperation from Server DUT, if TSTAT.S.F01 is true + if self.pics_guard(hasCoolingFeature and not hasHeatingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + asserts.assert_in(val, [0, 1]) + + # Test Harness Reads ControlSequenceOfOperation from Server DUT, if TSTAT.S.F00 is true + if self.pics_guard(hasHeatingFeature and not hasCoolingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + asserts.assert_in(val, [2, 3]) + + # Test Harness Reads ControlSequenceOfOperation from Server DUT, if both TSTAT.S.F01 and TSTAT.S.F01 are true + if self.pics_guard(hasHeatingFeature and hasCoolingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + asserts.assert_in(val, [4, 5]) + + if self.pics_guard(hasCoolingFeature and not hasHeatingFeature): + # Test Harness writes value 1 for attribute ControlSequenceOfOperation. If TSTAT.S.F01 is true & TSTAT.S.F00 is false + await self.write_single_attribute(attribute_value=cluster.Attributes.ControlSequenceOfOperation(1), endpoint_id=endpoint) + + # Test Harness Read it back again to confirm the successful write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + + # It's acceptable for the server to ignore any attempts to write to the ControlSequenceOfOperation attribute + if val != ControlSequenceOfOperation: + asserts.assert_equal(val, 1) + + # Test Harness writes value 3 for attribute ControlSequenceOfOperation. If TSTAT.S.F00 is true & TSTAT.S.F01 is false + if self.pics_guard(hasHeatingFeature and not hasCoolingFeature): + await self.write_single_attribute(attribute_value=cluster.Attributes.ControlSequenceOfOperation(3), endpoint_id=endpoint) + + # Test Harness Read it back again to confirm the successful write + if self.pics_guard(hasHeatingFeature and not hasCoolingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + + # It's acceptable for the server to ignore any attempts to write to the ControlSequenceOfOperation attribute + if val != ControlSequenceOfOperation: + asserts.assert_equal(val, 3) + + # Test Harness writes value 4 for attribute ControlSequenceOfOperation. If TSTAT.S.F01 & TSTAT.S.F00 are true + if self.pics_guard(hasHeatingFeature and hasCoolingFeature): + await self.write_single_attribute(attribute_value=cluster.Attributes.ControlSequenceOfOperation(4), endpoint_id=endpoint) + + # Test Harness Read it back again to confirm the successful write + if self.pics_guard(hasHeatingFeature and hasCoolingFeature): + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ControlSequenceOfOperation) + + # It's acceptable for the server to ignore any attempts to write to the ControlSequenceOfOperation attribute + if val != ControlSequenceOfOperation: + asserts.assert_equal(val, 4) + + self.step("13") + + if self.pics_guard(hasCoolingFeature): + # Sets OccupiedCoolingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature): + # Sets OccupiedHeatingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + # Sends SetpointRaise Command Heat Only + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kHeat, amount=-30), endpoint=endpoint) + + # Test Harness Reads back OccupiedHeatingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, OccupiedHeatingSetpointValue - 30 * 10) + + self.step("14") + + if self.pics_guard(hasHeatingFeature): + # Sets OccupiedHeatingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + # Test Harness Sends SetpointRaise Command Heat Only + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kHeat, amount=30), endpoint=endpoint) + + # Test Harness Reads back OccupiedHeatingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, OccupiedHeatingSetpointValue + 30 * 10) + + self.step("15") + + if self.pics_guard(hasCoolingFeature): + # Test Harness Sends SetpointRaise Command Cool Only + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kCool, amount=-30), endpoint=endpoint) + + # Test Harness Reads back OccupiedCoolingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, OccupiedCoolingSetpointValue - 30 * 10) + + self.step("16") + + if self.pics_guard(hasCoolingFeature): + # Sets OccupiedCoolingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + # Test Harness Sends SetpointRaise Command Cool Only + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kCool, amount=30), endpoint=endpoint) + + # Test Harness Reads back OccupiedCoolingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, OccupiedCoolingSetpointValue + 30 * 10) + + self.step("17") + + if self.pics_guard(hasCoolingFeature): + # Sets OccupiedCoolingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature): + # Sets OccupiedHeatingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature or hasCoolingFeature): + # Test Harness Sends SetpointRaise Command Heat & Cool + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kBoth, amount=-30), endpoint=endpoint) + + if self.pics_guard(hasCoolingFeature): + # Test Harness Reads back OccupiedCoolingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, OccupiedCoolingSetpointValue - 30 * 10) + + if self.pics_guard(hasHeatingFeature): + # Test Harness Reads back OccupiedHeatingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, OccupiedHeatingSetpointValue - 30 * 10) + + self.step("18") + + if self.pics_guard(hasCoolingFeature): + # Sets OccupiedCoolingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature): + # Sets OccupiedHeatingSetpoint to default value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature or hasCoolingFeature): + # Test Harness Sends SetpointRaise Command Heat & Cool + await self.send_single_cmd(cmd=Clusters.Objects.Thermostat.Commands.SetpointRaiseLower(mode=Clusters.Objects.Thermostat.Enums.SetpointRaiseLowerModeEnum.kBoth, amount=30), endpoint=endpoint) + + if self.pics_guard(hasCoolingFeature): + # Test Harness Reads back OccupiedCoolingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedCoolingSetpoint) + asserts.assert_equal(val, OccupiedCoolingSetpointValue + 30 * 10) + + if self.pics_guard(hasHeatingFeature): + # Test Harness Reads back OccupiedHeatingSetpoint to confirm the success of the write + val = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.OccupiedHeatingSetpoint) + asserts.assert_equal(val, OccupiedHeatingSetpointValue + 30 * 10) + + if self.pics_guard(hasCoolingFeature): + # Restores OccupiedCoolingSetpoint to original value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedCoolingSetpoint(OccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasHeatingFeature): + # Restores OccupiedHeatingSetpoint to original value + await self.write_single_attribute(attribute_value=cluster.Attributes.OccupiedHeatingSetpoint(OccupiedHeatingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasOccupancyFeature and hasCoolingFeature): + # Restores UnoccupiedCoolingSetpoint to original value + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedCoolingSetpoint(UnoccupiedCoolingSetpointValue), endpoint_id=endpoint) + + if self.pics_guard(hasOccupancyFeature and hasHeatingFeature): + # Restores UnoccupiedHeatingSetpoint to original value + await self.write_single_attribute(attribute_value=cluster.Attributes.UnoccupiedHeatingSetpoint(UnoccupiedHeatingSetpointValue), endpoint_id=endpoint) + + +if __name__ == "__main__": + default_matter_test_main() diff --git a/src/python_testing/TC_VALCC_4_4.py b/src/python_testing/TC_VALCC_4_4.py index 8915bd9044734e..3dc1b93efd3e04 100644 --- a/src/python_testing/TC_VALCC_4_4.py +++ b/src/python_testing/TC_VALCC_4_4.py @@ -37,8 +37,8 @@ import chip.clusters as Clusters from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from chip.testing.matter_testing import (MatterBaseTest, TestStep, async_test_body, default_matter_test_main, - utc_time_in_matter_epoch) +from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main +from chip.testing.timeoperations import utc_time_in_matter_epoch from mobly import asserts diff --git a/src/python_testing/TestCommissioningTimeSync.py b/src/python_testing/TestCommissioningTimeSync.py index d4033ea58ba8b6..51d33f2f67344d 100644 --- a/src/python_testing/TestCommissioningTimeSync.py +++ b/src/python_testing/TestCommissioningTimeSync.py @@ -20,7 +20,8 @@ from chip import ChipDeviceCtrl from chip.clusters.Types import NullValue from chip.interaction_model import InteractionModelError, Status -from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, utc_time_in_matter_epoch +from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main +from chip.testing.timeoperations import utc_time_in_matter_epoch from mobly import asserts # We don't have a good pipe between the c++ enums in CommissioningDelegate and python diff --git a/src/python_testing/TestMatterTestingSupport.py b/src/python_testing/TestMatterTestingSupport.py index f111250481032d..5632834a843ba3 100644 --- a/src/python_testing/TestMatterTestingSupport.py +++ b/src/python_testing/TestMatterTestingSupport.py @@ -22,13 +22,13 @@ import chip.clusters as Clusters from chip.clusters.Types import Nullable, NullValue -from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, - get_wait_seconds_from_set_time, parse_matter_test_args, type_matches, - utc_time_in_matter_epoch) +from chip.testing.matter_testing import (MatterBaseTest, async_test_body, default_matter_test_main, parse_matter_test_args, + type_matches) from chip.testing.pics import parse_pics, parse_pics_xml from chip.testing.taglist_and_topology_test import (TagProblem, create_device_type_list_for_root, create_device_type_lists, find_tag_list_problems, find_tree_roots, flat_list_ok, get_all_children, get_direct_children_of_root, parts_list_cycles, separate_endpoint_types) +from chip.testing.timeoperations import compare_time, get_wait_seconds_from_set_time, utc_time_in_matter_epoch from chip.tlv import uint from mobly import asserts, signals diff --git a/src/python_testing/TestSpecParsingDeviceType.py b/src/python_testing/TestSpecParsingDeviceType.py index baf7ac4d9c42e6..95a8e796098b06 100644 --- a/src/python_testing/TestSpecParsingDeviceType.py +++ b/src/python_testing/TestSpecParsingDeviceType.py @@ -252,9 +252,15 @@ def test_spec_files(self): one_four, one_four_problems = build_xml_device_types(PrebuiltDataModelDirectory.k1_4) one_four_one, one_four_one_problems = build_xml_device_types(PrebuiltDataModelDirectory.k1_4_1) tot, tot_problems = build_xml_device_types(PrebuiltDataModelDirectory.kMaster) - + # 1.3 has a couple of problems related to proxy clusters and a random file from the DM editor. + # Some of these should be fixed with the move to alchemy. For now, let's just make sure 1.4 + # and the current pull don't introduce NEW problems. asserts.assert_equal(len(one_four_problems), 0, "Problems found when parsing 1.4 spec") asserts.assert_equal(len(one_four_one_problems), 0, "Problems found when parsing 1.4.1 spec") + # TOT has a bunch of problems related to IDs being allocated for closures and TBR. These should all + # mention ID-TBD as the id, so let's pull those out for now and make sure there are no UNKNOWN problems. + filtered_tot_problems = [p for p in tot_problems if 'ID-TBD' not in p.problem] + asserts.assert_equal(len(filtered_tot_problems), 0, "Problems found when parsing master spec") asserts.assert_greater(len(set(tot.keys()) - set(one_three.keys())), 0, "Master dir does not contain any device types not in 1.3") diff --git a/src/python_testing/TestSpecParsingSupport.py b/src/python_testing/TestSpecParsingSupport.py index ce461f89682046..0f3390de905d49 100644 --- a/src/python_testing/TestSpecParsingSupport.py +++ b/src/python_testing/TestSpecParsingSupport.py @@ -277,10 +277,16 @@ def test_build_xml_override(self): asserts.assert_equal(len(one_four_clusters.keys()), len(one_four_one_clusters.keys()), "1.4 and 1.4.1 do not contain the same clusters") # only the pulse width modulation cluster was removed post 1.3 - 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") + one_four_removed = set([Clusters.PulseWidthModulation.id]) + asserts.assert_equal(set(one_three_clusters.keys()) - set(one_four_clusters.keys()), + one_four_removed, "There are some 1.3 clusters that are unexpectedly not included in the 1.4 spec") + # Ballast and all the proxy clusters are being removed in 1.5 + one_five_removed = set([Clusters.BallastConfiguration.id, Clusters.ProxyConfiguration.id, + Clusters.ProxyDiscovery.id, Clusters.ProxyValid.id]) asserts.assert_equal(set(one_four_clusters.keys())-set(tot_xml_clusters.keys()), - set(), "There are some 1.4 clusters that are not included in the TOT spec") + one_five_removed, "There are some 1.4 clusters that are unexpectedly not included in the TOT spec") + asserts.assert_equal(set(one_three_clusters.keys())-set(tot_xml_clusters.keys()), + one_four_removed.union(one_five_removed), "There are some 1.3 clusters that are unexpectedly not included in the TOT spec") str_path = get_data_model_directory(PrebuiltDataModelDirectory.k1_4, DataModelLevel.kCluster) string_override_check, problems = build_xml_clusters(str_path) diff --git a/src/python_testing/matter_testing_infrastructure/BUILD.gn b/src/python_testing/matter_testing_infrastructure/BUILD.gn index f4d92e9496215c..cc803ca9a44d60 100644 --- a/src/python_testing/matter_testing_infrastructure/BUILD.gn +++ b/src/python_testing/matter_testing_infrastructure/BUILD.gn @@ -39,7 +39,9 @@ pw_python_package("chip-testing-module") { "chip/testing/basic_composition.py", "chip/testing/choice_conformance.py", "chip/testing/conformance.py", + "chip/testing/conversions.py", "chip/testing/global_attribute_ids.py", + "chip/testing/matchers.py", "chip/testing/matter_asserts.py", "chip/testing/matter_testing.py", "chip/testing/metadata.py", @@ -48,6 +50,7 @@ pw_python_package("chip-testing-module") { "chip/testing/spec_parsing.py", "chip/testing/taglist_and_topology_test.py", "chip/testing/tasks.py", + "chip/testing/timeoperations.py", ] tests = [ "chip/testing/test_metadata.py", diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/conversions.py b/src/python_testing/matter_testing_infrastructure/chip/testing/conversions.py new file mode 100644 index 00000000000000..20a5d760a1e68d --- /dev/null +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/conversions.py @@ -0,0 +1,122 @@ +# +# Copyright (c) 2025 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. +# + +"""Conversion utilities for Matter testing infrastructure. + +This module provides utility functions for converting between different data +representations commonly used in Matter testing. +""" + +from binascii import hexlify, unhexlify + +import chip.clusters as Clusters + + +def bytes_from_hex(hex: str) -> bytes: + """ Converts hex string to bytes, handling various formats (colons, spaces, newlines). + + Examples: + >>> bytes_from_hex("01:ab:cd") + b'\\x01\\xab\\xcd' + >>> bytes_from_hex("01 ab cd") + b'\\x01\\xab\\xcd' + >>> bytes_from_hex("01abcd") + b'\\x01\\xab\\xcd' + >>> bytes_from_hex("01\\nab\\ncd") + b'\\x01\\xab\\xcd' + """ + return unhexlify("".join(hex.replace(":", "").replace(" ", "").split())) + + +def hex_from_bytes(b: bytes) -> str: + """ Converts a bytes object to a hexadecimal string. + + This function performs the inverse operation of bytes_from_hex(). It converts + a bytes object into a continuous hexadecimal string without any separators. + + Args: + b: bytes, the bytes object to convert to hexadecimal + + Returns: + str: A string containing the hexadecimal representation of the bytes, + using lowercase letters a-f for hex digits + + Examples: + >>> hex_from_bytes(b'\\x01\\xab\\xcd') + '01abcd' + >>> hex_from_bytes(bytes([1, 171, 205])) # Same bytes, different notation + '01abcd' + """ + return hexlify(b).decode("utf-8") + + +def format_decimal_and_hex(number): + """ Formats a number showing both decimal and hexadecimal representations. + + Creates a string representation of a number showing both its decimal value + and its hex representation in parentheses. + + Args: + number: int, the number to format + + Returns: + str: A formatted string like "123 (0x7b)" + + Examples: + >>> format_decimal_and_hex(123) + '123 (0x7b)' + >>> format_decimal_and_hex(0) + '0 (0x00)' + >>> format_decimal_and_hex(255) + '255 (0xff)' + """ + return f'{number} (0x{number:02x})' + + +def cluster_id_with_name(id): + """ Formats a Matter cluster ID with its name and numeric representation. + + Uses format_decimal_and_hex() for numeric formatting and looks up cluster name from registry. + Falls back to "Unknown cluster" if ID not recognized. + + Args: + id: int, the Matter cluster identifier + + Returns: + str: A formatted string containing the ID and cluster name + + Examples: + >>> cluster_id_with_name(6) # OnOff cluster + '6 (0x06) OnOff' + >>> cluster_id_with_name(999999) # Unknown cluster + '999999 (0xf423f) Unknown cluster' + >>> cluster_id_with_name("invalid") # Invalid input + 'HERE IS THE PROBLEM' + """ + if id in Clusters.ClusterObjects.ALL_CLUSTERS.keys(): + s = Clusters.ClusterObjects.ALL_CLUSTERS[id].__name__ + else: + s = "Unknown cluster" + try: + return f'{format_decimal_and_hex(id)} {s}' + except (TypeError, ValueError): + return 'HERE IS THE PROBLEM' + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/matchers.py b/src/python_testing/matter_testing_infrastructure/chip/testing/matchers.py new file mode 100644 index 00000000000000..46e53ddbd2dce0 --- /dev/null +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/matchers.py @@ -0,0 +1,70 @@ +# +# Copyright (c) 2025 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. +# + +"""Type matching utilities for Matter testing infrastructure. + +This module provides functionality for validating type compatibility between +received values and expected type specifications. +""" + +import typing + +from chip.tlv import float32, uint + + +def is_type(received_value, desired_type): + """ Checks if a received value matches an expected type. + + Handles unpacking Nullable and Optional types and + compares list value types for non-empty lists. + + Args: + received_value: The value to type check + desired_type: The expected type specification (can be a basic type, Union, + Optional, or List type) + + Returns: + bool: True if the received_value matches the desired_type specification + + Examples: + >>> is_type(42, int) + True + >>> from typing import Optional + >>> is_type(None, Optional[str]) + True + >>> is_type([1,2,3], list[int]) + True + """ + if typing.get_origin(desired_type) == typing.Union: + return any(is_type(received_value, t) for t in typing.get_args(desired_type)) + elif typing.get_origin(desired_type) == list: + if isinstance(received_value, list): + # Assume an empty list is of the correct type + return True if received_value == [] else any(is_type(received_value[0], t) for t in typing.get_args(desired_type)) + else: + return False + elif desired_type == uint: + return isinstance(received_value, int) and received_value >= 0 + elif desired_type == float32: + return isinstance(received_value, float) + else: + return isinstance(received_value, desired_type) + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_asserts.py b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_asserts.py index 2371b21557d8bd..078e4030d5d62c 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_asserts.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_asserts.py @@ -158,19 +158,24 @@ def assert_list(value: Any, description: str, min_length: Optional[int] = None, f"{description} must not exceed {max_length} elements") -def assert_list_element_type(value: List[Any], description: str, expected_type: Type[T]) -> None: +def assert_list_element_type(value: List[Any], expected_type: Type[T], description: str, allow_empty: bool = False) -> None: """ Asserts that all elements in the list are of the expected type. Args: value: The list to validate - description: User-defined description for error messages expected_type: The type that all elements should match + description: User-defined description for error messages + allow_empty: If False, raises AssertionError for empty lists (default: False) Raises: - AssertionError: If value is not a list or contains elements of wrong type + AssertionError: If value is not a list, contains elements of wrong type, + or is empty when allow_empty=False + TypeError: If expected_type is not a valid type """ assert_list(value, description) + if not allow_empty and not value: + asserts.fail(f"{description} must not be empty") for i, item in enumerate(value): asserts.assert_true(isinstance(item, expected_type), f"{description}[{i}] must be of type {expected_type.__name__}") diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py index d999a0e73122d7..4625f9ca3b32b3 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py @@ -32,7 +32,7 @@ import time import typing import uuid -from binascii import hexlify, unhexlify +from binascii import unhexlify from dataclasses import asdict as dataclass_asdict from dataclasses import dataclass, field from datetime import datetime, timedelta, timezone @@ -41,7 +41,10 @@ from itertools import chain from typing import Any, Iterable, List, Optional, Tuple -from chip.tlv import float32, uint +import chip.testing.conversions as conversions +import chip.testing.matchers as matchers +import chip.testing.timeoperations as timeoperations +from chip.tlv import uint # isort: off @@ -149,78 +152,6 @@ def get_default_paa_trust_store(root_path: pathlib.Path) -> pathlib.Path: return pathlib.Path.cwd() -def type_matches(received_value, desired_type): - """ Checks if the value received matches the expected type. - - Handles unpacking Nullable and Optional types and - compares list value types for non-empty lists. - """ - if typing.get_origin(desired_type) == typing.Union: - return any(type_matches(received_value, t) for t in typing.get_args(desired_type)) - elif typing.get_origin(desired_type) == list: - if isinstance(received_value, list): - # Assume an empty list is of the correct type - return True if received_value == [] else any(type_matches(received_value[0], t) for t in typing.get_args(desired_type)) - else: - return False - elif desired_type == uint: - return isinstance(received_value, int) and received_value >= 0 - elif desired_type == float32: - return isinstance(received_value, float) - else: - return isinstance(received_value, desired_type) - -# TODO(#31177): Need to add unit tests for all time conversion methods. - - -def utc_time_in_matter_epoch(desired_datetime: Optional[datetime] = None): - """ Returns the time in matter epoch in us. - - If desired_datetime is None, it will return the current time. - """ - if desired_datetime is None: - utc_native = datetime.now(tz=timezone.utc) - else: - utc_native = desired_datetime - # Matter epoch is 0 hours, 0 minutes, 0 seconds on Jan 1, 2000 UTC - utc_th_delta = utc_native - datetime(2000, 1, 1, 0, 0, 0, 0, timezone.utc) - utc_th_us = int(utc_th_delta.total_seconds() * 1000000) - return utc_th_us - - -matter_epoch_us_from_utc_datetime = utc_time_in_matter_epoch - - -def utc_datetime_from_matter_epoch_us(matter_epoch_us: int) -> datetime: - """Returns the given Matter epoch time as a usable Python datetime in UTC.""" - delta_from_epoch = timedelta(microseconds=matter_epoch_us) - matter_epoch = datetime(2000, 1, 1, 0, 0, 0, 0, timezone.utc) - - return matter_epoch + delta_from_epoch - - -def utc_datetime_from_posix_time_ms(posix_time_ms: int) -> datetime: - millis = posix_time_ms % 1000 - seconds = posix_time_ms // 1000 - return datetime.fromtimestamp(seconds, timezone.utc) + timedelta(milliseconds=millis) - - -def compare_time(received: int, offset: timedelta = timedelta(), utc: Optional[int] = None, tolerance: timedelta = timedelta(seconds=5)) -> None: - if utc is None: - utc = utc_time_in_matter_epoch() - - # total seconds includes fractional for microseconds - expected = utc + offset.total_seconds() * 1000000 - delta_us = abs(expected - received) - delta = timedelta(microseconds=delta_us) - asserts.assert_less_equal(delta, tolerance, "Received time is out of tolerance") - - -def get_wait_seconds_from_set_time(set_time_matter_us: int, wait_seconds: int): - seconds_passed = (utc_time_in_matter_epoch() - set_time_matter_us) // 1000000 - return wait_seconds - seconds_passed - - @dataclass class SetupPayloadInfo: filter_type: discovery.FilterType = discovery.FilterType.LONG_DISCRIMINATOR @@ -804,21 +735,6 @@ def get_attribute_string(self, cluster_id: int, attribute_id) -> str: return f"Attribute {attribute_name} ({attribute_id}, 0x{attribute_id:04X})" -def id_str(id): - return f'{id} (0x{id:02x})' - - -def cluster_id_str(id): - if id in Clusters.ClusterObjects.ALL_CLUSTERS.keys(): - s = Clusters.ClusterObjects.ALL_CLUSTERS[id].__name__ - else: - s = "Unknown cluster" - try: - return f'{id_str(id)} {s}' - except TypeError: - return 'HERE IS THE PROBLEM' - - @dataclass class CustomCommissioningParameters: commissioningParameters: CommissioningParameters @@ -1024,19 +940,6 @@ def stack(self) -> ChipStack: return builtins.chipStack -def bytes_from_hex(hex: str) -> bytes: - """Converts any `hex` string representation including `01:ab:cd` to bytes - - Handles any whitespace including newlines, which are all stripped. - """ - return unhexlify("".join(hex.replace(":", "").replace(" ", "").split())) - - -def hex_from_bytes(b: bytes) -> str: - """Converts a bytes object `b` into a hex string (reverse of bytes_from_hex)""" - return hexlify(b).decode("utf-8") - - @dataclass class TestStep: test_plan_number: typing.Union[int, str] @@ -2621,3 +2524,16 @@ def run_tests(test_class: MatterBaseTest, matter_test_config: MatterTestConfig, if not run_tests_no_exit(test_class, matter_test_config, runner.get_loop(), hooks, default_controller, external_stack): sys.exit(1) + + +# TODO(#37537): Remove these temporary aliases after transition period +type_matches = matchers.is_type +utc_time_in_matter_epoch = timeoperations.utc_time_in_matter_epoch +utc_datetime_from_matter_epoch_us = timeoperations.utc_datetime_from_matter_epoch_us +utc_datetime_from_posix_time_ms = timeoperations.utc_datetime_from_posix_time_ms +compare_time = timeoperations.compare_time +get_wait_seconds_from_set_time = timeoperations.get_wait_seconds_from_set_time +bytes_from_hex = conversions.bytes_from_hex +hex_from_bytes = conversions.hex_from_bytes +id_str = conversions.format_decimal_and_hex +cluster_id_str = conversions.cluster_id_with_name diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/spec_parsing.py b/src/python_testing/matter_testing_infrastructure/chip/testing/spec_parsing.py index a514c232344302..3de7bbb5c0559a 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/spec_parsing.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/spec_parsing.py @@ -64,6 +64,9 @@ class XmlFeature: name: str conformance: ConformanceCallable + def __str__(self): + return f'{self.code}: {self.name} conformance {str(self.conformance)}' + @dataclass class XmlAttribute: @@ -91,6 +94,9 @@ class XmlCommand: name: str conformance: ConformanceCallable + def __str__(self): + return f'{self.name} id:0x{self.id:02X} {self.id} conformance: {str(self.conformance)}' + @dataclass class XmlEvent: @@ -826,7 +832,13 @@ def parse_single_device_type(root: ElementTree.Element) -> tuple[dict[int, XmlDe clusters = d.iter('cluster') for c in clusters: try: - cid = uint(int(c.attrib['id'], 0)) + try: + cid = uint(int(c.attrib['id'], 0)) + except ValueError: + location = DeviceTypePathLocation(device_type_id=id) + problems.append(ProblemNotice("Parse Device Type XML", location=location, + severity=ProblemSeverity.WARNING, problem=f"Unknown cluster id {c.attrib['id']}")) + continue conformance_xml, tmp_problem = get_conformance(c, cid) if tmp_problem: problems.append(tmp_problem) diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/test_matter_asserts.py b/src/python_testing/matter_testing_infrastructure/chip/testing/test_matter_asserts.py index 88df62ffdad721..98b4233c679f8d 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/test_matter_asserts.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/test_matter_asserts.py @@ -167,15 +167,17 @@ def test_assert_list(self): def test_assert_list_element_type(self): """Test assert_list_element_type with valid and invalid values.""" # Valid cases - matter_asserts.assert_list_element_type([], "test_empty", str) - matter_asserts.assert_list_element_type(["a", "b"], "test_strings", str) - matter_asserts.assert_list_element_type([1, 2, 3], "test_ints", int) + matter_asserts.assert_list_element_type(["a", "b"], str, "test_strings") + matter_asserts.assert_list_element_type([1, 2, 3], int, "test_ints") + matter_asserts.assert_list_element_type([], str, "test_empty", allow_empty=True) # Invalid cases with self.assertRaises(signals.TestFailure): - matter_asserts.assert_list_element_type("not_a_list", "test_not_list", str) + matter_asserts.assert_list_element_type("not_a_list", str, "test_not_list") with self.assertRaises(signals.TestFailure): - matter_asserts.assert_list_element_type([1, "2", 3], "test_mixed", int) + matter_asserts.assert_list_element_type([1, "2", 3], int, "test_mixed") + with self.assertRaises(signals.TestFailure): + matter_asserts.assert_list_element_type([], str, "test_empty") # empty list should fail by default # String assertion tests def test_assert_is_string(self): diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/timeoperations.py b/src/python_testing/matter_testing_infrastructure/chip/testing/timeoperations.py new file mode 100644 index 00000000000000..7255e2254917fe --- /dev/null +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/timeoperations.py @@ -0,0 +1,176 @@ +# +# Copyright (c) 2025 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. +# + +"""Time conversion and validation utilities for Matter testing infrastructure. + +This module provides functionality for handling time-related operations in Matter +testing, particularly focusing on conversions between different time formats and +epochs. + +Examples: + To run the doctests, execute the module as a script: + $ python3 timeoperations.py +""" + +from datetime import datetime, timedelta, timezone +from typing import Optional + +from mobly import asserts + +# TODO(#31177): Need to add unit tests for all time conversion methods. + + +def utc_time_in_matter_epoch(desired_datetime: Optional[datetime] = None): + """ Converts a datetime to microseconds since Matter epoch. + + The Matter epoch is defined as January 1, 2000, 00:00:00 UTC. This function + calculates the number of microseconds beчtween the input datetime and the + Matter epoch. If no datetime is provided, the current UTC time is used. + + Args: + desired_datetime: Optional datetime to convert, uses current UTC if None. + Should be timezone-aware. + + Returns: + int: Microseconds since Matter epoch + + Examples: + >>> from datetime import datetime, timezone + >>> utc_time_in_matter_epoch(datetime(2000, 1, 1, 0, 0, 0, 0, tzinfo=timezone.utc)) + 0 + >>> utc_time_in_matter_epoch(datetime(2000, 1, 1, 0, 0, 0, 1, tzinfo=timezone.utc)) + 1 + """ + if desired_datetime is None: + utc_native = datetime.now(tz=timezone.utc) + else: + utc_native = desired_datetime + # Matter epoch is 0 hours, 0 minutes, 0 seconds on Jan 1, 2000 UTC + utc_th_delta = utc_native - datetime(2000, 1, 1, 0, 0, 0, 0, timezone.utc) + utc_th_us = int(utc_th_delta.total_seconds() * 1000000) + return utc_th_us + + +def utc_datetime_from_matter_epoch_us(matter_epoch_us: int) -> datetime: + """ Converts microseconds since Matter epoch to UTC datetime. + + Inverse of utc_time_in_matter_epoch(). + It converts a microsecond timestamp relative to the Matter epoch + (Jan 1, 2000, 00:00:00 UTC) into a timezone-aware Python datetime object. + + Args: + matter_epoch_us: int, microseconds since Matter epoch + + Returns: + datetime: UTC datetime + + Examples: + >>> utc_datetime_from_matter_epoch_us(0) + datetime.datetime(2000, 1, 1, 0, 0, tzinfo=datetime.timezone.utc) + >>> utc_datetime_from_matter_epoch_us(123456789) + datetime.datetime(2000, 1, 1, 0, 2, 3, 456789, tzinfo=datetime.timezone.utc) + """ + delta_from_epoch = timedelta(microseconds=matter_epoch_us) + matter_epoch = datetime(2000, 1, 1, 0, 0, 0, 0, timezone.utc) + + return matter_epoch + delta_from_epoch + + +def utc_datetime_from_posix_time_ms(posix_time_ms: int) -> datetime: + """ Converts POSIX timestamp in milliseconds to UTC datetime. + + This function converts a POSIX timestamp (milliseconds since January 1, 1970, 00:00:00 UTC) + to a timezone-aware Python datetime object. + + Args: + posix_time_ms: int, Unix timestamp in milliseconds since Jan 1, 1970 + + Returns: + datetime: UTC datetime + + Examples: + >>> utc_datetime_from_posix_time_ms(0) + datetime.datetime(1970, 1, 1, 0, 0, tzinfo=datetime.timezone.utc) + >>> utc_datetime_from_posix_time_ms(1609459200000) # 2021-01-01 00:00:00 UTC + datetime.datetime(2021, 1, 1, 0, 0, tzinfo=datetime.timezone.utc) + """ + millis = posix_time_ms % 1000 + seconds = posix_time_ms // 1000 + return datetime.fromtimestamp(seconds, timezone.utc) + timedelta(milliseconds=millis) + + +def compare_time(received: int, offset: timedelta = timedelta(), utc: Optional[int] = None, tolerance: timedelta = timedelta(seconds=5)) -> None: + """ Validates a Matter timestamp against expected time within tolerance. + + Args: + received: int, Matter timestamp in microseconds + offset: timedelta, Optional offset from reference time (default: 0s) + utc: Optional[int], Reference time in Matter microseconds (default: current time) + tolerance: timedelta, Maximum allowed time difference (default: 5s) + + Raises: + AssertionError: If the received time differs from the expected time by + more than the specified tolerance + + Examples: + >>> compare_time(5000000, utc=0, tolerance=timedelta(seconds=5)) # Passes (exactly 5s) + >>> from mobly import signals + >>> try: + ... compare_time(6000000, utc=0, tolerance=timedelta(seconds=5)) + ... except signals.TestFailure as e: + ... print("AssertionError: Received time is out of tolerance") + AssertionError: Received time is out of tolerance + """ + if utc is None: + utc = utc_time_in_matter_epoch() + + # total seconds includes fractional for microseconds + expected = utc + offset.total_seconds() * 1000000 + delta_us = abs(expected - received) + delta = timedelta(microseconds=delta_us) + asserts.assert_less_equal(delta, tolerance, "Received time is out of tolerance") + + +def get_wait_seconds_from_set_time(set_time_matter_us: int, wait_seconds: int): + """ Calculates remaining wait time based on a previously set timestamp. + + This function determines how many seconds remain from an original wait duration, + accounting for time that has already elapsed since a Matter timestamp. Useful + for implementing timeouts or delays that need to account for already elapsed time. + + Args: + set_time_matter_us: int, Start time in Matter microseconds + wait_seconds: int, Total seconds to wait from start time + + Returns: + int: Remaining seconds (negative if period expired) + + Examples: + >>> import unittest.mock + >>> start_time = utc_time_in_matter_epoch(datetime(2000, 1, 1, 0, 0, 0, tzinfo=timezone.utc)) # 0 + >>> with unittest.mock.patch(__name__ + '.utc_time_in_matter_epoch') as mock_time: + ... mock_time.return_value = 2000000 # Simulate current time 2 seconds after start + ... get_wait_seconds_from_set_time(start_time, 5) # 5 - (2000000 / 1e6) = 5 - 2 = 3 + 3 + """ + seconds_passed = (utc_time_in_matter_epoch() - set_time_matter_us) // 1000000 + return wait_seconds - seconds_passed + + +if __name__ == "__main__": + import doctest + doctest.testmod() diff --git a/src/python_testing/matter_testing_infrastructure/data_model_xmls.gni b/src/python_testing/matter_testing_infrastructure/data_model_xmls.gni index 9af0c66c9ecefc..d9b0fc256e6159 100644 --- a/src/python_testing/matter_testing_infrastructure/data_model_xmls.gni +++ b/src/python_testing/matter_testing_infrastructure/data_model_xmls.gni @@ -569,12 +569,16 @@ data_model_XMLS_master = [ "${chip_root}/data_model/master/clusters/ApplicationBasic.xml", "${chip_root}/data_model/master/clusters/ApplicationLauncher.xml", "${chip_root}/data_model/master/clusters/AudioOutput.xml", - "${chip_root}/data_model/master/clusters/BallastConfiguration.xml", "${chip_root}/data_model/master/clusters/BasicInformationCluster.xml", "${chip_root}/data_model/master/clusters/Binding-Cluster.xml", "${chip_root}/data_model/master/clusters/BooleanState.xml", "${chip_root}/data_model/master/clusters/BooleanStateConfiguration.xml", + "${chip_root}/data_model/master/clusters/CameraAVSettingsUserLevelManagement.xml", + "${chip_root}/data_model/master/clusters/CameraAVStreamManagement.xml", "${chip_root}/data_model/master/clusters/Channel.xml", + "${chip_root}/data_model/master/clusters/Chime.xml", + "${chip_root}/data_model/master/clusters/ClosureControl.xml", + "${chip_root}/data_model/master/clusters/ClosureDimension.xml", "${chip_root}/data_model/master/clusters/ColorControl.xml", "${chip_root}/data_model/master/clusters/CommissionerControlCluster.xml", "${chip_root}/data_model/master/clusters/ConcentrationMeasurement.xml", @@ -592,18 +596,19 @@ data_model_XMLS_master = [ "${chip_root}/data_model/master/clusters/DiagnosticsWiFi.xml", "${chip_root}/data_model/master/clusters/DishwasherAlarm.xml", "${chip_root}/data_model/master/clusters/DoorLock.xml", + "${chip_root}/data_model/master/clusters/EcosystemInformationCluster.xml", "${chip_root}/data_model/master/clusters/ElectricalEnergyMeasurement.xml", "${chip_root}/data_model/master/clusters/ElectricalPowerMeasurement.xml", - "${chip_root}/data_model/master/clusters/EnergyCalendar.xml", "${chip_root}/data_model/master/clusters/EnergyEVSE.xml", + "${chip_root}/data_model/master/clusters/EnergyMetering.xml", "${chip_root}/data_model/master/clusters/EnergyPreference.xml", "${chip_root}/data_model/master/clusters/EnergyPrice.xml", + "${chip_root}/data_model/master/clusters/EnergyTariff.xml", "${chip_root}/data_model/master/clusters/FanControl.xml", "${chip_root}/data_model/master/clusters/FlowMeasurement.xml", "${chip_root}/data_model/master/clusters/GeneralCommissioningCluster.xml", "${chip_root}/data_model/master/clusters/Group-Key-Management-Cluster.xml", "${chip_root}/data_model/master/clusters/Groups.xml", - "${chip_root}/data_model/master/clusters/Humidistat.xml", "${chip_root}/data_model/master/clusters/ICDManagement.xml", "${chip_root}/data_model/master/clusters/Identify.xml", "${chip_root}/data_model/master/clusters/IlluminanceMeasurement.xml", @@ -638,7 +643,6 @@ data_model_XMLS_master = [ "${chip_root}/data_model/master/clusters/Mode_Refrigerator.xml", "${chip_root}/data_model/master/clusters/Mode_WaterHeater.xml", "${chip_root}/data_model/master/clusters/NetworkCommissioningCluster.xml", - "${chip_root}/data_model/master/clusters/NetworkIdentityManagement.xml", "${chip_root}/data_model/master/clusters/OTAProvider.xml", "${chip_root}/data_model/master/clusters/OTARequestor.xml", "${chip_root}/data_model/master/clusters/OccupancySensing.xml", @@ -651,15 +655,17 @@ data_model_XMLS_master = [ "${chip_root}/data_model/master/clusters/PowerSourceConfigurationCluster.xml", "${chip_root}/data_model/master/clusters/PowerTopology.xml", "${chip_root}/data_model/master/clusters/PressureMeasurement.xml", - "${chip_root}/data_model/master/clusters/ProxyConfiguration-Cluster.xml", - "${chip_root}/data_model/master/clusters/ProxyDiscovery-Cluster.xml", "${chip_root}/data_model/master/clusters/PumpConfigurationControl.xml", + "${chip_root}/data_model/master/clusters/PushAVStreamTransport.xml", "${chip_root}/data_model/master/clusters/RefrigeratorAlarm.xml", "${chip_root}/data_model/master/clusters/ResourceMonitoring.xml", "${chip_root}/data_model/master/clusters/Scenes.xml", "${chip_root}/data_model/master/clusters/ServiceArea.xml", "${chip_root}/data_model/master/clusters/SmokeCOAlarm.xml", + "${chip_root}/data_model/master/clusters/SoilMeasurement.xml", "${chip_root}/data_model/master/clusters/Switch.xml", + "${chip_root}/data_model/master/clusters/TLSCertificateManagement.xml", + "${chip_root}/data_model/master/clusters/TLSClientManagement.xml", "${chip_root}/data_model/master/clusters/TargetNavigator.xml", "${chip_root}/data_model/master/clusters/TemperatureControl.xml", "${chip_root}/data_model/master/clusters/TemperatureMeasurement.xml", @@ -668,25 +674,44 @@ data_model_XMLS_master = [ "${chip_root}/data_model/master/clusters/ThreadBorderRouterManagement.xml", "${chip_root}/data_model/master/clusters/ThreadNetworkDirectory.xml", "${chip_root}/data_model/master/clusters/TimeSync.xml", - "${chip_root}/data_model/master/clusters/ValidProxies-Cluster.xml", "${chip_root}/data_model/master/clusters/ValveConfigurationControl.xml", "${chip_root}/data_model/master/clusters/WakeOnLAN.xml", "${chip_root}/data_model/master/clusters/WaterContentMeasurement.xml", "${chip_root}/data_model/master/clusters/WaterHeaterManagement.xml", + "${chip_root}/data_model/master/clusters/WebRTC_Provider.xml", + "${chip_root}/data_model/master/clusters/WebRTC_Requestor.xml", "${chip_root}/data_model/master/clusters/WiFiNetworkManagement.xml", "${chip_root}/data_model/master/clusters/WindowCovering.xml", + "${chip_root}/data_model/master/clusters/ZoneManagement.xml", "${chip_root}/data_model/master/clusters/bridge-clusters-ActionsCluster.xml", "${chip_root}/data_model/master/clusters/bridge-clusters-BridgedDeviceBasicInformationCluster.xml", - "${chip_root}/data_model/master/clusters/bridge-clusters-EcosystemInformationCluster.xml", "${chip_root}/data_model/master/device_types/Aggregator.xml", "${chip_root}/data_model/master/device_types/AirPurifier.xml", "${chip_root}/data_model/master/device_types/AirQualitySensor.xml", + "${chip_root}/data_model/master/device_types/AudioDoorbell.xml", "${chip_root}/data_model/master/device_types/BaseDeviceType.xml", "${chip_root}/data_model/master/device_types/BasicVideoPlayer.xml", "${chip_root}/data_model/master/device_types/BatteryStorage.xml", "${chip_root}/data_model/master/device_types/BridgedNode.xml", + "${chip_root}/data_model/master/device_types/Camera.xml", "${chip_root}/data_model/master/device_types/CastingVideoClient.xml", "${chip_root}/data_model/master/device_types/CastingVideoPlayer.xml", + "${chip_root}/data_model/master/device_types/Chime.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseController.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Awning.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Barrier.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Blind.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Cabinet.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-ClosureBase.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Curtain.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Door.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-GarageDoor.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Gate.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Pergola.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Screen.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Shade.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Shutter.xml", + "${chip_root}/data_model/master/device_types/ClosureBaseDeviceTypes-Window.xml", "${chip_root}/data_model/master/device_types/ColorDimmerSwitch.xml", "${chip_root}/data_model/master/device_types/ColorTemperatureLight.xml", "${chip_root}/data_model/master/device_types/ContactSensor.xml", @@ -702,17 +727,20 @@ data_model_XMLS_master = [ "${chip_root}/data_model/master/device_types/DoorLock.xml", "${chip_root}/data_model/master/device_types/DoorLockController.xml", "${chip_root}/data_model/master/device_types/EVSE.xml", + "${chip_root}/data_model/master/device_types/ElectricalEnergyTariff.xml", + "${chip_root}/data_model/master/device_types/ElectricalMeter.xml", "${chip_root}/data_model/master/device_types/ElectricalSensor.xml", - "${chip_root}/data_model/master/device_types/EnergyTariff.xml", - "${chip_root}/data_model/master/device_types/EnergyTariffCalendar.xml", + "${chip_root}/data_model/master/device_types/ElectricalUtilityMeter.xml", "${chip_root}/data_model/master/device_types/ExtendedColorLight.xml", "${chip_root}/data_model/master/device_types/ExtractorHood.xml", "${chip_root}/data_model/master/device_types/Fan.xml", + "${chip_root}/data_model/master/device_types/FloodlightCamera.xml", "${chip_root}/data_model/master/device_types/FlowSensor.xml", "${chip_root}/data_model/master/device_types/GenericSwitch.xml", "${chip_root}/data_model/master/device_types/HeatPump.xml", - "${chip_root}/data_model/master/device_types/HumidifierDehumidifier.xml", "${chip_root}/data_model/master/device_types/HumiditySensor.xml", + "${chip_root}/data_model/master/device_types/Intercom.xml", + "${chip_root}/data_model/master/device_types/IrrigationSystem.xml", "${chip_root}/data_model/master/device_types/JointFabricAdmin.xml", "${chip_root}/data_model/master/device_types/LaundryDryer.xml", "${chip_root}/data_model/master/device_types/LaundryWasher.xml", @@ -721,7 +749,6 @@ data_model_XMLS_master = [ "${chip_root}/data_model/master/device_types/ModeSelectDeviceType.xml", "${chip_root}/data_model/master/device_types/MountedDimmableLoadControl.xml", "${chip_root}/data_model/master/device_types/MountedOnOffControl.xml", - "${chip_root}/data_model/master/device_types/NetworkInfraIntro.xml", "${chip_root}/data_model/master/device_types/NetworkInfraManager.xml", "${chip_root}/data_model/master/device_types/OccupancySensor.xml", "${chip_root}/data_model/master/device_types/OnOffLight.xml", @@ -742,12 +769,16 @@ data_model_XMLS_master = [ "${chip_root}/data_model/master/device_types/RootNodeDeviceType.xml", "${chip_root}/data_model/master/device_types/SecondaryNetworkInterface.xml", "${chip_root}/data_model/master/device_types/SmokeCOAlarm.xml", + "${chip_root}/data_model/master/device_types/SnapshotCamera.xml", + "${chip_root}/data_model/master/device_types/SoilSensor.xml", "${chip_root}/data_model/master/device_types/SolarPower.xml", "${chip_root}/data_model/master/device_types/Speaker.xml", "${chip_root}/data_model/master/device_types/TemperatureControlledCabinet.xml", "${chip_root}/data_model/master/device_types/TemperatureSensor.xml", "${chip_root}/data_model/master/device_types/Thermostat.xml", + "${chip_root}/data_model/master/device_types/ThermostatController.xml", "${chip_root}/data_model/master/device_types/ThreadBorderRouter.xml", + "${chip_root}/data_model/master/device_types/VideoDoorbell.xml", "${chip_root}/data_model/master/device_types/VideoRemoteControl.xml", "${chip_root}/data_model/master/device_types/WaterFreezeDetector.xml", "${chip_root}/data_model/master/device_types/WaterHeater.xml", diff --git a/third_party/bouffalolab/bl602/bl_iot_sdk.gni b/third_party/bouffalolab/bl602/bl_iot_sdk.gni index ba564db1469bec..0cf4768465f131 100644 --- a/third_party/bouffalolab/bl602/bl_iot_sdk.gni +++ b/third_party/bouffalolab/bl602/bl_iot_sdk.gni @@ -20,6 +20,7 @@ import("${chip_root}/src/lib/lib.gni") declare_args() { bl_iot_sdk_root = "${chip_root}/third_party/bouffalolab/repo" + enable_lwip_pbuf_ram = false enable_debug_coredump = false coredump_binary_id = 0 } @@ -63,6 +64,10 @@ template("bl_iot_sdk") { "-include", rebase_path("${invoker.freertos_config}", root_build_dir), ] + + if (defined(invoker.enable_lwip_pbuf_ram) && invoker.enable_lwip_pbuf_ram) { + defines += [ "CHIP_SYSTEM_CONFIG_PACKETBUFFER_LWIP_PBUF_RAM=1" ] + } } source_set("${sdk_target_name}_soc") { @@ -906,6 +911,10 @@ template("bl_iot_sdk") { "${bl_iot_sdk_root}/components/network/lwip_dhcpd", ] + if (defined(invoker.enable_lwip_pbuf_ram) && invoker.enable_lwip_pbuf_ram) { + include_dirs += [ "${bouffalolab_iot_sdk_build_root}/patches/lwip" ] + } + defines = [ "LWIP_IPV6=1" ] } @@ -927,7 +936,6 @@ template("bl_iot_sdk") { "${bl_iot_sdk_root}/components/network/lwip/src/core/inet_chksum.c", "${bl_iot_sdk_root}/components/network/lwip/src/core/init.c", "${bl_iot_sdk_root}/components/network/lwip/src/core/ip.c", - "${bl_iot_sdk_root}/components/network/lwip/src/core/mem.c", "${bl_iot_sdk_root}/components/network/lwip/src/core/memp.c", "${bl_iot_sdk_root}/components/network/lwip/src/core/netif.c", "${bl_iot_sdk_root}/components/network/lwip/src/core/pbuf.c", @@ -941,6 +949,12 @@ template("bl_iot_sdk") { "${bl_iot_sdk_root}/components/network/lwip/src/core/udp.c", ] + if (defined(invoker.enable_lwip_pbuf_ram) && invoker.enable_lwip_pbuf_ram) { + sources += [ "${bouffalolab_iot_sdk_build_root}/patches/lwip/mem.c" ] + } else { + sources += [ "${bl_iot_sdk_root}/components/network/lwip/src/core/mem.c" ] + } + sources += [ "${bl_iot_sdk_root}/components/network/lwip/src/core/ipv4/autoip.c", "${bl_iot_sdk_root}/components/network/lwip/src/core/ipv4/dhcp.c", diff --git a/third_party/bouffalolab/bl616/bouffalo_sdk.gni b/third_party/bouffalolab/bl616/bouffalo_sdk.gni index 174b04b8160ae2..9b498966eded53 100644 --- a/third_party/bouffalolab/bl616/bouffalo_sdk.gni +++ b/third_party/bouffalolab/bl616/bouffalo_sdk.gni @@ -21,6 +21,7 @@ declare_args() { # Location of the bl616 SDK. bouffalo_sdk_root = "${chip_root}/third_party/bouffalolab/bouffalo_sdk" + enable_lwip_pbuf_ram = false enable_debug_coredump = false coredump_binary_id = 0 bouffalo_sdk_coredump_version = 1 @@ -72,6 +73,10 @@ template("bouffalo_sdk") { if (defined(invoker.defines)) { defines += invoker.defines } + + if (defined(invoker.enable_lwip_pbuf_ram) && invoker.enable_lwip_pbuf_ram) { + defines += [ "CHIP_SYSTEM_CONFIG_PACKETBUFFER_LWIP_PBUF_RAM=1" ] + } } config("${sdk_target_name}_config_startup") { @@ -412,6 +417,7 @@ template("bouffalo_sdk") { include_dirs = [ "${bouffalo_sdk_root}/components/libc" ] sources = [ + "${bouffalo_sdk_root}/components/libc/assert.c", "${bouffalo_sdk_root}/components/libc/newlib/port_init_fini.c", "${bouffalo_sdk_root}/components/libc/newlib/port_memory.c", "${bouffalo_sdk_root}/components/libc/newlib/syscalls_nosys.c", @@ -895,6 +901,10 @@ template("bouffalo_sdk") { include_dirs += [ "${bouffalo_sdk_root}/components/net/lwip/lwip/src/apps/dhcpd" ] + if (defined(invoker.enable_lwip_pbuf_ram) && invoker.enable_lwip_pbuf_ram) { + include_dirs += [ "${bouffalolab_iot_sdk_build_root}/patches/lwip" ] + } + defines = [ "CONFIG_LWIP", "CONFIG_MAC_TXQ_DEPTH=8", @@ -937,7 +947,6 @@ template("bouffalo_sdk") { "${bouffalo_sdk_root}/components/net/lwip/lwip/src/core/ipv6/ip6_frag.c", "${bouffalo_sdk_root}/components/net/lwip/lwip/src/core/ipv6/mld6.c", "${bouffalo_sdk_root}/components/net/lwip/lwip/src/core/ipv6/nd6.c", - "${bouffalo_sdk_root}/components/net/lwip/lwip/src/core/mem.c", "${bouffalo_sdk_root}/components/net/lwip/lwip/src/core/memp.c", "${bouffalo_sdk_root}/components/net/lwip/lwip/src/core/netif.c", "${bouffalo_sdk_root}/components/net/lwip/lwip/src/core/pbuf.c", @@ -952,6 +961,13 @@ template("bouffalo_sdk") { "${bouffalo_sdk_root}/components/net/lwip/lwip/src/netif/ethernet.c", ] + if (defined(invoker.enable_lwip_pbuf_ram) && invoker.enable_lwip_pbuf_ram) { + sources += [ "${bouffalolab_iot_sdk_build_root}/patches/lwip/mem.c" ] + } else { + sources += + [ "${bouffalo_sdk_root}/components/net/lwip/lwip/src/core/mem.c" ] + } + sources += [ "${bouffalo_sdk_root}/components/net/lwip/lwip/src/apps/dhcpd/dhcp_server_raw.c", "${bouffalo_sdk_root}/components/net/lwip/lwip/src/apps/lwiperf/lwiperf.c", diff --git a/third_party/bouffalolab/bl702/bl_iot_sdk.gni b/third_party/bouffalolab/bl702/bl_iot_sdk.gni index 76d35da758e883..45122f43c34021 100644 --- a/third_party/bouffalolab/bl702/bl_iot_sdk.gni +++ b/third_party/bouffalolab/bl702/bl_iot_sdk.gni @@ -21,6 +21,7 @@ import("${chip_root}/src/lib/lib.gni") declare_args() { bl_iot_sdk_root = "${chip_root}/third_party/bouffalolab/repo" + enable_lwip_pbuf_ram = false enable_debug_coredump = false coredump_binary_id = 0 } diff --git a/third_party/bouffalolab/bl702l/bl_iot_sdk.gni b/third_party/bouffalolab/bl702l/bl_iot_sdk.gni index ac608a72098cd6..514d25d2172427 100644 --- a/third_party/bouffalolab/bl702l/bl_iot_sdk.gni +++ b/third_party/bouffalolab/bl702l/bl_iot_sdk.gni @@ -21,6 +21,7 @@ import("${chip_root}/src/lib/lib.gni") declare_args() { bl_iot_sdk_root = "${chip_root}/third_party/bouffalolab/repo" + enable_lwip_pbuf_ram = false enable_pds = false enable_debug_coredump = false coredump_binary_id = 0 diff --git a/third_party/bouffalolab/repo b/third_party/bouffalolab/repo index 75df6e87ffa10b..11448aeb1a5d9c 160000 --- a/third_party/bouffalolab/repo +++ b/third_party/bouffalolab/repo @@ -1 +1 @@ -Subproject commit 75df6e87ffa10b905c9dbb0efc5fd35f96955c55 +Subproject commit 11448aeb1a5d9c000859db47863a3bfcbc4d6032 diff --git a/third_party/libdatachannel/BUILD.gn b/third_party/libdatachannel/BUILD.gn new file mode 100644 index 00000000000000..902638e6cbb879 --- /dev/null +++ b/third_party/libdatachannel/BUILD.gn @@ -0,0 +1,155 @@ +# Copyright (c) 2025 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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("libdatachannel_config") { + include_dirs = [ + "repo/include", + "repo/include/rtc", + ] +} + +config("libdatachannel_config_disable_warnings") { + cflags_cc = [ + "-Wno-shadow", + "-Wno-unreachable-code", + "-Wno-non-virtual-dtor", + "-Wno-implicit-fallthrough", + ] +} + +config("libdatachannel_config_enable_features") { + cflags_cc = [ + "-fexceptions", + "-frtti", + ] +} + +source_set("libdatachannel") { + include_dirs = [ + "repo/src", + "repo/include/rtc", + "repo/deps/plog/include", + "repo/deps/usrsctp/usrsctplib", + "repo/deps/libjuice/include", + "repo/deps/libsrtp/include", + ] + + # --------------------------------------------------------------------------- + # Source files from repo/src/*.cpp + # --------------------------------------------------------------------------- + sources = [ + "repo/src/av1rtppacketizer.cpp", + "repo/src/candidate.cpp", + "repo/src/capi.cpp", + "repo/src/channel.cpp", + "repo/src/configuration.cpp", + "repo/src/datachannel.cpp", + "repo/src/description.cpp", + "repo/src/global.cpp", + "repo/src/h264rtpdepacketizer.cpp", + "repo/src/h264rtppacketizer.cpp", + "repo/src/h265nalunit.cpp", + "repo/src/h265rtpdepacketizer.cpp", + "repo/src/h265rtppacketizer.cpp", + "repo/src/mediahandler.cpp", + "repo/src/message.cpp", + "repo/src/nalunit.cpp", + "repo/src/pacinghandler.cpp", + "repo/src/peerconnection.cpp", + "repo/src/plihandler.cpp", + "repo/src/rembhandler.cpp", + "repo/src/rtcpnackresponder.cpp", + "repo/src/rtcpreceivingsession.cpp", + "repo/src/rtcpsrreporter.cpp", + "repo/src/rtp.cpp", + "repo/src/rtpdepacketizer.cpp", + "repo/src/rtppacketizationconfig.cpp", + "repo/src/rtppacketizer.cpp", + "repo/src/track.cpp", + "repo/src/websocket.cpp", + "repo/src/websocketserver.cpp", + ] + + # --------------------------------------------------------------------------- + # Source files from repo/src/impl/*.cpp + # --------------------------------------------------------------------------- + sources += [ + "repo/src/impl/certificate.cpp", + "repo/src/impl/channel.cpp", + "repo/src/impl/datachannel.cpp", + "repo/src/impl/dtlssrtptransport.cpp", + "repo/src/impl/dtlstransport.cpp", + "repo/src/impl/http.cpp", + "repo/src/impl/httpproxytransport.cpp", + "repo/src/impl/icetransport.cpp", + "repo/src/impl/init.cpp", + "repo/src/impl/logcounter.cpp", + "repo/src/impl/peerconnection.cpp", + "repo/src/impl/pollinterrupter.cpp", + "repo/src/impl/pollservice.cpp", + "repo/src/impl/processor.cpp", + "repo/src/impl/sctptransport.cpp", + "repo/src/impl/sha.cpp", + "repo/src/impl/tcpserver.cpp", + "repo/src/impl/tcptransport.cpp", + "repo/src/impl/threadpool.cpp", + "repo/src/impl/tls.cpp", + "repo/src/impl/tlstransport.cpp", + "repo/src/impl/track.cpp", + "repo/src/impl/transport.cpp", + "repo/src/impl/utils.cpp", + "repo/src/impl/verifiedtlstransport.cpp", + "repo/src/impl/websocket.cpp", + "repo/src/impl/websocketserver.cpp", + "repo/src/impl/wshandshake.cpp", + "repo/src/impl/wstransport.cpp", + ] + + public_configs = [ ":libdatachannel_config" ] + configs += [ + ":libdatachannel_config_disable_warnings", + ":libdatachannel_config_enable_features", + ] + + defines = [ + "BUILD_SHARED_LIBS=1", # default ON in the CMake + "BUILD_SHARED_DEPS_LIBS=0", # default OFF + "USE_GNUTLS=0", # default OFF => no GnuTLS + "USE_MBEDTLS=0", # default OFF => no MbedTLS + "USE_NICE=0", # default OFF => no libnice + "PREFER_SYSTEM_LIB=0", # default OFF + "USE_SYSTEM_SRTP=0", # default from PREFER_SYSTEM_LIB + "USE_SYSTEM_JUICE=0", + "USE_SYSTEM_USRSCTP=0", + "USE_SYSTEM_PLOG=0", + "USE_SYSTEM_JSON=0", + "NO_WEBSOCKET=0", # default OFF => websockets on + "NO_MEDIA=0", # default OFF => media on + "NO_EXAMPLES=0", # default OFF + "NO_TESTS=0", # default OFF + "WARNINGS_AS_ERRORS=0", # default OFF + "CAPI_STDCALL=0", # default OFF + "SCTP_DEBUG=0", # default OFF + "RTC_UPDATE_VERSION_HEADER=0", # default OFF + + # Because NO_WEBSOCKET=0 => RTC_ENABLE_WEBSOCKET=1 + "RTC_ENABLE_WEBSOCKET=1", + + # Because NO_MEDIA=0 => RTC_ENABLE_MEDIA=1 + "RTC_ENABLE_MEDIA=1", + + # Because USE_SYSTEM_SRTP=0 => RTC_SYSTEM_SRTP=0 + "RTC_SYSTEM_SRTP=0", + ] +} diff --git a/third_party/libdatachannel/repo b/third_party/libdatachannel/repo new file mode 160000 index 00000000000000..6fa7cffe637f07 --- /dev/null +++ b/third_party/libdatachannel/repo @@ -0,0 +1 @@ +Subproject commit 6fa7cffe637f071315b3950c129dd72cbab845a5 diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 742da0a3b3dda4..644057e2a388c9 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -547,7 +547,7 @@ template("efr32_sdk") { } if (chip_enable_multi_ota_encryption && chip_enable_multi_ota_requestor) { - defines += [ "OTA_ENCRYPTION_ENABLE=1" ] + defines += [ "SL_MATTER_ENABLE_OTA_ENCRYPTION=1" ] } if (chip_enable_ota_custom_tlv_testing && chip_enable_multi_ota_requestor) { diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index 2db499924fd24a..65ed5229f159f8 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit 2db499924fd24a9ff045ad5831438ee79e46a8ac +Subproject commit 65ed5229f159f88490a8938538768b692b6173fb diff --git a/third_party/silabs/silabs_board.gni b/third_party/silabs/silabs_board.gni index 6385a880a47ff6..0cdcf7747d155e 100644 --- a/third_party/silabs/silabs_board.gni +++ b/third_party/silabs/silabs_board.gni @@ -51,9 +51,6 @@ declare_args() { # Disable AWS SDK OTA by default aws_sdk_ota = false - # Self-provision enabled - use_provision_channel = false - # Temperature Sensor support sl_enable_si70xx_sensor = false diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp index d0593cdcc9ea15..ed5c63b93c5345 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -6641,6 +6641,8 @@ char const * DeviceTypeIdToText(chip::DeviceTypeId id) return "Color Temperature Light"; case 0x0000010D: return "Extended Color Light"; + case 0x00000142: + return "Camera"; case 0x00000202: return "Window Covering"; case 0x00000203: